/// --------------------------------------------- /// Ultimate Character Controller /// Copyright (c) Opsive. All Rights Reserved. /// https://www.opsive.com /// --------------------------------------------- namespace Opsive.UltimateCharacterController.StateSystem { using Opsive.Shared.Utility; using System; using System.Collections.Generic; using UnityEngine; /// /// Allows the Preset component to serialized the property value. /// public class PersistablePreset : Preset { [Tooltip("The serialized properties.")] [SerializeField] protected Serialization m_Data; public Serialization Data { get { return m_Data; } set { m_Data = value; } } /// /// Creates a persistable preset based off of the specified component. /// /// The object to retrieve the property values of. /// The created preset. Null if no properties have been found to create the preset with. public static PersistablePreset CreatePreset(object obj) { return CreatePreset(obj, MemberVisibility.None); } /// /// Creates a persistable preset based off of the specified component and visibility. /// /// The object to retrieve the property values of. /// Specifies the visibility of the field/properties that should be retrieved. /// The created preset. Null if no properties have been found to create the preset with. public static PersistablePreset CreatePreset(object obj, MemberVisibility visibility) { var data = new Serialization(); data.Serialize(obj, false, visibility); var preset = CreateInstance(); preset.Data = data; return preset; } /// /// Initializes the preset with the specified visiblity. The preset must be initialized before the preset values are applied so the delegates can be created. /// /// The object to map the delegates to. /// Specifies the visibility of the field/properties that should be retrieved. public override void Initialize(object obj, MemberVisibility visibility) { m_Delegates = new BaseDelegate[m_Data.ValueHashes.Length]; var valuePositionMap = new Dictionary(m_Data.ValueHashes.Length); for (int i = 0; i < m_Data.ValueHashes.Length; ++i) { valuePositionMap.Add(m_Data.ValueHashes[i], i); } var valueCount = 0; var properties = Serialization.GetSerializedProperties(obj.GetType(), visibility); for (int i = 0; i < properties.Length; ++i) { var hash = Serialization.StringHash(properties[i].PropertyType.FullName) + Serialization.StringHash(properties[i].Name); int position; if (!valuePositionMap.TryGetValue(hash, out position)) { continue; } // Create a generic delegate based on the property type. var genericDelegateType = typeof(GenericDelegate<>).MakeGenericType(properties[i].PropertyType); m_Delegates[valueCount] = Activator.CreateInstance(genericDelegateType) as BaseDelegate; // Initialize the delegate. if (m_Delegates[valueCount] != null) { m_Delegates[valueCount].Initialize(obj, properties[i], valuePositionMap, m_Data, visibility); } else { Debug.LogWarning("Warning: Unable to create preset of type " + properties[i].PropertyType); } valueCount++; } // The delegate length may not match if a property has been added but no longer exists. if (m_Delegates.Length != valueCount) { Array.Resize(ref m_Delegates, valueCount); } } } }