将 Json 字符串转换为给定的派生类型

Convert Json string to given derived type

提问人:xVice1337 提问时间:11/1/2023 最后编辑:xVice1337 更新时间:11/1/2023 访问量:55

问:

我有一个关于 json/序列化的问题。

我正在研究我的引擎的网格化逻辑,我需要将给定的 json 表示转换为给定类的实例,我有需要转换为的类的 Type 对象。

我需要转换的所有类都派生自 LuminosityBehaviour,我不能只转换为 LuminosityBehaviour,因为它们没有来自 json 的字段。

这是我目前得到的: 丝线化:


        private static void SerializeObj(GameObject obj, string path)
        {
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }

            File.WriteAllText(Path.Combine(path, $"{obj.Name}-{obj.GetHashCode()}.json"), JsonConvert.SerializeObject(obj, Formatting.Indented));
        }

去serilization:

        public static GameObject DeserializeFromFolder(string path)
        {
            if (Directory.Exists(path))
            {
                // Deserialize the main GameObject
                string[] mainGameObjectFiles = Directory.GetFiles(path, $"{Path.GetFileName(path)}*.json");
                if (mainGameObjectFiles.Length > 0)
                {
                    string gameObjectFile = mainGameObjectFiles[0];
                    GameObject rootGameObject = JsonConvert.DeserializeObject<GameObject>(File.ReadAllText(gameObjectFile), new JsonSerializerSettings
                    {
                        TypeNameHandling = TypeNameHandling.Auto
                    });
                    return rootGameObject;
                }
            }

            return null;
        }

GameObject 类:

    public class GameObject
    {
        public string Name { get; set; } = "New GameObject";
        public string Tag { get; set; } = string.Empty;
        public bool ActiveAndEnabled { get; set; } = true;
        public int ExecutionOrder = 0;


        //[JsonIgnore]
        public GameObject Parent = null;

        //[JsonIgnore]
        public List<GameObject> Childs = new List<GameObject>();

        //[JsonIgnore]
        public Dictionary<Type, LuminosityBehaviour> components = new Dictionary<Type, LuminosityBehaviour>();
    }

光度行为:

 public class LuminosityBehaviour
    {
        public int ExecutionOrder = 0;
       
        public string Name = string.Empty;

        [JsonIgnore]
        public GameObject GameObject { get; set; }

        [JsonIgnore]
        public TransformComponent Transform
        {
            get
            {
                return GameObject.Transform;
            }
        }
        [JsonIgnore]
        public List<GameObject> Children { get; set; }
        
    }

最后是行为,所以更容易理解我需要做什么。 我需要一个带有 JSON 中的 corect 值的 cameracomponent 实例。

namespace Luminosity3D.Builtin
{
    public class Camera : LuminosityBehaviour
    {
        public Quaternion Rotation = Quaternion.Identity; // Store camera's rotation separately
        public Vector3 Position = Vector3.Zero;
        public Matrix4x4 ViewMatrix { get; private set; }
        public Matrix4x4 ProjectionMatrix { get; private set; }
        public Vector3 Forward
        {
            get
            {
                // Calculate the forward vector based on the camera's orientation
                return -Vector3.Transform(Vector3.UnitZ, Rotation);
            }
        }
        public Vector3 Right
        {
            get
            {
                Vector3 forward = -Vector3.Transform(Vector3.UnitZ, Rotation);
                Vector3 up = Vector3.Transform(Vector3.UnitY, Rotation);
                return Vector3.Cross(up, forward);
            }
        }

        public Vector3 Up
        {
            get
            {
                return Vector3.Transform(Vector3.UnitY, Rotation);
            }
        }


      

        public float FieldOfView { get; set; }
        public float AspectRatio { get; set; }
        public float NearClip { get; set; }
        public float FarClip { get; set; }

        public override void Awake()
        {

            FieldOfView = 90;
            AspectRatio = 1920f / 1080f;
            NearClip = .1f;
            FarClip = 5000f;

            SetActive();
            UpdateProjectionMatrix();
            UpdateViewMatrix();
        }

        public void UpdateProjectionMatrix()
        {
            ProjectionMatrix = Matrix4x4.CreatePerspectiveFieldOfView(
                LMath.ToRadians(FieldOfView), // Use System.Numerics MathHelper
                AspectRatio,
                NearClip,
                FarClip
            );
        }

        public void UpdateViewMatrix()
        {
            Matrix4x4 rotationMatrix = Matrix4x4.CreateFromQuaternion(Rotation);

            // Calculate the forward, right, and up vectors using the rotation matrix



            // Calculate the target position using the camera's Position and Forward vector
            Vector3 target = Position + Forward;

            // Create the view matrix using the calculated vectors
            ViewMatrix = Matrix4x4.CreateLookAt(Position, target, Up);
        }

        public void SetActive()
        {
            Engine.SceneManager.ActiveScene.activeCam = this;
        }

        public void SetPosition(Vector3 position)
        {
            Position = position;
            UpdateViewMatrix();
        }

        public void Move(Vector3 direction, float speed)
        {
            //Vector3 worldDirection = Vector3.Transform(direction, Rotation); // Use camera's rotation
            Position += direction * speed * Time.deltaTime;
            UpdateViewMatrix();
        }

        public void RotateCamera(Vector3 orientation, float angle)
        {
            // Create a quaternion representing the rotation
            Quaternion rotation = Quaternion.CreateFromAxisAngle(orientation, angle);

            // Apply the rotation to the current camera rotation
            Quaternion newRotation = rotation * Rotation;

            newRotation = Quaternion.Normalize(newRotation);

            // Extract the pitch and yaw rotations from the new rotation
            Vector3 forwardVector = Vector3.Transform(Vector3.UnitZ, newRotation);
            float pitch = (float)Math.Asin(-forwardVector.Y);
            float yaw = (float)Math.Atan2(forwardVector.X, forwardVector.Z);

            // Clamp the pitch rotation to stay within a desired range (e.g., -80 to 80 degrees)
            float maxPitch = LMath.ToRadians(80); // Maximum pitch angle in radians
            pitch = LMath.Clamp(pitch, -maxPitch, maxPitch);

            // Reconstruct the new quaternion based on the clamped pitch and original yaw
            Quaternion clampedRotation = Quaternion.CreateFromYawPitchRoll(yaw, pitch, 0);

            // Update the camera's rotation
            Rotation = clampedRotation;
            // Update the view matrix
            UpdateViewMatrix();
        }

        public void LookAt(Vector3 target)
        {
            Vector3 direction = Vector3.Normalize(target - Position);
            Rotation = Quaternion.CreateFromRotationMatrix(Matrix4x4.CreateLookAt(Vector3.Zero, direction, Vector3.UnitY));
            UpdateViewMatrix();
        }
    }
}

Json格式:

{
  "ExecutionOrder": 0,
  "Parent": null,
  "Childs": [],
  "components": {
    "Luminosity3D.Builtin.Camera, Luminosity3D, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null": {
      "Rotation": {
        "X": 0.23763347,
        "Y": 0.68091494,
        "Z": -0.250537,
        "W": 0.6458455,
        "IsIdentity": false
      },
      "Position": {
        "X": -7.1340866,
        "Y": 6.405525,
        "Z": 7.3761296
      },
      "ExecutionOrder": 0,
      "Name": "",
      "ViewMatrix": {
        "M11": -0.05282802,
        "M12": 0.6472329,
        "M13": 0.7604597,
        "M14": 0.0,
        "M21": 4.8428774E-08,
        "M22": 0.7615231,
        "M23": -0.64813787,
        "M24": 0.0,
        "M31": -0.9986037,
        "M32": -0.034239803,
        "M33": -0.040229786,
        "M34": 0.0,
        "M41": 6.9889503,
        "M42": -0.0079827905,
        "M43": 9.8735895,
        "M44": 1.0,
        "IsIdentity": false,
        "Translation": {
          "X": 6.9889503,
          "Y": -0.0079827905,
          "Z": 9.8735895
        }
      },
      "ProjectionMatrix": {
        "M11": 0.5625,
        "M12": 0.0,
        "M13": 0.0,
        "M14": 0.0,
        "M21": 0.0,
        "M22": 1.0,
        "M23": 0.0,
        "M24": 0.0,
        "M31": 0.0,
        "M32": 0.0,
        "M33": -1.00002,
        "M34": -1.0,
        "M41": 0.0,
        "M42": 0.0,
        "M43": -0.100002006,
        "M44": 0.0,
        "IsIdentity": false,
        "Translation": {
          "X": 0.0,
          "Y": 0.0,
          "Z": -0.100002006
        }
      },
      "Forward": {
        "X": -0.7604597,
        "Y": 0.6481378,
        "Z": 0.04022968
      },
      "Right": {
        "X": 0.052827936,
        "Y": 2.0489097E-08,
        "Z": 0.9986037
      },
      "Up": {
        "X": 0.6472328,
        "Y": 0.76152307,
        "Z": -0.0342398
      },
      "FieldOfView": 90.0,
      "AspectRatio": 1.7777778,
      "NearClip": 0.1,
      "FarClip": 5000.0,
      "dataField": {}
    },
    "Luminosity3D.Builtin.CameraController, Luminosity3D, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null": {
      "ExecutionOrder": 0,
      "Name": "",
      "dataField": {}
    }
  },
  "Name": "New Camera",
  "Tag": "",
  "ActiveAndEnabled": true
}
C# JSON .NET 序列化

评论

1赞 Alexei Levenkov 11/1/2023
您能否将问题编辑为仅与问题相关的代码(即所有与文件相关的东西似乎都不相关),并重新设计您的示例示例 JSON,使其较小并专注于问题?(考虑重新阅读有关在删除代码块/JSON 时发布代码的最小可重现示例指南)

答: 暂无答案