Design Pattern 3: Unity Private Variable Serialisation

Private Variables in UnityEngine.Object (MonoBehaviour / ScriptableObject) are not serialised in initial scene (=efficiency). In addition they persist their values in assembly reload. This allows us to retain both a minimum file size scene AND assemly reload capacity.

namespace Disanity.Test
{
    using UnityEngine;

    /// Conclusion: Private variables are not saved in initial scene but their values persist in Assembly Reload = Best of both worlds.
    public class TestPrivateSerialisation : MonoBehaviour
    {
        private int a;

        void Awake()
        {
            a = Util.RandomInt(312, 4145);
        }

        private void OnEnable()
        {
            Debug.Log("Generated Value "+a);
        }
    }
}

By running the following code we get :

Output: 2942
Output after reload: 2942

If you had used [NonSerialized] attribute, their value would have been forgotten and since awake isnt called again after assembly reload. You would get :

Output after reload: 0

This opportunity allows to combine both approaches, retaining both of their benefits.
a) From Design Pattern 1: Zero Initial File Size Scene. YES THIS WORKS !!!
b) From Design Pattern 2:
Custom Classes persist their values after Assembly Reload (at no cost !!!).

What Inspector Shows What Unity Serializes

With Debug Inspector activated, you can even inspect private fields (but not edit them).

DebugInspector.png

What more do you need ? Unity gives you all the tools needed to handle serialisation.

namespace Disanity.Test
{
    using System;
    using UnityEngine;

    /// Requirements:
    /// 1) Each Type of Field, Known ahead of time.
    public class DesignPatternCorrectSerialization : MonoBehaviour
    {
        public float Speed;
        public bool IgnoreForces;
        private cMovementDirection Move;         //private allows them to survive assembly reload
        private cMoveConstantVelocity Velocity;  //but they are not stored in initial scene.

        private void Awake()
        {
            Move = new cMovementDirection(){Transform = transform};
            Velocity = new cMoveConstantVelocity(){Rigid = GetComponent<Rigidbody>(), IgnoreForces=IgnoreForces};
        }

        private void FixedUpdate()
        {
            var direction = Move.Direction() * Speed;
            //if (direction.magnitude > 0) Debug.Log("Move Direction: " + direction);
            Velocity.Move(direction);
        }
    }

    [Serializable]
    public class cMovementDirection
    {
        public Transform Transform;

        public Vector3 Direction()
        {
            //read movement input
            float h = Input.GetAxis("Horizontal");
            float v = Input.GetAxis("Vertical");

            var movementDirection = v * Transform.forward + h * Transform.right;
            Util.NormaliseIfAboveOne(ref movementDirection);
            return movementDirection;
        }
    }

    [Serializable]
    public class cMoveConstantVelocity
    {
        public Rigidbody Rigid;
        public bool IgnoreForces;

        /// Used to track changes to current velocity
        private Vector3 _oldVelocity;

        public void Move(Vector3 direction)
        {
            if (Rigid.isKinematic)
            {
                Rigid.MovePosition(Rigid.position + direction);
            }
            else
            {
                if (IgnoreForces)
                {
                    Rigid.velocity = direction;
                }
                else
                {
                    var newSpeed = Rigid.velocity - _oldVelocity;
                    Rigid.velocity = newSpeed + direction;
                    _oldVelocity = direction;
                }
            }
        }
    }
}
Advertisements

One thought on “Design Pattern 3: Unity Private Variable Serialisation

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s