Purple Ice Purple Ice - 3 months ago 14
C# Question

Is there a way to get a random value into this class?

Note: sorry for vague title, I really had no idea how to name it, mainly because I don't know what kind of issue it is.

EDIT: I know that I can do it by simply using a struct and overriding some operators, but the whole point of this is making it as close as possible to the actual float, in both usage and functionality, except it would be a lot harder to access it in memory and change it, if it's not possible, I can deal with it.

I am trying to create a safe value type which simply offsets real values, I need that so I can at least partially protect them from people simply using Cheat engine or anything else and changing them to whatever they want, is there a way to get a random number into it which wouldn't cause values to overflow whenever it was offset?

Here's my code:

public class safeFloat {
private float val;
//private int offset = Random.Range(-1000, 1000);

public float Val
{
get
{
return val; //- offset;
}
set
{
val = value; //+ offset;
}
}

public static implicit operator safeFloat(float value)
{
return new safeFloat(){Val = value};
}

public static implicit operator float(safeFloat x)
{
return x.Val;
}
}


Obviously at the moment it does nothing, the parts of code which don't work are commented out, I had no idea that I can't do it simply like that. This is the error I would get if I tried to create safeFloat and assign some value to it, when nothing is commented out:

ArgumentException: RandomRangeInt can only be called from the main thread. Constructors and field initializers will be executed from the loading thread when loading a scene. Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function. UnityEngine.Random.Range (Int32 min, Int32 max)


Since unity suggests using Awake() or Start() which isn't an option since this is just a "helper" class, not something I will put on an object in game, is there anything I can do?

Question not so relevant to the main topic: I've never tried code in different manner, so I don't even know if it would work, if there are flaws in my logic, could you please point them out?

Answer

Try this (actually I tested it, and it works).

The reason for this approach is that you tried to initialize the offset in constructor. To fix this just use this.

public class safeFloat 
{
    private float val;
    private int offset;

    private bool offsetSet = false;

    public float Val
    {
        get
        {
            if(!offsetSet)
                offset = Random.Range(-1000, 1000);                
            offsetSet = true;

            return val - offset;
        }
        set
        {
            if(!offsetSet)
                offset = Random.Range(-1000, 1000);                
            offsetSet = true;

            val = value + offset;
        }
    }

    public static implicit operator safeFloat(float value)
    {
        return new safeFloat(){Val = value};
    }

    public static implicit operator float(safeFloat x)
    {
        return x.Val;
    }
}