Search Unity

Sending a ref int as parameter and updating in the first script cuts the link?

Discussion in 'Scripting' started by Deleted User, Sep 6, 2016.

  1. Deleted User

    Deleted User

    Guest

    If I do something like this

    Code (CSharp):
    1. class FirstClass{
    2. int number;
    3.  
    4. void Start(){
    5. SendNumber();
    6. }
    7.  
    8. void Update{
    9. number = GetNewValue();
    10. }
    11.  
    12. SendNumber(){
    13. SecondClass.SendNumber(ref number);
    14. }
    the receiving class does not get the updated value for number. Any way around it?
     
  2. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
  3. Deleted User

    Deleted User

    Guest

    I know that Update is called after but I thought that the ref would persist. The reason it works for structs, lists and arrays is cause we never replace the referenced object itself but values within it?

    Maybe that's the solution, to send it as a struct?
     
  4. Deleted User

    Deleted User

    Guest

    That didn't work either unfortunately. Can someone please explain to me what I'm doing wrong? I don't understand why this does not work. Does it work for arrays at least?

    After some testing it seems to work for arrays. Why not structs?
     
    Last edited by a moderator: Sep 6, 2016
  5. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    That's not how ref works. Assignments to number in SendNumber would affect number in FirstClass but assigning number to some other int member in SecondClass doesn't hold onto the reference to FirstClass.number. Structs work the same way because they're treated as value types.

    What are you trying to do?
     
  6. Deleted User

    Deleted User

    Guest

    Thank you. So I haven't done anything wrong when I tried arrays, is it true they work like?

    I'm trying to have a script which reads all inputs and I wanted to have to only send the inputs once using ref.
     
  7. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Arrays aren't value types.

    What do you mean by "read all inputs"? And where are you sending them? What are you doing with them once they get there?
     
  8. Deleted User

    Deleted User

    Guest

    They are ref types, but since it didn't work to use ref for value types I thought maybe it could be the same for using a reference type.

    I created another thread here recently and people suggested I should have a script that only reads Input.GetButton etc. Then instead of calling like 10 different methods to get the read input (for example from Jump script) I hoped it would work to send the struct once to other scripts.

    Edit: maybe using a class instead of a struct then? Or is it a bad idea to use this method.
     
  9. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Nope sorry.

    I didn't read the other thread you mentioned but I don't know that I agree with that advice. The Input class provided by Unity already does what you want (reads all input in a single place) and is designed to ensure that those values are consistent across an entire frame (so they can be used in multiple scripts reliably). You really don't gain anything by creating yet another wrapper class around Input.

    Code (csharp):
    1.  
    2. public class MyInput : MonoBehaviour
    3. {
    4.     public bool ButtonDown { get; private set; }
    5.     public MyInput Instance { get; private set; }
    6.  
    7.     void Awake() { Instance = this; }
    8.  
    9.     void Update()
    10.     {
    11.         ButtonDown = Input.GetMouseButton(0);
    12.     }
    13. }
    14.  
    15. // somewhere else
    16. void Update()
    17. {
    18.     // what does this get you
    19.     if (MyInput.Instance.ButtonDown)
    20.  
    21.     // that this doesn't?
    22.     if (Input.GetMouseButton(0))
    23. }
    24.  
    Now - if you're polling the same input in multiple places then it certainly makes sense to declare those KeyCodes or integers in a common place as constants.

    Code (csharp):
    1.  
    2. public const KeyCode MoveForward = KeyCode.W;
    3.  
    4. // everywhere you check input
    5. if (Input.GetKey(GameConstants.MoveForward))
    6.  
    This allows you to change key bindings in a single place instead of hunting down all your references and risk missing a few.
     
    Deleted User likes this.
  10. Deleted User

    Deleted User

    Guest

    Thank you again very much for your help. I'm gonna go with your solution instead and then I don't have to worry about this. I appreciate the lesson.