- Home /
Modifying prefab's private variables with properties from values of another script.
I'm currently trying to use properties (Setter & Getter) to set values on private variables and making sure some constraints are respected, on a prefab. I created another script with public variables so I could set values in the Inspector, and in this scripts Start() function, I set the prefab's variables:
public class Initializer : MonoBehaviour
{
public float turretCannon_reloadTime; /*< ReloadTime to initialize the Turret_Cannon prefab. */
public float turretCannon_rotationSpeed; /*< RotationSpeed to initialize the Turret_Cannon prefab. */
public float turretCannon_sleepTime; /*< SleepTime to initialize the Turret_Cannon prefab. */
public GameObject turretCannon; /*< Reference to the Turret_Cannon prefab to retrieve script for initialization. */
private TurretCannon _turretCannon; /*< Reference to the Turret_Cannon prefab's script. */
void Start ()
{
_turretCannon = turretCannon.GetComponent<TurretCannon>();
_turretCannon.reloadTime = turretCannon_reloadTime;
_turretCannon.rotationSpeed = turretCannon_rotationSpeed;
_turretCannon.sleepTime = turretCannon_sleepTime;
}
}
I also have this for my prefab:
public class TurretCannon : MonoBehaviour
{
private float _reloadTime; /*!< Time to reload after a shot is fired. */
private float _rotationSpeed; /*!< Ball rotation speed multiplier. */
private float _sleepTime; /*!< Sleep before next shot fired after reload time. */
//...
public float reloadTime
{
set
{
// Check constraint
_reloadTime = value;
}
get
{
return _reloadTime;
}
}
//...
}
When I initialize my object after that, all my private variables (e.g.: _reloadTime) are either null or 0. However, if I set those variable public, everything is fine and working as intended.
From what I understood, private variables can only be changed/set once the object has been instantiated. Is that the case? Does that mean I'd better set a script that is called to initialize those values when the object is instantiated, rather than when my initializing script is started? Is there another work around? I'd prefer to keep my variable private to enforce those constraints without complicating it much more.
Edit: Using [System.NonSerialized] on public variables cause the same issue as setting it private. Basically, Unity has to have access to it from the inspector for this technique to work, which nullify the points of doing that in the first place. Why is it working this way?
Create a custom inspector and keep the variables public :)
@Benproductions1 Looks like it's the only viable alternative. At least the initializer script overwrite any value placed in the prefab's inspector. I can even add a [System.NonSerialized] to avoid them from showing. I just don't feel like the constraints are really enforced since others could use the public variables ins$$anonymous$$d of the properties.
@$$anonymous$$aivo When working in python (where "private" does not exist), I used to ponder on how I was going to ensure no one would "stuff anything up", but then I realized. Who cares? When they do something they aren't supposed to (like access a special, undocumented variable) they should take the responsibility for anything that goes wrong!
It's seriously nothing to worry about :)
@Benproductions1 $$anonymous$$aybe, but just in terms of clarity, I feel I better know where things are going when doing this that way. (Been doing C++ for a while and maybe I'm trying to hard to follow what I know.) I just find it annoying to have variables set on tons of different gameObject, I feel it's too easy to get lost in all that and centralizing it would be simpler, but it seems to be much worst right now.
Answer by Kaivo · Jun 30, 2013 at 02:00 PM
It is not possible to change private or NonSerialized variables on prefabs before they are instantiated.
The variables would have to either be updated after the objected is instantiated (which means one function call multiplied by the amount of instantiated object) or have its variable public and Serialized. It duplicates the variables in the inspector. (One set is displayed for the prefab, another on the Initializer script which could be confusing.)
However, the good side is that even though the variables can be set through the prefab's Inspector, they are automatically overwritten by the Initializer script that is called on start. This way, the variable constraints are enforced. The only issue that could arise is confusion if people not knowing how it was set would try to edit the prefab's variables.
Answer by foo-bar · Oct 16, 2020 at 07:56 AM
You can always change private variables with another script with the following approaches:
1. SerializedObject
var yourScript= go.GetComponent<YourScript>();
var so = new SerializedObject(yourScript);
so.FindProperty("nameOfYourPrivateVariable").vector3Value = Vector3.zero;
so.ApplyModifiedProperties();
3. System.Reflections
var yourScript = vehicle.GetComponent<TypeOfYourClass>();
var myFieldInfo = typeof(TypeOfYourClass).GetField("nameOfYourField", BindingFlags.NonPublic | BindingFlags.Instance);
var value = myFieldInfo.GetValue(yourScript);
Debug.Log(value.ToString());
myFieldInfo.SetValue(comVehicleController, YourValue);
var value2 = myFieldInfo.GetValue(yourScript);
Debug.Log(value2.ToString());
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
When to use public or private variables for the inspector? 2 Answers
C# Return Type Error? 1 Answer
Flip over an object (smooth transition) 3 Answers