Search Unity

how to get foreach gameobject in list a vector3 for position and rotation?

Discussion in 'Scripting' started by Aviation_Simmer, Aug 29, 2022.

  1. Aviation_Simmer

    Aviation_Simmer

    Joined:
    Aug 30, 2021
    Posts:
    110
    Hello! I am working on a script, which should contain the position and rotation for every gameobject in 1 list element per object. I have no clue how i could do this, but I have seen it before... maybe?

    from this
    upload_2022-8-29_21-39-10.png

    to this
    upload_2022-8-29_21-40-0.png

    Code (CSharp):
    1. {
    2.     public Vector3 Position;
    3.     public Vector3 Rotation;
    4.  
    5.     public List<float> Locations = new List<float>();
    6.  
    7.     void Update()
    8.     {
    9.  
    10.  
    11.         foreach (float loc in Locations)
    12.         {
    13.             Position = new Vector3(transform.position.x, transform.position.y, transform.position.z);
    14.             Rotation = new Vector3(transform.localEulerAngles.x, transform.localEulerAngles.y, transform.localEulerAngles.z);
    15.         }
    16.     }
    17. }
     
  2. Zalosath

    Zalosath

    Joined:
    Sep 13, 2014
    Posts:
    687
    For position and rotation you should make a container class for a Vector3 and a Quaternion (or 2 Vector3's and convert to Quaternion at runtime).

    E.g.
    Code (CSharp):
    1. [System.Serializable]
    2. public class PositionAndRotationContainer
    3. {
    4.     public Vector3 position;
    5.     public Vector3 rotation;
    6.  
    7.     public Quaternion GetRotation()
    8.     {
    9.         return Quaternion.Euler(rotation); // might be correct, didn't check it
    10.     }
    11. }
    12.  
    13. public List<PositionAndRotationContainer> locations = new List<PositionAndRotationContainer>();
     
    Aviation_Simmer and Bunny83 like this.
  3. kruskal21

    kruskal21

    Joined:
    May 17, 2022
    Posts:
    68
    To get the inspector display, you can define a struct that contains both the position and rotation information.

    Code (CSharp):
    1. public struct Location
    2. {
    3.     public Vector3 position;
    4.     public Vector3 rotation;
    5. }
    Then get a list of the gameobjects you want to store the locations for, and then:

    Code (CSharp):
    1. public List<Location> Locations = new();
    2.  
    3. foreach (GameObject go in gameObjects) // gameObjects is a List<GameObject> you create beforehand
    4. {
    5.     Locations.Add(new Location() { postion = go.transform.postion, rotation = go.transform.localEulerAngles });
    6. }
    7.  
     
    Aviation_Simmer likes this.
  4. Aviation_Simmer

    Aviation_Simmer

    Joined:
    Aug 30, 2021
    Posts:
    110
    Thanks! that helped. but I dont get it...? why do i get the position and rotation in the console correctly but not in the script? it always shows 0.0, 0.0, 0.0

    Code (CSharp):
    1. {
    2.     [System.Serializable]
    3.     public class PositionAndRotationContainer
    4.     {
    5.         public string PlayerName;
    6.         public Transform Player;
    7.         public Vector3 Position;
    8.         public Vector3 Rotation;
    9.  
    10.         void FixedUpdate()
    11.         {
    12.             Position = new Vector3(Player.transform.position.x, Player.transform.position.y, Player.transform.position.z);
    13.             Rotation = new Vector3(Player.transform.localEulerAngles.x, Player.transform.localEulerAngles.y, Player.transform.localEulerAngles.z);
    14.             UnityEngine.Debug.Log("Position: " + Position + " | Rotation " + Rotation);
    15.         }    
    16.     }
    17.     public List<PositionAndRotationContainer> locations = new List<PositionAndRotationContainer>();
    18. }
     
  5. kruskal21

    kruskal21

    Joined:
    May 17, 2022
    Posts:
    68
    The idea is that PositionAndRotationContainer is not supposed to inherit from monobehaviour and just be a simple data container. Instead, have another script on each of the gameobjects you are interested in that is responsible for populating the list. There are a number of ways of storing the list, the simplist way is to have the list as a global, static variable inside a static class.
    Code (CSharp):
    1. public static class GameData
    2. {
    3.     public static List<PositionAndRotationContainer> locations = new();
    4. }
    5.  
    6. public class LocationUpdater : MonoBehaviour
    7. {
    8.     private int locationIndex;
    9.  
    10.     private PositionAndRotationContainer GetLocation()
    11.     {
    12.         return new PositionAndRotationContainer { position = transform.position, rotation = transform.localEulerAngles };
    13.     }
    14.  
    15.     private void Start()
    16.     {
    17.         locationIndex = GameData.locations.Count;
    18.         GameData.locations.Add(GetLocation());
    19.     }
    20.  
    21.     private void FixedUpdate()
    22.     {
    23.         GameData.locations[locationIndex] = GetLocation();
    24.     }
    25. }
    26.  
    Note that global static variables can be bad in that they are sometimes hard to debug. You might want to consider something like https://docs.unity3d.com/Manual/class-ScriptableObject.html as an alternative way of storing global data. Feel free to ask if there is anything here you are confused about.