Quaternion serialization in structs

Issue #155 resolved
Former user created an issue

If I create something like this:

public class NetworkSharedStore : SerializedMonoBehaviour

{

public struct zoomLevel

{

    public float level;

    public float startLevel;

    public float endLevel;

    public Vector3 cameraRotationEuler;

}

Odin do not apply changes when I try to change quaternion field. After click enter or change focus, a quaternion always become zeros.

Comments (4)

  1. mSkull001
    • changed status to open

    Thanks for reporting this. We're taking another look at our quaternion fields, to see if we can't get them working better.

    The issue is due to the conversion between eulers, angle axis, or even the raw drawer, back into Unity's quaternion, and then converting back and forth again the next frame. If we were to convert from say, an euler rotation of -90, 0, 0, to quaternions and then back again, we might get something like 270, 0, 0 instead. Which is clearly not ideal, which is why we currently have a few tricks to trick to help alleviate this , but clearly it's not enough.

    We're sorry for the inconvenience, and we'll be sure to have a fix ready as soon as possible.

  2. Кирилл Титов

    Yes, I know about angle conversion from 0 to 360. Something other happened there. No matter what i enter to quaternion it always became zeros, but... I tried few times and I cannot reproduce it. I have changed a lot of things and the problem just disappeared. I will write a comment here if I meet it again. Probably the reason of it was big size of the scene and the problem with saving it. Git also could do something with my project. I noticed that send you not right script that cause a problem. This script also miss struct array in build. It was empty in app after build. Right now it is also gone and everything is working fine

    using UnityEngine;
    using UnityEngine.Networking;
    using System.Collections;
    using System;
    using Sirenix.OdinInspector;
    using System.Collections.Generic;
    
    
    public class NetworkSharedStore : SerializedMonoBehaviour
    {
    
    public struct zoomLevel
    {
        public float level;
        public float startLevel;
        public float endLevel;
        public Quaternion cameraRotation;
    }
    
        private static NetworkSharedStore s_instance;
    
        private NetworkSharedStore() { }
    
        public static NetworkSharedStore Instance
        {
            get
            {
                return s_instance;
            }
        }
    
        private void Awake()
        {
            if (s_instance == null)
            {
                s_instance = this;
            }
        }
    
        public event Action<float> zoomChanged;
        public event Action<Vector3> positionChanged;
    
        public Vector4 startBoundsOfView;
        public Vector4 boundsOfView;
    
        [SerializeField]
        private float _currentZoom;
        public float currentZoom
        {
            get
            {
                return _currentZoom;
            }
            set
            {         
                if(_currentZoom!=value && zoomChanged!=null)
                {
                    zoomChanged.Invoke(value);        
                }
                if (positionChanged != null)
                {
                    positionChanged.Invoke(_currentPosition);
                }
                _currentZoom = value;
            }
    
        }
        [SerializeField]
        private Vector3 _currentPosition;
        public Vector3 currentPosition
        {
            get
            {
                return _currentPosition;
            }
            set
            {
                if (_currentPosition != value && positionChanged != null)
                {
                    positionChanged.Invoke(value);
                }
                _currentPosition = value;
            }
        }
    
        public float maxZoom;
        public float minZoom;
    
    
        public zoomLevel[] zoomLevels = new zoomLevel[3];
    }
    
  3. mSkull001

    We've implemented some improvements to the Quaternion drawers. They would, particularly when using the raw draw mode, snap values to 0, or otherwise jump around when editing them. This is no longer the case. Btw, you can change the draw mode of Quaternions by right clicking, or in the preferences window.

    As for the missing array data, we'll have to investigate that further. In your example, It should be serialized by Odin, since the struct is not marked with the [Serializable] attribute, and it should be there in the build. Which version of Unity are you using, and which platform are you building for?

    For now, I'll recommend you put [Serializable] on your zoomLevel struct. That'll make Unity serialize it, instead of Odin.

    Edit: We've tested your script in a new project, with Unity version 5.3, and with Odin version 1.0.4.2, building to PC. The serialization is working correctly there.

  4. Log in to comment