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

Bug When I access a variable from a certain script, it instantly changes to a certain value

Discussion in 'Scripting' started by BrewinNJuicin, May 21, 2023.

  1. BrewinNJuicin

    BrewinNJuicin

    Joined:
    Feb 25, 2022
    Posts:
    11
    Hello all,
    Beginner here. So I have 1 script where 2 of my other scripts are getting variable(s) from. The main variable I want to focus on is the variable totalVenom from the AntManager script. This one script, AntMovement, instantly changes this variable's value to 156 for only its script for some reason when the condition below is met.
    Code (CSharp):
    1.  
    2. //this is in the AntMovement script
    3. public void OnCollisionEnter2D(Collision2D collision)
    4.     {
    5.         Debug.Log("collision enter");
    6.  
    7.         if (collision.gameObject.tag == "food")
    8.         {
    9.             Debug.Log("food tag collided");
    10.             touchingFood = true;
    11.         }
    12.     }
    I don't know why this happens, and I don't know how to stop it from happening. I would like it to stop happening. I also want to know why the value of totalVenom change to 156 for all scripts. Attached below are my scripts that access the totalVenom variable:
    AntManager.cs:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class AntManager : MonoBehaviour
    6. {
    7.     public AntMovement _AntMovement;
    8.     public GameObject ant;
    9.     public GameObject food;
    10.     private GameObject newAnt;
    11.     public List<GameObject> ants = new List<GameObject>();
    12.     private float randomYPos;
    13.     public float spawnCooldown = 5.0f;
    14.     private float spawnTimer = 0;
    15.  
    16.     public float speed = .8f;
    17.     private int _totalVenom;
    18.     public int totalVenom
    19.     {
    20.         get
    21.         {
    22.             return _totalVenom;
    23.         }
    24.  
    25.         set
    26.         {
    27.             _totalVenom = value;
    28.         }
    29.     }
    30.     public int venomBite = 3;
    31.     public bool spawnedRight;
    32.     private bool antCooldownTimer = true;
    33.  
    34.     private void Start()
    35.     {
    36.         totalVenom = 0;
    37.         //StartCoroutine(AddVenom());
    38.     }
    39.  
    40.     void Update()
    41.     {
    42.         Debug.Log("totalVenom variable from AntManager script: " + totalVenom);
    43.  
    44.         if (antCooldownTimer)
    45.         {
    46.             spawnTimer += Time.deltaTime;
    47.  
    48.             if (spawnTimer > spawnCooldown)
    49.             {
    50.                 SpawnAnt();
    51.                 spawnTimer = 0;
    52.             }
    53.         }
    54.  
    55.         /*
    56.         if (ant.GetComponent<AntMovement>().touchingFood == true)
    57.         {
    58.             Debug.Log("venomTimer variable: " + venomTimer);
    59.             venomTimer += Time.deltaTime;
    60.  
    61.             if (venomTimer > venomCooldown)
    62.             {
    63.                 Debug.Log("totalVenom += venomBite;");
    64.                 totalVenom += venomBite;
    65.                 venomTimer = 0;
    66.             }
    67.         }
    68.         */
    69.  
    70.         if (Input.GetMouseButtonDown(0)) //check if mouse1 (left click) is pressed
    71.         {
    72.             RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero); //casts a raycast to where you clicked
    73.  
    74.             if (hit.collider != null)
    75.             {
    76.                 if (hit.collider.gameObject.CompareTag("Ant"))
    77.                 {
    78.                     GameObject clickedAnt = hit.collider.gameObject;
    79.                     ants.Remove(clickedAnt);
    80.                     Destroy(clickedAnt);
    81.                 }
    82.             }
    83.         }
    84.  
    85.         /*
    86.         if (_AntMovement.touchingFood && venomCoroutine == null)
    87.         {
    88.             Debug.Log("yep");
    89.             venomCoroutine = StartCoroutine(AddVenom());
    90.         }
    91.         else if (!_AntMovement.touchingFood && venomCoroutine != null)
    92.         {
    93.             Debug.Log("nope");
    94.             StopCoroutine(venomCoroutine);
    95.             venomCoroutine = null;
    96.         }
    97.         */
    98.     }
    99.  
    100.     void SpawnAnt()
    101.     {
    102.         float randomSpawn = Random.Range(0f, 2f);
    103.         randomYPos = Random.Range(-7f, 6.45f);
    104.  
    105.         if (randomSpawn > 1f)
    106.         {
    107.             newAnt = Instantiate(ant);
    108.             ants.Add(newAnt);
    109.             ant.transform.position = new Vector2(10.25f, randomYPos); // ant will spawn on the right side
    110.             spawnedRight = true;
    111.         }
    112.         else
    113.         {
    114.             newAnt = Instantiate(ant);
    115.             ants.Add(newAnt);
    116.             ant.transform.position = new Vector2(-10.40f, randomYPos); //ant will spawn on the left side
    117.             spawnedRight = false;
    118.         }
    119.     }
    120.  
    121.     public IEnumerator AddVenom()
    122.     {
    123.         while (true)
    124.         {
    125.             if (_AntMovement.touchingFood == true)
    126.             {
    127.                 Debug.Log("AddVenom() IEnumerator is executing");
    128.                 Debug.Log("totalVenom variable: " + totalVenom);
    129.  
    130.                 yield return new WaitForSeconds(3f);
    131.                 totalVenom += venomBite;
    132.             }
    133.  
    134.             yield return null;
    135.         }
    136.     }
    137.  
    138. }
    139.  
    FoodManager.cs:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class FoodManager : MonoBehaviour
    6. {
    7.    public AntManager _AntManager;
    8.     public int foodHealth = 100;
    9.     private float venomPercentage;
    10.  
    11.     void Update()
    12.     {
    13.         Debug.Log("venomPercentage variable: " + venomPercentage);
    14.         Debug.Log("totalVenom variable from FoodManager script: " + _AntManager.totalVenom);
    15.         venomPercentage = _AntManager.totalVenom / foodHealth;
    16.  
    17.         if (venomPercentage > .5)
    18.         {
    19.             Debug.Log("venom percentage is greater than 50%; run the losing credits screen");
    20.         }
    21.     }
    22. }
    23.  
    And AntMovement, where the problem occurs
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class AntMovement : MonoBehaviour
    6. {
    7.     public AntManager _AntManager;
    8.     public bool touchingFood = false;
    9.     private float offset;
    10.     private float venomTimer = 0;
    11.     public float venomCooldown = 2.0f;
    12.  
    13.     void Update()
    14.     {
    15.         Debug.Log("touchingFood variable: " + touchingFood);
    16.         Debug.Log("totalVenom variable from AntMovement script: " + _AntManager.totalVenom);
    17.  
    18.         if (touchingFood)
    19.         {
    20.             Debug.Log("venomTimer variable: " + venomTimer);
    21.             venomTimer += Time.deltaTime;
    22.  
    23.             if (venomTimer > venomCooldown)
    24.             {
    25.                 Debug.Log("totalVenom += venomBite;");
    26.                 _AntManager.totalVenom += _AntManager.venomBite;
    27.                 Debug.Log("totalVenom variable from if statement: " + _AntManager.totalVenom);
    28.                 venomTimer = 0;
    29.             }
    30.         }
    31.        
    32.         if (touchingFood == false)
    33.         {
    34.             float xDiff = _AntManager.food.transform.position.x - transform.position.x;
    35.             float yDiff = _AntManager.food.transform.position.y - transform.position.y;
    36.  
    37.             float radians = Mathf.Atan2(yDiff, xDiff);
    38.             float degrees = radians * Mathf.Rad2Deg;
    39.  
    40.             transform.rotation = Quaternion.Euler(0, 0, degrees + offset); //rotates ant towards the food
    41.             transform.position = Vector2.MoveTowards(transform.position, _AntManager.food.transform.position, _AntManager.speed * Time.deltaTime); //moves ant towards the food
    42.         }
    43.     }
    44.  
    45.     public void OnCollisionEnter2D(Collision2D collision)
    46.     {
    47.         Debug.Log("collision enter");
    48.  
    49.         if (collision.gameObject.tag == "food")
    50.         {
    51.             Debug.Log("food tag collided");
    52.             touchingFood = true;
    53.         }
    54.     }
    55. }
    56.  
    I've been on this tiring problem for days now, and I really need to get an answer as this is for my school project. Thanks!
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    Oh my goodness, don't waste another minute fooling around!!!

    Time to start debugging! Here is how you can begin your exciting new debugging adventures:

    You must find a way to get the information you need in order to reason about what the problem is.

    Once you understand what the problem is, you may begin to reason about a solution to the problem.

    What is often happening in these cases is one of the following:

    - the code you think is executing is not actually executing at all
    - the code is executing far EARLIER or LATER than you think
    - the code is executing far LESS OFTEN than you think
    - the code is executing far MORE OFTEN than you think
    - the code is executing on another GameObject than you think it is
    - you're getting an error or warning and you haven't noticed it in the console window

    To help gain more insight into your problem, I recommend liberally sprinkling
    Debug.Log()
    statements through your code to display information in realtime.

    Doing this should help you answer these types of questions:

    - is this code even running? which parts are running? how often does it run? what order does it run in?
    - what are the names of the GameObjects or Components involved?
    - what are the values of the variables involved? Are they initialized? Are the values reasonable?
    - are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

    Knowing this information will help you reason about the behavior you are seeing.

    You can also supply a second argument to Debug.Log() and when you click the message, it will highlight the object in scene, such as
    Debug.Log("Problem!",this);


    If your problem would benefit from in-scene or in-game visualization, Debug.DrawRay() or Debug.DrawLine() can help you visualize things like rays (used in raycasting) or distances.

    You can also call Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene manually, looking for all the parts, where they are, what scripts are on them, etc.

    You can also call GameObject.CreatePrimitive() to emplace debug-marker-ish objects in the scene at runtime.

    You could also just display various important quantities in UI Text elements to watch them change as you play the game.

    Visit Google for how to see console output from builds. If you are running a mobile device you can also view the console output. Google for how on your particular mobile target, such as this answer or iOS: https://forum.unity.com/threads/how-to-capturing-device-logs-on-ios.529920/ or this answer for Android: https://forum.unity.com/threads/how-to-capturing-device-logs-on-android.528680/

    If you are working in VR, it might be useful to make your on onscreen log output, or integrate one from the asset store, so you can see what is happening as you operate your software.

    Another useful approach is to temporarily strip out everything besides what is necessary to prove your issue. This can simplify and isolate compounding effects of other items in your scene or prefab.

    Here's an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

    https://forum.unity.com/threads/coroutine-missing-hint-and-error.1103197/#post-7100494

    "When in doubt, print it out!(tm)" - Kurt Dekker (and many others)

    Note: the
    print()
    function is an alias for Debug.Log() provided by the MonoBehaviour class.
     
    BrewinNJuicin and Bunny83 like this.
  3. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,495
    My guess is that you don't reference the correct instance of your script(s). This is probably one of the most common mistakes. You can determine that easily by modifying your Debug.Log statements to include a context object, like this:

    Code (CSharp):
    1.     Debug.Log("totalVenom variable from AntMovement script: " + _AntManager.totalVenom, _AntManager);
    Note the second argument at the end. Now when you click on this log message in the console, the Unity editor will highlight / ping that context object in the hierarchy / project view. I guess that you have an AntManager instance in the scene and you may also have a prefab in your project. Prefabs are also objects (that serve as object templates) they just don't live in the scene. Even thought prefabs objects don't receive any callbacks, they are actual objects in memory. So you can read / write variables and even call methods on them.

    If this doesn't help, check aall the other cases where you access this "manager".
     
    BrewinNJuicin likes this.
  4. BrewinNJuicin

    BrewinNJuicin

    Joined:
    Feb 25, 2022
    Posts:
    11
    Thank you for both of your guys' help. I am trying out your guys' recommendations/solutions right now and I will update you guys with my findings.
    Also, what do you mean by "instance"?
     
  5. BrewinNJuicin

    BrewinNJuicin

    Joined:
    Feb 25, 2022
    Posts:
    11
    Alright, I added "_AntManager" as another parameter to the Debug.Log's in my AntMovement script. When I click the debugs in the console, it doesn't ping the AntManager object I have in the hierarchy. Also, it seems to now show that the value the AntMovement script sets the totalVenom variable as the previous value it got to in the previous play test for some reason. For example, the first playtest logged the totalVenom variable up to 48 (only for the AntMovement script though). The next playtest right after that logged the totalVenom variable as 48 when it first started logging the totalVenom variable (only for the AntMovement script once again).
    After doing this debugging, I realized something, but I don't know if it's going to get me anywhere. I referenced AntManager to my Ant prefab (note, my Ant prefab has the AntMovement script on it) by dragging my AntManager empty gameObject (this holds the AntManager script) from the hierarchy into the Assets folder in the Project tab, and then into my Ant prefab's Inspector onto the AntMovement script component. Is this the reason why the value of totalVenom is different for just the AntMovement script, or am I getting no where? If this is the reason why totalVenom is different for just the AntMovement script, how can I fix this? Thanks.
     
    Last edited: May 21, 2023
  6. BrewinNJuicin

    BrewinNJuicin

    Joined:
    Feb 25, 2022
    Posts:
    11
    Great update - I fixed it! My realization was correct and I fixed my problem. So what I did was I changed the _AntManager variable in my AntMovement script to a gameObject variable. I then added a new variable, with that being "public AntManager AntManagerScript;". I then did this in the Awake() function:
    Code (CSharp):
    1. private void Awake()
    2.     {
    3.         _AntManager = GameObject.Find("AntManager");
    4.         AntManagerScript = _AntManager.GetComponent<AntManager>();
    5.     }
    I then changed every place where I had _AntManager. (to refer to the AntManager script) to AntManagerScript.
    And now, the totalVenom variable updates for all scripts, and it doesn't randomly set to a random value every time I playtest it, all thanks to both of you guys. Once again, thank you both. I'm glad you both told be about Debug.Break(); and Debug.Log capable of having 2 parameters instead of just one, as those both told me the smoking guns on what my problem was. This leads me closer to finishing my first video game that will also be my school project, so thank you both.
     
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
  8. BrewinNJuicin

    BrewinNJuicin

    Joined:
    Feb 25, 2022
    Posts:
    11
    Interesting... I'll keep that noted. Knowing this, I slightly changed my script. It's basically like the last script I posted but instead of having this line of code: _AntManager = GameObject.Find("AntManager");, I put this line of code: _AntManager = GameObject.FindWithTag("AntManager");.