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
to this
{
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>();
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 });
}
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.