Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Issue with variable not properly changing

Discussion in 'Scripting' started by Zefalcon, Nov 16, 2017.

  1. Zefalcon

    Zefalcon

    Joined:
    Jun 17, 2016
    Posts:
    7
    I have this really weird bug happening with one of my switch statements where I change the variable outside Update (where the switch statement is located), and by the time Update starts, the variable is back to its default value. And it only happens with that specific enum value; all the others work just fine.

    Here's the class in its entirety to hopefully shed some light on the problem:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class InsectLeg : MonoBehaviour {
    6.  
    7.     public enum Direction {
    8.         Forward, Backward, FootUp, FootDown, Still
    9.     }
    10.  
    11.     public int forward; //Which direction is "forward"?  1 if positive z rotation, -1 if negative z rotation
    12.  
    13.     Direction legMotion;
    14.     Direction footPosition = Direction.FootUp;
    15.  
    16.     public GameObject foot;
    17.  
    18.     // Use this for initialization
    19.     void Start () {
    20.         legMotion = Direction.Still;
    21.     }
    22.    
    23.     // Update is called once per frame
    24.     void Update () {
    25.         switch (legMotion) {
    26.             case Direction.Forward: {
    27.                     transform.Rotate(Vector3.back, forward);
    28.                     break;
    29.                 }
    30.             case Direction.Backward: {
    31.                     transform.Rotate(Vector3.back, -forward);
    32.                     break;
    33.                 }
    34.             case Direction.Still: {
    35.                     transform.Rotate(Vector3.back, 0f);
    36.                     break;
    37.                 }
    38.         }
    39.  
    40.         switch (footPosition) {
    41.             case (Direction.FootDown): {
    42.                     foot.SetActive(true);
    43.                     break;
    44.                 }
    45.             case (Direction.FootUp): {
    46.                     foot.SetActive(false);
    47.                     break;
    48.                 }
    49.         }
    50.  
    51.         //Testing
    52.         /*if (Input.GetKeyDown(KeyCode.F)) {
    53.             RotateForward();
    54.         }
    55.         if (Input.GetKeyDown(KeyCode.K)) {
    56.             RotateBackward();
    57.         }
    58.         if (Input.GetKeyDown(KeyCode.U)) {
    59.             SetFootUp();
    60.         }
    61.         if (Input.GetKeyDown(KeyCode.D)) {
    62.             SetFootDown();
    63.         }*/
    64.     }
    65.  
    66.     public void RotateForward() {
    67.         if (legMotion == Direction.Backward) {
    68.             legMotion = Direction.Still;
    69.         }
    70.         else {
    71.             legMotion = Direction.Forward;
    72.         }
    73.     }
    74.  
    75.     public void RotateBackward() {
    76.         if (legMotion == Direction.Forward) {
    77.             legMotion = Direction.Still;
    78.         }
    79.         else {
    80.             legMotion = Direction.Backward;
    81.         }
    82.     }
    83.  
    84.     public void Halt() {
    85.         legMotion = Direction.Still;
    86.     }
    87.  
    88.     public void SetFootDown() {
    89.         footPosition = Direction.FootDown;
    90.     }
    91.  
    92.     public void SetFootUp() {
    93.         footPosition = Direction.FootUp;
    94.     }
    95. }
    I call RotateForward() from another class. Using Debug statements, I know that the else loop is running as expected and legMotion is the correct value at the end of the method. But the actual rotation (and that entire case) never happens because at the top of the Update function, legMotion is Still again. As I said above, the other methods (RotateBackward(), SetFootDown(), and SetFootUp()) work just fine. It's only forward that fails.
    Possibly also important is that the testing key commands I have added in don't work anymore (when not commented out as they are here), but that's not really an issue as they won't be in the final version.

    Other possibly useful information: the object being rotated has a NetworkTransform, and the method in question is being called by another NetworkBehaviour object.

    Please help if you can. This is driving me insane.
     
  2. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,765
    Sounds like you have a script execution order issue.
    https://docs.unity3d.com/Manual/ExecutionOrder.html
    Maybe you are calling the script functions before the Start is called on the script.

    You could change line 13 to set legMotion to the default value of Still and not set it in Start
    Code (csharp):
    1.  
    2. Direction legMotion = Direction.Still;
    3.  
    or move "Still" to the beginning of the enum so it's the default value

    or change the script execution order of "InsectLeg" to ensure its Start is called before your external class calls the functions.
     
  3. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    970
    You probably want to consider using a state machine for this type of logic. Don't let other scripts be able to immediately set the leg state. Set what the leg's next state should be.

    Or consider using LateUpdate() instead of Update() which allows all other scripts to do their thing, then in LateUpdate(), the leg figures out what it's supposed to do based on all the feedback it got.