Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only. On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live. Read our full announcement for more information and let us know if you have any questions.

Question Send a varuable (pointers)

Discussion in 'Scripting' started by Programer_YEAA, Jul 28, 2022.

  1. Programer_YEAA

    Programer_YEAA

    Joined:
    Jun 3, 2022
    Posts:
    91
    If I do
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Pointers : MonoBehaviour
    6. {
    7.     int c = 5;
    8.  
    9.     B b = new();
    10.  
    11.     public void Start()
    12.     {
    13.         b.setD(c);
    14.     }
    15.  
    16.     public void Update()
    17.     {
    18.         c++;
    19.  
    20.         b.update();
    21.     }
    22. }
    23.  
    24. public class B : MonoBehaviour
    25. {
    26.     int d = 0;
    27.  
    28.     public void setD(int x)
    29.     {
    30.         d = x;
    31.     }
    32.  
    33.     public void update()
    34.     {
    35.         Debug.Log("d:" + d);
    36.     }
    37. }
    Then it will only output 5.
    But what if I want c and d to store the same value, so it would output 5,6,7,8,9...
    I do know about pointers but not how to use them :(
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    8,647
    Pointers is more a C++ thing. In C# you refer to values as either a reference or value type. When you have a reference type, any fields are referencing the data in memory. Value types are just copied from place to place. (This is a very basic explanation.)

    So when you change a value in an instance of a reference type, those changes 'propagate' to anything else that has a reference to the same instance. Or more accurately, as they're all pointing to the same reference, they read the same changed value. This doesn't happen with value types.

    Classes are reference types, structs are value types. All basic values, int, bool, etc, are structs under the hood.

    So in your case, you can wrap value types in a reference type, usually a plain class, create an instance of it, and reference that in multiple locations.

    Also this:
    Code (CSharp):
    1. B b = new();
    Don't do this. You shouldn't/can't make instance of Monobehaviours this way. B could just be a plain class, and if you want a value to be consistent across multiple locations, they should all reference the same reference type (ergo, a class).

    In the context of Unity, there is where scriptable objects shine.
     
    Bunny83 likes this.
  3. Programer_YEAA

    Programer_YEAA

    Joined:
    Jun 3, 2022
    Posts:
    91
    Ok, I will try to understand scriptable objects.
    Thx for your time :)
     
  4. Programer_YEAA

    Programer_YEAA

    Joined:
    Jun 3, 2022
    Posts:
    91
    I still don't know how to solve my problem.
    My problem is that I want a tale of objects. Where one follows what in front of it. That means every object has it's own destination. So I wonder how I can pass the postion of one object to another one. I want to do this one time. So that the object knows at al time where it's neighbour is. All objects is stored in a stack.

    I don't see how scriptable objects is the solution becuse I have to make a new one for each object with it's own value and update it.
     
  5. mopthrow

    mopthrow

    Joined:
    May 8, 2020
    Posts:
    350
    How about something like a 'Follower' Monobehaviour with a publicly accessible reference to a leader GameObject. If you have a ref to the leader, you have its position (and everything else!) Put in on each object and set their leaders accordingly.

    To set the refs to the leaders, you can drag and drop the other object in to your script's public field in the inspector, or set programatically if your objects are already instantiated and you have refs to them in your stack already.

    Use the Update function in each Follower to move the object towards its target. Make this function according to how you want it to approach its leader and over how much time, if you want it to stop short etc. Lots of options here, MoveTowards(), LookAt() if you need to control its rotation, or implement some lerp or easing function for the movement.

    If you want to make a new instance of a class that inherits from MonoBehaviour, call AddComponent<T> on whichever game object you want to add it to instead of new, though new is still fine for plain C# classes as Spiney says above.

    You can move your leader and everything else should follow in a nice chain.

    Well, I'm sure there are other ways too :)
     
  6. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    8,647
    You can't just pass their position because Vector3 is a struct, aka a value type. You're better off letting each object have a reference to each other's transform component (a reference type), of which they can continually read its .position property to figure out where they should be.
     
  7. Programer_YEAA

    Programer_YEAA

    Joined:
    Jun 3, 2022
    Posts:
    91
    Interesting, do you know how to do SerializedField but with script insted of drag and drop?
     
  8. mopthrow

    mopthrow

    Joined:
    May 8, 2020
    Posts:
    350
    Hmm not sure what you mean by how to do SerializeField. I think you mean set the reference to another object?

    If you don't want to drag and drop, you could have something like a manager script on another gameobject responsible for setting things up. Have the manager script instantiate the game objects, add a Follower component to each using AddComponent. Something like this:

    Code (CSharp):
    1. var go = new GameObject(); //make new empty gameobject
    2. var follower = go.AddComponent<Follower>(); //add your follower script
    3. follower.SetLeader(SomeGameObjectYouWantToLeadThisOne);
    You have the component cached, so you can set the leaders from here.

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class Follower : MonoBehaviour
    4. {
    5.     [field: SerializeField] private GameObject leader;
    6.  
    7.     public void SetLeader(GameObject go)
    8.     {
    9.         leader = go;
    10.     }
    11.  
    12.     public void Update()
    13.     {
    14.         //make me move towards leader
    15.     }
    16. }
    If you don't have access to whatever you want to be the leader in advance, instantiate all the gameObjects, add them to a collection first, then set the references in a different pass.

    At least if I'm understanding your question correctly ;)
     
  9. Programer_YEAA

    Programer_YEAA

    Joined:
    Jun 3, 2022
    Posts:
    91
    By reading all your post I think I can take it from here. Thx you for your time and answers :)
     
  10. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    8,647
    'SerializeField' is just one way to get a reference, same as any of the numerous ways you can through C# or Unity centric means. This can mean using GetComponent, getting the return on Instantiate, or just manually setting up the links using the inspector.