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

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
8400168--1109040--upload_2022-8-29_21-39-10.png

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

{
    public Vector3 Position;
    public Vector3 Rotation;

    public List<float> Locations = new List<float>();

    void Update()
    {


        foreach (float loc in Locations)
        {
            Position = new Vector3(transform.position.x, transform.position.y, transform.position.z);
            Rotation = new Vector3(transform.localEulerAngles.x, transform.localEulerAngles.y, transform.localEulerAngles.z);
        }
    }
}

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.

[System.Serializable]
public class PositionAndRotationContainer
{
    public Vector3 position;
    public Vector3 rotation;

    public Quaternion GetRotation()
    {
        return Quaternion.Euler(rotation); // might be correct, didn't check it
    }
}

public List<PositionAndRotationContainer> locations = new List<PositionAndRotationContainer>();
2 Likes

To get the inspector display, you can define a struct that contains both the position and rotation information.

public struct Location
{
    public Vector3 position;
    public Vector3 rotation;
}

Then get a list of the gameobjects you want to store the locations for, and then:

public List<Location> Locations = new();

foreach (GameObject go in gameObjects) // gameObjects is a List<GameObject> you create beforehand
{
    Locations.Add(new Location() { postion = go.transform.postion, rotation = go.transform.localEulerAngles }); 
}
1 Like

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

{
    [System.Serializable]
    public class PositionAndRotationContainer
    {
        public string PlayerName;
        public Transform Player;
        public Vector3 Position;
        public Vector3 Rotation;

        void FixedUpdate()
        {
            Position = new Vector3(Player.transform.position.x, Player.transform.position.y, Player.transform.position.z);
            Rotation = new Vector3(Player.transform.localEulerAngles.x, Player.transform.localEulerAngles.y, Player.transform.localEulerAngles.z);
            UnityEngine.Debug.Log("Position: " + Position + " | Rotation " + Rotation);
        }    
    }
    public List<PositionAndRotationContainer> locations = new List<PositionAndRotationContainer>();
}

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.

public static class GameData
{
    public static List<PositionAndRotationContainer> locations = new();
}

public class LocationUpdater : MonoBehaviour
{
    private int locationIndex;

    private PositionAndRotationContainer GetLocation()
    {
        return new PositionAndRotationContainer { position = transform.position, rotation = transform.localEulerAngles };
    }

    private void Start()
    {
        locationIndex = GameData.locations.Count;
        GameData.locations.Add(GetLocation());
    }

    private void FixedUpdate()
    {
        GameData.locations[locationIndex] = GetLocation();
    }
}

Note that global static variables can be bad in that they are sometimes hard to debug. You might want to consider something like Unity - Manual: ScriptableObject as an alternative way of storing global data. Feel free to ask if there is anything here you are confused about.