Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Unable to access private variable without [SerializeField] C# Unity

Discussion in 'Scripting' started by PowerThree, Jul 30, 2023.

  1. PowerThree

    PowerThree

    Joined:
    Jul 16, 2023
    Posts:
    1
    Code (CSharp):
    1. //MonserId.cs script
    2.  
    3. public class MonsterId : MonoBehaviour
    4. {
    5.     [SerializeField] private string monsterId; // <-- this variable if not serialized, gives null
    6.     public string Getter()
    7.     {
    8.         //Debug.Log(monsterId);
    9.         return monsterId;
    10.     }
    11.     public void Setter(string uuid)
    12.     {
    13.    
    14.         monsterId=uuid;
    15.         //Debug.Log(monsterId);
    16.     }
    17. }
    18.  
    19. AND
    20.  
    21. //EnemyHealth.cs script
    22.  
    23. Debug.Log(this.gameObject.GetComponentInChildren<MonsterId>().Getter());
    24.  
    25. OR
    26.  
    27. private MonsterId slime;
    28.  
    29. slime = this.gameObject.GetComponent<MonsterId>();
    30.  
    31. spawner.GetComponent<Spawner>().DeleteMonster(slime.Getter());
    The EnemyHealth.cs and MonsterId.cs are both added to GameObject slime.

    The idea here, I am using a setter to apply a uuid to the monster. Then using a getter to grab that uuid variable. With the code as is. It works, but I find myself having keep the [SerializeField] tag in front of the private variable. Why is this? I apologize for lack of knowledge. OOP is new to me!

    Lastly, I wanted to say the field is private according to everyone's posts I've read. But why does it need to be in Inspector for it to accessible between classes? AND if i dont include [SerializeField], and just private. I am unable to access it and get null values. Why? Why? Why? Lol..
     
    Last edited: Jul 30, 2023
  2. CodeRonnie

    CodeRonnie

    Joined:
    Oct 2, 2015
    Posts:
    284
    I would try to make less use of GetComponent, but just looking at the MonsterID component, I would change it to something like this:
    Code (CSharp):
    1. public class MonsterID : MonoBehaviour
    2. {
    3.     [SerializeField]
    4.     [HideInInspector]
    5.     private string _monsterId;
    6.  
    7.     public string ID { get => _monsterId; set => _monsterId = value; }
    8.  
    9.  
    10.     // Example Usage
    11.     private string SlimeID;
    12.  
    13.     private void Example()
    14.     {
    15.         Debug.Log(GetComponentInChildren<MonsterID>().ID);
    16.  
    17.         SlimeID = GetComponent<MonsterID>().ID;
    18.         GetComponent<Spawner>().DeleteMonster(SlimeID);
    19.     }
    20. }
    Private members are not serialized by default. That means the value of those properites will not be saved with scene files or prefabs. I suspect that's your root issue. If you don't want the variable to appear at all in the inspector use [HideInInspector].
     
  3. tsukimi

    tsukimi

    Joined:
    Dec 10, 2014
    Posts:
    50
    It does not have to be
    [SerializeField]
    for it to be accessible between classes; however, it will not store the value between plays if it is not
    [SerializeField]
    . That is, every time you replay your game, you will have to re-assign it, or it will return to null.
    On the other side, it sould return the same value set in the same play, even you don't have
    [SerializeField]
    . For example: the below code should output "Some-Id".
    Code (CSharp):
    1. var monsterId = gameObect.GetComponent<MonsterId>();
    2. monsterId.Setter("Some-Id");
    3. Debu.Log(monsterId.Getter());
    If it does not, you may want to check:
    1. Did you retrieve the monsterId from a different GameObject?
    2. Did you set another monsterId (from another route) to the same GameObject?
     
  4. wideeyenow_unity

    wideeyenow_unity

    Joined:
    Oct 7, 2020
    Posts:
    728
    I've never really paid attention to serialize field, as I thought that was just for showing a private variable in the inspector. It's way more than that, as https://docs.unity3d.com/Manual/script-Serialization.html states.

    Talk about a read and a half, thanks... lol..

    But looking into using UUID seems unneeded for a non-hackable game, as this website states :
    UUIDs are globally unique. In other words, we can identify each record in the database with an ID that is unique across tables, databases, and systems. The latter is especially important in distributed systems where we may add or remove nodes dynamically, and coordination between them can be challenging. The collision is only theoretically possible.

    Furthermore, they provide additional security since the next value is hard to predict. Therefore, it makes it almost impossible for a malicious user to guess the ID. On the other hand, such a user can easily guess the next value of sequential IDs.

    So I am a bit confused on the necessity of it, in your case. Are you meaning to use unity's InstanceID?