Jump to content

What does ~ do in C#?

Guest
Go to solution Solved by mathijs727,
58 minutes ago, fpo said:

What does that mean?


I don't know what camera is in binary.

Camera is a class with an integer attribute "cullingMask".

 

This integer is not intended to be used as a direct value but as a bitmask.

So instead of interpreting the 32 bits as a base 10 value, we consider each bit as a boolean.

 

In all programming languages, a boolean (bool) datatype is at least 8 bits (1 byte) because thats the smallest piece of information that your CPU can process.

So instead of using 32 boolean datatypes (which uses 32*8=256 bits), the camera class uses an integer (32 bits) where each bits represents a boolean value (either true of false).

 

For these kind of bitmasks, it can sometimes be usefull to have the "~" operator, which switches each bit.

 

In this case, a game object can be part of 0 or more layers.

Instead of using a boolean for each layer, to indicate that it is in that layer, Unity uses a bitmask.

This saves a lot of memory (32*8 - 32 = 224 bits = 28 bytes per GameObject), when you consider how many instances of GameObject you will have.

The camera bitmask indicates which layers it wants to render (if all 32 bits are set to "1" than all layers are rendered, if the first (right most) bit is set to "1" than only the first layer is rendered).

 

Bitmask are not only efficient in terms of memory, but also in computation.

Applying a bitmask for example takes just a single operation (bitwise &)

I found a C sharp script online associated with a video.

In the video they did something different from the script they provided as they wanted to save time.

 

Because the script is long I put it at the end.

 

The original line in the video was

fpsCamera.enabled = isAlive;

Where "fpsCamera" is an object in the scene of the "camera" type from Unity, and "isAlive" is a Boolean value that sets to true or false depending on if the player is "killed."

 

 

The script changed the line to:

fpsCamera.cullingMask = ~fpsCamera.cullingMask;

Where culling mask makes an object invisible when the value is set to "0'

Documentation on culling mask below;

https://docs.unity3d.com/ScriptReference/Camera-cullingMask.html

 

 

This seems like a C# type of question when I ask what the "~" does but it is shrouded in Unity's API so it may be more complicated for someone not so proficient to understand what it is I am asking.

 

I googled "What does the '~' do in C#?" and MSDN said bitwise comparison or something

and I found this link:
https://en.wikipedia.org/wiki/Bitwise_operations_in_C#Bitwise_NOT_.22.7E.22_.2F_one.27s_complement_.28unary.29


Is that the kind of bitwise comparison used? As in another way of saying:

bool x = !x 

...in a sense?

 

using UnityEngine;
using UnityEngine.Networking;

public class NetworkedPlayerScript : NetworkBehaviour
{
    public UnityStandardAssets.Characters.FirstPerson.FirstPersonController fpsController;
    public Camera fpsCamera;
    public AudioListener audioListener;
    public ShootingScript shootingScript;
    public CandyCaneMaterialSwitcher candyMaterialSwitcher;

    Renderer[] renderers;

    void Start()
    {
        renderers = GetComponentsInChildren<Renderer>();
    }

    public override void OnStartLocalPlayer()
    {
        fpsController.enabled = true;
        fpsCamera.enabled = true;
        audioListener.enabled = true;
        shootingScript.enabled = true;
        candyMaterialSwitcher.SwitchMaterial(true);

        gameObject.name = "LOCAL Player";
        base.OnStartLocalPlayer();
    }

    void ToggleRenderer(bool isAlive)
    {
        for (int i = 0; i < renderers.Length; i++)
            renderers[i].enabled = isAlive;
    }

    void ToggleControls(bool isAlive)
    {
        fpsController.enabled = isAlive;
        shootingScript.enabled = isAlive;
        fpsCamera.cullingMask = ~fpsCamera.cullingMask;
    }

    [ClientRpc]
    public void RpcResolveHit()
    {
        ToggleRenderer(false);

        if (isLocalPlayer)
        {
            Transform spawn = NetworkManager.singleton.GetStartPosition();
            transform.position = spawn.position;
            transform.rotation = spawn.rotation;

            ToggleControls(false);
        }

        Invoke("Respawn", 2f);
    }

    void Respawn()
    {
        ToggleRenderer(true);

        if (isLocalPlayer)
            ToggleControls(true);
    }
}

 

Link to comment
Share on other sites

Link to post
Share on other sites

An integerer usually consists of 32 or 64 bits.

The "~" sign flips the bits.

So every bit 0 bit becomes 1, and every 1 bit becomes 0.

Desktop: Intel i9-10850K (R9 3900X died 😢 )| MSI Z490 Tomahawk | RTX 2080 (borrowed from work) - MSI GTX 1080 | 64GB 3600MHz CL16 memory | Corsair H100i (NF-F12 fans) | Samsung 970 EVO 512GB | Intel 665p 2TB | Samsung 830 256GB| 3TB HDD | Corsair 450D | Corsair RM550x | MG279Q

Laptop: Surface Pro 7 (i5, 16GB RAM, 256GB SSD)

Console: PlayStation 4 Pro

Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, mathijs727 said:

An integerer usually consists of 32 or 64 bits.

The "~" sign flips the bits.

So every bit 0 bit becomes 1, and every 1 bit becomes 0.

What does that mean?


I don't know what camera is in binary.

Link to comment
Share on other sites

Link to post
Share on other sites

58 minutes ago, fpo said:

What does that mean?


I don't know what camera is in binary.

Camera is a class with an integer attribute "cullingMask".

 

This integer is not intended to be used as a direct value but as a bitmask.

So instead of interpreting the 32 bits as a base 10 value, we consider each bit as a boolean.

 

In all programming languages, a boolean (bool) datatype is at least 8 bits (1 byte) because thats the smallest piece of information that your CPU can process.

So instead of using 32 boolean datatypes (which uses 32*8=256 bits), the camera class uses an integer (32 bits) where each bits represents a boolean value (either true of false).

 

For these kind of bitmasks, it can sometimes be usefull to have the "~" operator, which switches each bit.

 

In this case, a game object can be part of 0 or more layers.

Instead of using a boolean for each layer, to indicate that it is in that layer, Unity uses a bitmask.

This saves a lot of memory (32*8 - 32 = 224 bits = 28 bytes per GameObject), when you consider how many instances of GameObject you will have.

The camera bitmask indicates which layers it wants to render (if all 32 bits are set to "1" than all layers are rendered, if the first (right most) bit is set to "1" than only the first layer is rendered).

 

Bitmask are not only efficient in terms of memory, but also in computation.

Applying a bitmask for example takes just a single operation (bitwise &)

Desktop: Intel i9-10850K (R9 3900X died 😢 )| MSI Z490 Tomahawk | RTX 2080 (borrowed from work) - MSI GTX 1080 | 64GB 3600MHz CL16 memory | Corsair H100i (NF-F12 fans) | Samsung 970 EVO 512GB | Intel 665p 2TB | Samsung 830 256GB| 3TB HDD | Corsair 450D | Corsair RM550x | MG279Q

Laptop: Surface Pro 7 (i5, 16GB RAM, 256GB SSD)

Console: PlayStation 4 Pro

Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, fpo said:

What does that mean?


I don't know what camera is in binary.

It would apply the operation to the integer value returned from the cullingMask field, not to the fpsCamera object

 

edit: For reference, the C# Operators page lists the order in which the operators are evaluated.

 

Link to comment
Share on other sites

Link to post
Share on other sites

51 minutes ago, mathijs727 said:

Snip

Ahh, okay that makes sense. It reads each bit in an integer value as a Boolean instead of having multiple Booleans.

Thank you very much. I didn't quite understand that that's what it was doing.

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×