Easy way to write and read some Transform to a text file in Unity3d?

后端 未结 2 1022
忘了有多久
忘了有多久 2021-01-22 21:53

This is strictly in Unity3D, I have an array of 100 Transform,

I want to write those to a file on the PC desktop, and later read them.

Consider ...<

相关标签:
2条回答
  • 2021-01-22 22:34

    You can use Json and the Playerprefs to save the Transform. This is a TransformSaver extension class that can do that:

    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;
    
    public static class TransformSaver
    {
    
        [System.Serializable]
        public class TransformInfo
        {
            public Vector3 pos;
            public Quaternion rot;
            public Vector3 scale;
        }
    
        //Save Transform
        public static void SaveTransform(this Transform trans, Transform[] tranformToSave)
        {
            TransformInfo[] trnfrm = new TransformInfo[tranformToSave.Length];
            for (int i = 0; i < trnfrm.Length; i++)
            {
                trnfrm[i] = new TransformInfo();
                trnfrm[i].pos = tranformToSave[i].position;
                trnfrm[i].rot = tranformToSave[i].rotation;
                trnfrm[i].scale = tranformToSave[i].localScale;
            }
    
            string jsonTransform = JsonHelper.ToJson(trnfrm, true);
            PlayerPrefs.SetString("transform", jsonTransform);
        }
    
        //Load Transform
        public static Transform[] LoadTransform(this Transform trans)
        {
            string jsonTransform = PlayerPrefs.GetString("transform");
            if (jsonTransform == null)
            {
                return null;
            }
            //Debug.Log("Loaded: " + jsonTransform);
    
            TransformInfo[] savedTransforms = JsonHelper.FromJson<TransformInfo>(jsonTransform);
            GameObject[] gameObjects = new GameObject[savedTransforms.Length];
            Transform[] loadedTransforms = new Transform[savedTransforms.Length];
    
            for (int i = 0; i < gameObjects.Length; i++)
            {
                gameObjects[i] = new GameObject("_");
                gameObjects[i].hideFlags = HideFlags.HideAndDontSave;
                loadedTransforms[i] = gameObjects[i].transform;
                loadedTransforms[i].position = savedTransforms[i].pos;
                loadedTransforms[i].rotation = savedTransforms[i].rot;
                loadedTransforms[i].localScale = savedTransforms[i].scale;
            }
            return loadedTransforms;
        }
    
        public static void CopyTransform(this Transform trans, Transform source, Transform target, bool createNewInstance = false)
        {
            if (source == null)
            {
                return;
            }
    
            if (target == null || createNewInstance)
            {
                GameObject obj = new GameObject("_");
                obj.hideFlags = HideFlags.HideAndDontSave;
                target = obj.transform;
            }
    
            target.position = source.position;
            target.rotation = source.rotation;
            target.localScale = source.localScale;
        }
    
        public static void CopyTransform(this Transform trans, Transform[] source, Transform[] target, bool createNewInstance = false)
        {
            if (source == null || source.Length <= 0)
            {
                return;
            }
    
            for (int i = 0; i < target.Length; i++)
            {
                CopyTransform(null, source[i], target[i], createNewInstance);
                if (i >= target.Length - 1)
                {
                    break;
                }
            }
        }
    }
    

    JsonHelper script for converting arrays to json and vice versa:

    using UnityEngine;
    using System.Collections;
    using System;
    
    public class JsonHelper
    {
    
        public static T[] FromJson<T>(string json)
        {
            Wrapper<T> wrapper = UnityEngine.JsonUtility.FromJson<Wrapper<T>>(json);
            return wrapper.Items;
        }
    
        public static string ToJson<T>(T[] array, bool prettyPrint)
        {
            Wrapper<T> wrapper = new Wrapper<T>();
            wrapper.Items = array;
            return UnityEngine.JsonUtility.ToJson(wrapper, prettyPrint);
        }
    
        [Serializable]
        private class Wrapper<T>
        {
            public T[] Items;
        }
    }
    

    Usage:

    using UnityEngine;
    using System.Collections;
    
    public class TransformTest : MonoBehaviour
    {
    
        public Transform[] objectToSave;
    
        // Use this for initialization
        void Start()
        {
            //Save Transform
            transform.SaveTransform(objectToSave);
    
            //Load Transform
            Transform[] loadedTransform = transform.LoadTransform();
            transform.CopyTransform(loadedTransform, objectToSave);
        }
    }
    

    It's not perfect and can be improved. Improvement includes making the LoadTransform function take transform array as parameter instead of returning an array.

    0 讨论(0)
  • 2021-01-22 22:45

    You can use Binary Serialization.

    Create following structs:

    [Serializable]
    public struct SerializebleVector
    {
        public float x, y, z, w;
    
        public SerializebleVector(float x, float y, float z, float w = 0f)
        {
            this.x = x;
            this.y = y;
            this.z = z;
            this.w = w;
        }
    
        public static explicit operator SerializebleVector(Quaternion a)
        {
            return new SerializebleVector(a.x, a.y, a.z, a.w);
        }
    
        public static implicit operator SerializebleVector(Vector3 a)
        {
            return new SerializebleVector(a.x, a.y, a.z);
        }
    
    }
    
    [Serializable]
    public struct SerializebleTransform
    {
        SerializebleVector position;
        SerializebleVector rotation;
        SerializebleVector scale;
    
        public SerializebleTransform(Transform tr)
        {
            position = tr.position;
            rotation = (SerializebleVector) tr.rotation;
            scale = tr.lossyScale;
        }
    
    
        public static implicit operator SerializebleTransform(Transform tr)
        {
            return new SerializebleTransform(tr);
        }
    }
    

    Save method:

    public static void Save(Transform[] ts )
    {
        var data = new List<SerializebleTransform>();
    
        foreach (var t in ts)
        {
            data.Add(t);
        }
    
        BinaryFormatter bf = new BinaryFormatter();
        using (FileStream file = File.Create (Application.persistentDataPath + "/savedTransforms.dat"))
        {
            bf.Serialize(file, data);
        }
    }
    

    Load Method:

    public static void Load(out List<SerializebleTransform> ts) 
    {
        if(File.Exists(Application.persistentDataPath + "/savedTransforms.dat"))
        {
            BinaryFormatter bf = new BinaryFormatter();
            using (FileStream file = File.Open(Application.persistentDataPath + "/savedTransforms.dat", FileMode.Open))
            {
                var data = (List<SerializebleTransform>)bf.Deserialize(file);
                return data;
            }
        }
        else
            ts = null;
    }
    

    PS: As far as I know you can't create Transform without GameObject, so read data from SerializebleTransform into Transform kind of manually.

    0 讨论(0)
提交回复
热议问题