Is it possible to make a variable publicly viewable but not publicly changeable?

I have a variable that I would like to make it so any other class can view that variable, like a public variable, but NOT be able to directly change that class, like a private variable.

Is there a way to do this?

Does this help?

Good Luck.

Simple getter public method would work, like “public int ReadInteger(){return privateInteger;}” would allow this type of behavior. Then you just call that like “localInteger = ThatScript.ReadInteger();”

Is that saying “leave it public to this class and private to everything else” sort of ?

It’s a private variable , which like a public variable can be accessed outside the class for reading (with that method from my last post), but without a similar “setter” method you couldn’t change its value outside the class.

Edit: so yes, to answer your question it means you could do all changes within the script (changing the private variables value) and still “read” the value from other scripts.

Properties ok? I almost never make variables public in classes and explicitly define properties for almost every variable I want to expose to other classes so I can be sure I’m explicitly declaring my readonly types… The only time I make public variables is if in Unity I want to assign something in the inspector, or

public class ReadOnlyVarClass
{
     private int ReadOnlyValue = 5;

     public int Value
     {
          get
          {
               return ReadOnlyValue;
          }
     }
}

This will also work, obviously, if the class extends MonoBehavior (or anything else)…

If you’re working in Java, I’m not sure it has properties and you may have to explicitly declare a return function.

Properties, however, won’t make a List or other collection readonly - as it will be passing back a reference type. However you can explicitly declare indexers for your class:

public class ReadOnlyList
{
    private List<int> MyList = new List<int>();

    public int this[int a]
    {
        get
        {
            return MyList[a];
         }
    }
}

So, in theory, you could construct a generic wrapper class that is returned if you want to pass back readonly lists.

However, if you want to assign your “private” variable in the Unity inspector, it cannot be private and must be public - that’s just how it works.

Huh, I never thought to make a public function that returns the value.
Even so, I would think this would be a functionality that is part of programming languages; it seems like a reasonable thing folks would want.

BloomingDedalus, won’t a read only variable be impossible to change even in its own class? That won’t suit my needs…

Exposing a public property with only a “get” function and not a “set” function makes it where you can’t alter the property value. The private variable itself can be changed by the class, the public property, not having a “set” method, cannot be changed. Properties are pretty much the same thing as creating return functions - but is explicitly implemented in C# to make it where it can act as a variable or a read only or set only function. That way both your return and set functions can share the same name.

https://msdn.microsoft.com/en-us/library/aa288470(v=vs.71).aspx

1 Like

properties are definatly the way to go here. However I would call it bad practise to just leave the setter out and instead to access the backing field direcly. Because you can not ensure value vallidation anymore.
Instead you should mark your setter as private and use it

private float _clampedFloat;
public float ClampedFloat
{
    get { return _clampedFloat; }
    private set { _clampedFloat= Mathf.Clamp( MIN, MAX, value ); }
}

also as a small tip, when you want to be able to change the value in the inspector and still want to ensure validation, you can do smething like that

[SerializeField]
private float _clampedFloat;
public float ClampedFloat
{
    get { return _clampedFloat; }
    private set { _clampedFloat= Mathf.Clamp( MIN, MAX, value ); }
}
// is called by Unity when ever a value in the inspector is changed
private void OnValidate()
{
    ClampedFloat = _clampedFloat;
}