projectEli/Assets/NeoFPS/Core/MotionGraphs/MotionGraphContainer.cs
2022-11-06 20:28:33 -05:00

661 lines
21 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using NeoFPS.CharacterMotion.Parameters;
using NeoFPS.CharacterMotion.MotionData;
using NeoSaveGames.Serialization;
namespace NeoFPS.CharacterMotion
{
public class MotionGraphContainer : ScriptableObject, IMotionGraphElement, INeoSerializableObject
{
[SerializeField] private List<MotionGraphParameter> m_Parameters = new List<MotionGraphParameter>();
[SerializeField] private List<MotionGraphDataBase> m_Data = new List<MotionGraphDataBase>();
[SerializeField] private MotionGraph m_RootNode = null;
private Dictionary<int, FloatParameter> m_FloatProperties = new Dictionary<int, FloatParameter>();
private Dictionary<int, IntParameter> m_IntProperties = new Dictionary<int, IntParameter>();
private Dictionary<int, TriggerParameter> m_Triggers = new Dictionary<int, TriggerParameter>();
private Dictionary<int, SwitchParameter> m_SwitchProperties = new Dictionary<int, SwitchParameter>();
private Dictionary<int, TransformParameter> m_TransformProperties = new Dictionary<int, TransformParameter>();
private Dictionary<int, VectorParameter> m_VectorProperties = new Dictionary<int, VectorParameter>();
private Dictionary<int, EventParameter> m_EventProperties = new Dictionary<int, EventParameter>();
private TriggerParameter[] m_TriggerArray = null;
private static MotionGraphCloner s_Cloner = new MotionGraphCloner();
private IMotionController m_Controller = null;
#if UNITY_EDITOR
public void OnValidate()
{
for (int i = m_Parameters.Count; i > 0; --i)
{
if (m_Parameters[i - 1] == null)
m_Parameters.RemoveAt(i - 1);
}
for (int i = m_Data.Count; i > 0; --i)
{
if (m_Data[i - 1] == null)
m_Data.RemoveAt(i - 1);
}
// Set hide flags
foreach (var p in m_Parameters)
p.hideFlags |= HideFlags.HideInHierarchy;
foreach (var d in m_Data)
d.hideFlags |= HideFlags.HideInHierarchy;
}
#endif
public MotionGraph rootNode
{
get { return m_RootNode; }
}
public MotionGraphContainer DeepCopy()
{
var clone = s_Cloner.CloneGraph(this);
s_Cloner.Clear();
return clone;
}
public void CheckReferences(IMotionGraphMap map)
{
m_RootNode = map.Swap(m_RootNode);
for (int i = 0; i < m_Parameters.Count; ++i)
m_Parameters[i] = map.Swap(m_Parameters[i]);
for (int i = 0; i < m_Data.Count; ++i)
m_Data[i] = map.Swap(m_Data[i]);
}
public void Initialise(IMotionController c)
{
m_Controller = c;
// Scan properties to fill dictionaries
foreach (MotionGraphParameter parameter in m_Parameters)
{
var trigger = parameter as TriggerParameter;
if (trigger != null)
{
m_Triggers.Add(Animator.StringToHash(trigger.name), trigger);
continue;
}
var intP = parameter as IntParameter;
if (intP != null)
{
m_IntProperties.Add(Animator.StringToHash(intP.name), intP);
continue;
}
var floatP = parameter as FloatParameter;
if (floatP != null)
{
m_FloatProperties.Add(Animator.StringToHash(floatP.name), floatP);
continue;
}
var transformP = parameter as TransformParameter;
if (transformP != null)
{
m_TransformProperties.Add(Animator.StringToHash(transformP.name), transformP);
continue;
}
var switchP = parameter as SwitchParameter;
if (switchP != null)
{
m_SwitchProperties.Add(Animator.StringToHash(switchP.name), switchP);
continue;
}
var vectorP = parameter as VectorParameter;
if (vectorP != null)
{
m_VectorProperties.Add(Animator.StringToHash(vectorP.name), vectorP);
continue;
}
var eventP = parameter as EventParameter;
if (eventP != null)
{
m_EventProperties.Add(Animator.StringToHash(eventP.name), eventP);
}
}
// Store trigger array (used for resetting)
m_TriggerArray = new TriggerParameter[m_Triggers.Count];
int i = 0;
foreach (var tp in m_Triggers.Values)
m_TriggerArray[i++] = tp;
rootNode.Initialise(c);
}
public MotionGraphState GetStateFromKey(int key)
{
return m_RootNode.GetStateFromKey(key);
}
public void SetTrigger(int hash)
{
TriggerParameter property = null;
if (m_Triggers.TryGetValue(hash, out property))
property.Trigger();
}
public void SetTrigger(string propertyName)
{
SetTrigger(Animator.StringToHash(propertyName));
}
public TriggerParameter GetTriggerProperty(int hash)
{
TriggerParameter property = null;
if (m_Triggers.TryGetValue(hash, out property))
return property;
return null;
}
public TriggerParameter GetTriggerProperty(string propertyName)
{
return GetTriggerProperty(Animator.StringToHash(propertyName));
}
public void ResetCheckedTriggers()
{
for (int i = 0; i < m_TriggerArray.Length; ++i)
{
if (m_TriggerArray[i].wasChecked)
m_TriggerArray[i].ResetValue();
}
}
public int GetInt(int hash)
{
IntParameter property = null;
if (m_IntProperties.TryGetValue(hash, out property))
return property.value;
else
return 0;
}
public int GetInt(string propertyName)
{
return GetInt(Animator.StringToHash(propertyName));
}
public void SetInt(int hash, int value)
{
IntParameter property = null;
if (m_IntProperties.TryGetValue(hash, out property))
property.value = value;
}
public IntParameter GetIntProperty(int hash)
{
IntParameter property = null;
if (m_IntProperties.TryGetValue(hash, out property))
return property;
return null;
}
public IntParameter GetIntProperty(string propertyName)
{
return GetIntProperty(Animator.StringToHash(propertyName));
}
public float GetFloat(int hash)
{
FloatParameter property = null;
if (m_FloatProperties.TryGetValue(hash, out property))
return property.value;
else
return 0;
}
public float GetFloat(string propertyName)
{
return GetFloat(Animator.StringToHash(propertyName));
}
public void SetFloat(int hash, float value)
{
FloatParameter property = null;
if (m_FloatProperties.TryGetValue(hash, out property))
property.value = value;
}
public void SetFloat(string propertyName, float value)
{
SetFloat(Animator.StringToHash(propertyName), value);
}
public FloatParameter GetFloatProperty(int hash)
{
FloatParameter property = null;
if (m_FloatProperties.TryGetValue(hash, out property))
return property;
return null;
}
public FloatParameter GetFloatProperty(string propertyName)
{
return GetFloatProperty(Animator.StringToHash(propertyName));
}
public Transform GetTransform(int hash)
{
TransformParameter property = null;
if (m_TransformProperties.TryGetValue(hash, out property))
return property.value;
else
return null;
}
public Transform GetTransform(string propertyName)
{
return GetTransform(Animator.StringToHash(propertyName));
}
public void SetTransform(int hash, Transform value)
{
TransformParameter property = null;
if (m_TransformProperties.TryGetValue(hash, out property))
property.value = value;
}
public void SetTransform(string propertyName, Transform value)
{
SetTransform(Animator.StringToHash(propertyName), value);
}
public TransformParameter GetTransformProperty(int hash)
{
TransformParameter property = null;
if (m_TransformProperties.TryGetValue(hash, out property))
return property;
return null;
}
public TransformParameter GetTransformProperty(string propertyName)
{
return GetTransformProperty(Animator.StringToHash(propertyName));
}
public bool GetSwitch(int hash)
{
SwitchParameter property = null;
if (m_SwitchProperties.TryGetValue(hash, out property))
return property.on;
else
return false;
}
public bool GetSwitch(string propertyName)
{
return GetSwitch(Animator.StringToHash(propertyName));
}
public void SetSwitch(int hash, bool value)
{
SwitchParameter property = null;
if (m_SwitchProperties.TryGetValue(hash, out property))
property.on = value;
}
public void SetSwitch(string propertyName, bool value)
{
SetSwitch(Animator.StringToHash(propertyName), value);
}
public SwitchParameter GetSwitchProperty(int hash)
{
SwitchParameter property = null;
if (m_SwitchProperties.TryGetValue(hash, out property))
return property;
return null;
}
public SwitchParameter GetSwitchProperty(string propertyName)
{
return GetSwitchProperty(Animator.StringToHash(propertyName));
}
public Vector3 GetVector(int hash)
{
VectorParameter property = null;
if (m_VectorProperties.TryGetValue(hash, out property))
return property.value;
else
return Vector3.zero;
}
public Vector3 GetVector(string propertyName)
{
return GetVector(Animator.StringToHash(propertyName));
}
public void SetVector(int hash, Vector3 value)
{
VectorParameter property = null;
if (m_VectorProperties.TryGetValue(hash, out property))
property.value = value;
}
public VectorParameter GetVectorProperty(int hash)
{
VectorParameter property = null;
if (m_VectorProperties.TryGetValue(hash, out property))
return property;
return null;
}
public VectorParameter GetVectorProperty(string propertyName)
{
return GetVectorProperty(Animator.StringToHash(propertyName));
}
public void AddEventListener(int hash, UnityAction listener)
{
EventParameter property = null;
if (m_EventProperties.TryGetValue(hash, out property))
property.AddListener(listener);
}
public void AddEventListener(string propertyName, UnityAction listener)
{
AddEventListener(Animator.StringToHash(propertyName), listener);
}
public void RemoveEventListener(int hash, UnityAction listener)
{
EventParameter property = null;
if (m_EventProperties.TryGetValue(hash, out property))
property.RemoveListener(listener);
}
public void RemoveEventListener(string propertyName, UnityAction listener)
{
RemoveEventListener(Animator.StringToHash(propertyName), listener);
}
public EventParameter GetEventProperty(int hash)
{
EventParameter property = null;
if (m_EventProperties.TryGetValue(hash, out property))
return property;
return null;
}
public EventParameter GetEventProperty(string propertyName)
{
return GetEventProperty(Animator.StringToHash(propertyName));
}
public void CollectParameters(List<MotionGraphParameter> list)
{
list.AddRange(m_Parameters);
}
public void CollectIntParameters(List<IntParameter> list)
{
foreach (MotionGraphParameter property in m_Parameters)
{
var cast = property as IntParameter;
if (cast != null)
list.Add(cast);
}
list.Sort((IntParameter lhs, IntParameter rhs) =>
{
return string.Compare(lhs.name, rhs.name);
}
);
}
public void CollectFloatParameters(List<FloatParameter> list)
{
foreach (MotionGraphParameter property in m_Parameters)
{
var cast = property as FloatParameter;
if (cast != null)
list.Add(cast);
}
list.Sort((FloatParameter lhs, FloatParameter rhs) =>
{
return string.Compare(lhs.name, rhs.name);
}
);
}
public void CollectTriggerParameters(List<TriggerParameter> list)
{
foreach (MotionGraphParameter property in m_Parameters)
{
var cast = property as TriggerParameter;
if (cast != null)
list.Add(cast);
}
list.Sort((TriggerParameter lhs, TriggerParameter rhs) =>
{
return string.Compare(lhs.name, rhs.name);
}
);
}
public void CollectTransformParameters(List<TransformParameter> list)
{
foreach (MotionGraphParameter property in m_Parameters)
{
var cast = property as TransformParameter;
if (cast != null)
list.Add(cast);
}
list.Sort((TransformParameter lhs, TransformParameter rhs) =>
{
return string.Compare(lhs.name, rhs.name);
}
);
}
public void CollectSwitchParameters(List<SwitchParameter> list)
{
foreach (MotionGraphParameter property in m_Parameters)
{
var cast = property as SwitchParameter;
if (cast != null)
list.Add(cast);
}
list.Sort((SwitchParameter lhs, SwitchParameter rhs) =>
{
return string.Compare(lhs.name, rhs.name);
}
);
}
public void CollectVectorParameters(List<VectorParameter> list)
{
foreach (MotionGraphParameter property in m_Parameters)
{
var cast = property as VectorParameter;
if (cast != null)
list.Add(cast);
}
list.Sort((VectorParameter lhs, VectorParameter rhs) =>
{
return string.Compare(lhs.name, rhs.name);
}
);
}
public void CollectEventParameters(List<EventParameter> list)
{
foreach (MotionGraphParameter property in m_Parameters)
{
var cast = property as EventParameter;
if (cast != null)
list.Add(cast);
}
list.Sort((EventParameter lhs, EventParameter rhs) =>
{
return string.Compare(lhs.name, rhs.name);
}
);
}
public void CollectData(List<MotionGraphDataBase> list, bool sorted = true)
{
list.AddRange(m_Data);
if (sorted)
{
list.Sort((MotionGraphDataBase lhs, MotionGraphDataBase rhs) =>
{
return string.Compare(lhs.name, rhs.name);
});
}
}
public void CollectBoolData(List<BoolData> list, bool sorted = true)
{
foreach (MotionGraphDataBase data in m_Data)
{
var cast = data as BoolData;
if (cast != null)
list.Add(cast);
}
if (sorted)
{
list.Sort((BoolData lhs, BoolData rhs) =>
{
return string.Compare(lhs.name, rhs.name);
});
}
}
public void CollectIntData(List<IntData> list, bool sorted = true)
{
foreach (MotionGraphDataBase data in m_Data)
{
var cast = data as IntData;
if (cast != null)
list.Add(cast);
}
if (sorted)
{
list.Sort((IntData lhs, IntData rhs) =>
{
return string.Compare(lhs.name, rhs.name);
});
}
}
public void CollectFloatData(List<FloatData> list, bool sorted = true)
{
foreach (MotionGraphDataBase data in m_Data)
{
var cast = data as FloatData;
if (cast != null)
list.Add(cast);
}
if (sorted)
{
list.Sort((FloatData lhs, FloatData rhs) =>
{
return string.Compare(lhs.name, rhs.name);
});
}
}
public void AddDataOverrides(IMotionGraphDataOverride o)
{
for (int i = 0; i < m_Data.Count; ++i)
m_Data[i].AddOverride(o);
}
public void RemoveDataOverrides(IMotionGraphDataOverride o)
{
for (int i = 0; i < m_Data.Count; ++i)
m_Data[i].RemoveOverride(o);
}
[Obsolete("ApplyDataOverrides is has been replaced with Add/RemoveDataOverrides which allows for stacking.")]
public void ApplyDataOverrides(IMotionGraphDataOverride o)
{
for (int i = 0; i < m_Data.Count; ++i)
m_Data[i].AddOverride(o);
}
public void WriteProperties(INeoSerializer writer)
{
// Save parameters
foreach (var pair in m_FloatProperties)
writer.WriteValue(pair.Key, pair.Value.value);
foreach (var pair in m_IntProperties)
writer.WriteValue(pair.Key, pair.Value.value);
foreach (var pair in m_Triggers)
writer.WriteValue(pair.Key, pair.Value.PeekTrigger());
foreach (var pair in m_SwitchProperties)
writer.WriteValue(pair.Key, pair.Value.on);
if (m_TransformProperties.Count > 0)
{
var owner = m_Controller.GetComponent<NeoSerializedGameObject>();
if (owner != null)
{
foreach (var pair in m_TransformProperties)
writer.WriteTransformReference(pair.Key, pair.Value.value, owner);
}
}
}
public void ReadProperties(INeoDeserializer reader)
{
// Load parameters
foreach (var pair in m_FloatProperties)
{
float result;
if (reader.TryReadValue(pair.Key, out result, 0f))
pair.Value.value = result;
}
foreach (var pair in m_IntProperties)
{
int result;
if (reader.TryReadValue(pair.Key, out result, 0))
pair.Value.value = result;
}
foreach (var pair in m_Triggers)
{
bool result;
if (reader.TryReadValue(pair.Key, out result, false))
{
if (result)
pair.Value.Trigger();
else
pair.Value.ResetValue();
}
}
foreach (var pair in m_SwitchProperties)
{
bool result;
if (reader.TryReadValue(pair.Key, out result, false))
pair.Value.on = result;
}
if (m_TransformProperties.Count > 0)
{
var owner = m_Controller.GetComponent<NeoSerializedGameObject>();
if (owner != null)
{
foreach (var pair in m_TransformProperties)
{
Transform result;
if (reader.TryReadTransformReference(pair.Key, out result, owner))
pair.Value.value = result;
}
}
}
}
}
}