Search Unity

Possible struct bug

Discussion in 'Scripting' started by darklight98, Sep 22, 2018.

  1. darklight98

    darklight98

    Joined:
    Jan 24, 2013
    Posts:
    18
    I'm working on a timed event controller, here is the code (feel free to use it):

    Code (CSharp):
    1.  
    2. //Libraries
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. //Package that contains info about the event and how
    7. //long it will last
    8. public struct actionEvent {
    9.     public System.Action action;
    10.     public float timeLeft;
    11.  
    12.     public actionEvent (System.Action _action, float _totalTime) {
    13.         this.action     = _action;
    14.         this.timeLeft   = _totalTime;
    15.     }
    16.  
    17.     public bool Run (float timepassed) {
    18.         this.timeLeft -= timepassed;
    19.         Debug.Log(timeLeft);
    20.  
    21.         if (timeLeft > 0) {
    22.             action();
    23.             return false;
    24.         }
    25.         else {
    26.             return true;
    27.         }
    28.     }
    29. }
    30.  
    31. //If an agent requires an event to occur during a certain time
    32. //They will resort to this controller
    33. public class eventController : Controller<eventController> {
    34.  
    35.     //List with all occuring events
    36.     protected static List<actionEvent> events = new List<actionEvent>();
    37.  
    38.     public void Start() {
    39.         //Start singleton service
    40.         ActivateSingleton(this);
    41.     }
    42.  
    43.     public static void subscribe (System.Action _action, float _totalTime, bool _overwrite = true) {
    44.         actionEvent newAction = new actionEvent(_action, _totalTime);
    45.         events.Add(newAction);
    46.     }
    47.  
    48.     void FixedUpdate () {
    49.         float delta = Time.smoothDeltaTime;
    50.  
    51.         for (int i = 0; i < events.Count; i++) {
    52.             bool dumpEvent = events[i].Run(delta);
    53.  
    54.             if (dumpEvent) {
    55.                 events.RemoveAt(i);
    56.             }
    57.         }
    58.     }
    59. }
    60.  
    The thing is, if I use actionEvent as a class, the time left counts correctly, going -0.02f everytime. But if I use actionEvent as struct, time left keeps stuck at the first decrement. This seems like a bug, could anyone explain me, why this happens?
     
  2. darklight98

    darklight98

    Joined:
    Jan 24, 2013
    Posts:
    18
    Got what's going wrong, structs are always passed by value (never by reference), so when I do this:

    Code (CSharp):
    1. bool dumpEvent = events[i].Run(delta);
    CSharp makes a copy of events and run it, it's not the same from the list I created, the workaround I found is this:

    Code (CSharp):
    1.  
    2.             actionEvent e = events[i];
    3.             bool dumpEvent = e.Run(delta);
    4.             events[i] = e;
    5.