0
\$\begingroup\$
public class TransformInfo
    {
        public string sceneName;
        public string name;
        public Transform parent;
        public Vector3 pos;
        public Quaternion rot;
        public Vector3 scale;
    }

Then the method:

public static TransformInfo[]  LoadTransformInfo()
    {
        string jsonTransform = File.ReadAllText(@"d:\json\json.txt");
        if (jsonTransform == null)
        {
            return null;
        }

        TransformInfo[] savedTransforms = JsonHelper.FromJson<TransformInfo>(jsonTransform);

        return savedTransforms;
    }

The return is:

Return info

But then when using it:

var test = TransformSaver.LoadTransformInfo();

Each item in the array contain the the TransfomInfo but instead I want it to return a Transform with already the info.

So I can do for example:

Transform test1 = test[0];

Instead make a loop and assign each property from the Test to the new Transform test1.

\$\endgroup\$
8
  • 1
    \$\begingroup\$ You could do Transform test1 = test[0].parent.GetChild(childIndex); but the problem would be the index, maybe you could put that the index data in your class. Or you could also do something like test[0].parent.Find(test[0].name);, which is Transform.Find: docs.unity3d.com/ScriptReference/Transform.Find.html \$\endgroup\$ Sep 4, 2018 at 18:00
  • 1
    \$\begingroup\$ Although, other than the scene name, I don't see why creating a class that has Transform's data that is already in the transform itself, why not making a wrapper struct/class that just stores the scene name and the transform? \$\endgroup\$ Sep 4, 2018 at 18:03
  • \$\begingroup\$ @LinkWindcrafter Can you show me an example how to do the wrapper struct/class that just stores the scene name and the transform please ? \$\endgroup\$ Sep 4, 2018 at 18:17
  • \$\begingroup\$ Sure, I already made an answer. \$\endgroup\$ Sep 4, 2018 at 18:31
  • \$\begingroup\$ @LinkWindcrafter "I don't see why creating a class that has Transform's data that is already in the transform itself" It looks like they may be attempting to serialize this information to a text file, and deserialize it later - something they can't do with Transform components themselves in quite the same way. \$\endgroup\$
    – DMGregory
    Sep 4, 2018 at 18:53

1 Answer 1

1
\$\begingroup\$

As I said in the comments, I personally see no reason why you are making a class that stores Transform's data, like parent, rotation, position and scale, that a Transform already has by itself. What a transform does not have by itself is the scene name. So, the idea of having a wrapper class is okay, but there is redundancy of information, in my opinion. What I would do is a wrapper struct or class, just containing a reference to a transform, and a scene name. Like this:

public struct SceneTransformInfo
{
    public string sceneName;
    public Transform transform;
}

So to access all the data you declared in your class would be accessed like this:

SceneTransformData data;

Scene Name = data.sceneName;
Name = data.transform.name;
Parent = data.transform.parent;
Position = data.transform.position;
Rotation = data.transform.rotation;
Scale = data.transform.localScale;

If you are lazy, like me, and you would like for the user to be easier to access the data, then make functions or C#'s properties. Like this:

public struct SceneTransformInfo
{
    public string sceneName;
    public Transform transform;

    public string name { get { return transform.name; } }

    public string parent { get { return transform.parent; } }

    public string position { get { return transform.position; } }

    public string rotation { get { return transform.rotation; } }

    public string scale { get { return transform.localScale; } }
}

So, at the end, the way of obtaining a Transform of an array of this struct/class, is just by getting its transform property.

NOTE: Just be careful though, if you intend to have this data to persist between scenes, you may lose the Transform reference if that Transform does not persist, for that, you would need to make a custom data type to store the transform's information, this time similarly to what you did. But instead your parent reference should also be of the type of the custom data, and not Transform (due to the aforementioned problem). I have made myself some time ago a data type for that, in case you are interested on it.

ABOUT THE DATA TYPE I WAS PROPOSING:

I had a problem like yours a while ago, where I wanted to store Transform's Data, without having to rely on a Transform's instance, so I did a struct like the one I wrote. But my previous structure didn't have a reference to the parent's transform data. So this is my proposal, have it a class, and have inside the class another variable of the same type, referring to its father. Now, here I am using implicit operators, just syntactic sugar to avoid writing the new keyword (it is implicitly done anyway). Here on this class, I also made an IEnumerator to iterate all the parent's parent recursively in a foreach, but you can omit that function, and the class would be good to go for you, if you liked that idea, you could add the implementation for the children.

Of course, I didn't put the scene name's string on that data type, since I wanted to separate the logic. So it is up to you if you want to make a struct/class to store both a string (scene's name) and the TransformData, or have the string in this same class, that is more up to your design decisions.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class TransformData
{
    [SerializeField] private string _name;              /// <summary>Transform's Name.</summary>
    [SerializeField] private TransformData _parent;     /// <summary>Transform's Parent.</summary>
    [SerializeField] private Vector3 _position;         /// <summary>Transform's Position.</summary>
    [SerializeField] private Quaternion _rotation;      /// <summary>Transform's Rotation.</summary>
    [SerializeField] private Vector3 _eulerRotation;    /// <summary>Transfrom's Euler Rotation.</summary>
    [SerializeField] private Vector3 _scale;            /// <summary>Transform's Scale.</summary>

    /// <summary>Gets and Sets name property.</summary>
    public string name
    {
        get { return _name; }
        set { _name = value; }
    }

    /// <summary>Gets and Sets parent property.</summary>
    public TransformData parent
    {
        get { return _parent; }
        set { _parent = value; }
    }

    /// <summary>Gets and Sets position property.</summary>
    public Vector3 position
    {
        get { return _position; }
        set { _position = value; }
    }

    /// <summary>Gets and Sets rotation property.</summary>
    public Quaternion rotation
    {
        get { return _rotation; }
        set
        {
            _rotation = value;
            _eulerRotation = rotation.eulerAngles;
        }
    }

    /// <summary>Gets and Sets eulerRotation property.</summary>
    public Vector3 eulerRotation
    {
        get { return _eulerRotation; }
        set
        {
            _eulerRotation = value;
            _rotation = Quaternion.Euler(_eulerRotation);
        }
    }

    /// <summary>Gets and Sets scale property.</summary>
    public Vector3 scale
    {
        get { return _scale; }
        set { _scale = value; }
    }

    /// <summary>Transform to TransformData's implicit operator.</summary>
    public static implicit operator TransformData(Transform _transform) { return new TransformData(_transform); }

    /// <summary>TransformData's Constructor.</summary>
    /// <param name="_transform">Transform's Data.</param>
    public TransformData(Transform _transform)
    {
        name = _transform.name;
        parent = _transform.parent;
        position = _transform.position;
        rotation = _transform.rotation;
        scale = _transform.localScale;
    }

    /// <summary>Iterates through all parents recursively, starting from this Transform Data's parent.</summary>
    public IEnumerator<TransformData> GetParents()
    {
        TransformData currrentParent = parent;

        while(currrentParent != null)
        {
            yield return currrentParent;
            currrentParent = currrentParent.parent;
        }
    }
}

Hope it helps.

\$\endgroup\$
2
  • \$\begingroup\$ Hi, Sorry for the late comment. Could you show me also how to make the part in the NOTE ? And in overall how to use it ? If I'm adding for example the public struct SceneTransformInfo code to the class I'm getting errors since parent and position and rotation of Transform are not strings. \$\endgroup\$ Sep 5, 2018 at 18:32
  • 1
    \$\begingroup\$ Sure, no problem, I updated my answer. Let me know if you have more questions. \$\endgroup\$ Sep 5, 2018 at 21:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .