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 Changes made to script values during play mode don't take effect

Discussion in 'Editor & General Support' started by somuchforpathos, Aug 14, 2023.

  1. somuchforpathos

    somuchforpathos

    Joined:
    Jan 28, 2022
    Posts:
    5
    Hi, I started getting this last night and I'm not sure whether this is a bug or I've accidentally enabled something.

    Essentially play mode is working the wrong way round. Any changes I make to public variables in my scripts don't take effect while in play mode, then when I exit play mode the values I've changed don't reset to their original values before I entered play mode.

    Anyone know what might be causing this? I tried googling it but it's mostly people looking for a way to have changes made in play mode persist.
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,718
    Show us the code, exactly what you're changing, and exactly what's happening.
     
    CodeSmile likes this.
  3. somuchforpathos

    somuchforpathos

    Joined:
    Jan 28, 2022
    Posts:
    5
    I have a class that contains variables for my enemies so I can easily tweak them:

    Code (CSharp):
    1. public class EnemyInfo : MonoBehaviour
    2. {
    3.     // Enemy Stats
    4.     public float health;
    5.     public float moveSpeed;
    6.     public float attackDamage;
    7.     public float attackDelaySeconds; // Time between enemy attacks
    8.     public float attackRange;
    9.     public float attackVelocity;
    10.     public int attackStyle; // used for switch statement in EnemyController that defines how enemy attacks
    11.     public float mass;
    12.  
    13.     public bool immuneKnockback;
    14. }
    upload_2023-8-14_14-54-48.png

    But changes I make here don't change anything (it's been working fine until yesterday). As an example changing Move Speed there makes no difference.

    Code (CSharp):
    1.     void Update()
    2.     {
    3.         EnemyAttack(enemyInfo.attackStyle); // Atacks player using attackStyle referenced in enemyInfo
    4.         EnemyMove(); // Moves the enemy gradually towards the player
    5.         DestroyEnemy(); // If Enemy has no health, destroy the enemy
    6.     }
    7.  
    8.     void EnemyMove()
    9.     {
    10.         playerPos = player.transform.position; // player position
    11.         enemyPos = transform.position; // enemy position
    12.  
    13.         // normalise the vector from the enemy to the player then multiplied by the enemy's speed to move the enemy towards the player at a constant speed
    14.         transform.Translate((playerPos - enemyPos).normalized * enemyInfo.moveSpeed * Time.deltaTime, Space.World);
    15.     }
     

    Attached Files:

  4. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,718
    We're missing a lot of information here. You are using a MonoBehaviour just as a data container? On which object did you attach this
    EnemyInfo
    script? Which instance of the script is your other unnamed script referring to? Can you show how you set the references up and explain where and when you are making changes in the inspector?

    At first glance it just looks like you are probably not changing the values on the correct instance of the script or you have referenced a different instance than you expect.
     
  5. somuchforpathos

    somuchforpathos

    Joined:
    Jan 28, 2022
    Posts:
    5
    These two scipts are attached to the enemy prefabs which are instantiated by a SpawnManager script.

    Code (CSharp):
    1. public class EnemyController : MonoBehaviour
    2. {
    3.     // Class Components
    4.     private Rigidbody enemyRb; // create variable for Enemy Rigidbody to be assigned to
    5.     private GameObject player; // assign player game object to provide access to attributes
    6.  
    7.     // Enemy Stats
    8.     public EnemyInfo enemyInfo; // Gives access to the enemy stats contained in EnemyInfo
    9.  
    10.     // Class Variables
    11.     private Vector3 playerPos; // player position
    12.     private Vector3 enemyPos; // enemy position
    13.     private float timeSinceAttack; // Keeps track of time for attackSpeed
    14.  
    15.  
    16.     // Start is called before the first frame update
    17.     void Start()
    18.     {
    19.         enemyRb = GetComponent<Rigidbody>(); // assigns Enemy's Rigidbody to enemyRb
    20.         enemyRb.mass = enemyInfo.mass; // Sets enemy mass to mass set in EnemyInfo
    21.         enemyInfo = GetComponent<EnemyInfo>(); // assigns EnemyInfo's variables to enemyInfo
    22.  
    23.         player = GameObject.Find("Player"); // assign player game object to provide access to components
    24.     }
    25.  
    26.     // Update is called once per frame
    27.     void Update()
    28.     {
    29.         EnemyAttack(enemyInfo.attackStyle); // Atacks player using attackStyle referenced in enemyInfo
    30.         EnemyMove(); // Moves the enemy gradually towards the player
    31.         DestroyEnemy(); // If Enemy has no health, destroy the enemy
    32.     }
    33.  
    34.     void EnemyMove()
    35.     {
    36.         playerPos = player.transform.position; // player position
    37.         enemyPos = transform.position; // enemy position
    38.  
    39.         // normalise the vector from the enemy to the player then multiplied by the enemy's speed to move the enemy towards the player at a constant speed
    40.         transform.Translate((playerPos - enemyPos).normalized * enemyInfo.moveSpeed * Time.deltaTime, Space.World);
    41.     }
    Code (CSharp):
    1. public class EnemyInfo : MonoBehaviour
    2. {
    3.     // Enemy Stats
    4.     public float health;
    5.     public float moveSpeed;
    6.     public float attackDamage;
    7.     public float attackDelaySeconds; // Time between enemy attacks
    8.     public float attackRange;
    9.     public float attackVelocity;
    10.     public int attackStyle; // used for switch statement in EnemyController that defines how enemy attacks
    11.     public float mass;
    12.  
    13.     public bool immuneKnockback;
    14. }
    15.  
    I also don't think I made myself very clear, this code works, I can change it and enter play mode and the changes take effect and work as expected. The issue is if I then make changes in the inspector during play mode nothing changes, those values then also don't reset exiting play mode. I can then hit play mode again and the changes take effect.

     
  6. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    Well you're changing the values of a prefab asset. Any changes to actual assets will persist between play mode sessions.

    It's only the stuff that lives in scenes that get reset.

    Mind you some of these values are probably better living on a scriptable object.
     
  7. somuchforpathos

    somuchforpathos

    Joined:
    Jan 28, 2022
    Posts:
    5
    Ah thank you, knew it had to be something silly. The course I'd been learning from seemed to imply that anything changed in play mode would be reset.

    So when I switched to using a spawn manager for the enemies it stopped behaving how I expected.

    Could you give an example from what I've done? Would be good to know what I can be doing better.
     
  8. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    A lot of this immutable info doesn't have to be designed on a prefab/per instance basis, but but can be done as scriptable objects:

    Code (CSharp):
    1. [CreateAssetMenu(menuName = "Enemies/Enemy Info")]
    2. public class EnemyStats : ScriptableObject
    3. {
    4.     [SerializeField]
    5.     private int _maxHealth = 100;
    6.    
    7.     [SerializeField]
    8.     private float _movementSpeed = 3f;
    9.    
    10.     public int MaxHealth => _maxHealth;
    11.    
    12.     public float MovementSpeed => _movementSpeed;
    13.    
    14.     // etc etc
    15. }
    Then you just reference this SO on your prefabs as needed, and read the values off of them.

    If you don't know what those are, definitely worth reading up on them.

    Of course if this needs to change on a per-instance basis you will need something more elaborate.
     
    somuchforpathos likes this.
  9. somuchforpathos

    somuchforpathos

    Joined:
    Jan 28, 2022
    Posts:
    5
    Oh cool, yeah that's sort of what I was trying to do with the EnemyInfo script, but didn't know there was a specific object that could be used for it, I'll have a look into it. Thanks again for the help.
     
    spiney199 likes this.