176 lines
4.9 KiB
C#
176 lines
4.9 KiB
C#
// Designed by KINEMATION, 2024.
|
|
|
|
using System.Collections.Generic;
|
|
using KINEMATION.KAnimationCore.Runtime.Core;
|
|
using UnityEngine;
|
|
|
|
namespace KINEMATION.KAnimationCore.Runtime.Rig
|
|
{
|
|
public class KRigComponent : MonoBehaviour
|
|
{
|
|
[SerializeField] private List<Transform> hierarchy = new List<Transform>();
|
|
private List<KVirtualElement> _virtualElements;
|
|
private Dictionary<string, int> _hierarchyMap;
|
|
private List<KTransform> _cachedHierarchyPose;
|
|
|
|
#if UNITY_EDITOR
|
|
[SerializeField] private List<int> hierarchyDepths = new List<int>();
|
|
|
|
public bool CompareRig(KRig compareTo)
|
|
{
|
|
if (compareTo == null || hierarchy == null || compareTo.rigHierarchy.Count != hierarchy.Count)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
int count = hierarchy.Count;
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
if (!compareTo.rigHierarchy[i].name.Equals(hierarchy[i].name)) return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public int[] GetHierarchyDepths()
|
|
{
|
|
return hierarchyDepths.ToArray();
|
|
}
|
|
|
|
public void RefreshHierarchy()
|
|
{
|
|
hierarchy.Clear();
|
|
hierarchyDepths.Clear();
|
|
TraverseHierarchyByLayer(transform, 0);
|
|
}
|
|
|
|
public Transform[] GetHierarchy()
|
|
{
|
|
if (hierarchy == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return hierarchy.ToArray();
|
|
}
|
|
|
|
public bool Contains(string entry)
|
|
{
|
|
if (hierarchy == null) return false;
|
|
|
|
HashSet<string> set = new HashSet<string>();
|
|
foreach (var element in hierarchy)
|
|
{
|
|
set.Add(element.name);
|
|
}
|
|
|
|
return set.Contains(entry);
|
|
}
|
|
|
|
private void TraverseHierarchyByLayer(Transform currentTransform, int depth)
|
|
{
|
|
hierarchy.Add(currentTransform);
|
|
hierarchyDepths.Add(depth);
|
|
|
|
foreach (Transform child in currentTransform)
|
|
{
|
|
TraverseHierarchyByLayer(child, depth + 1);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
public void Initialize()
|
|
{
|
|
// Register Virtual Elements.
|
|
_virtualElements = new List<KVirtualElement>();
|
|
KVirtualElement[] virtualElements = GetComponentsInChildren<KVirtualElement>();
|
|
|
|
foreach (var virtualElement in virtualElements)
|
|
{
|
|
_virtualElements.Add(virtualElement);
|
|
}
|
|
|
|
// Map the hierarchy indexes to the element names.
|
|
_hierarchyMap = new Dictionary<string, int>();
|
|
|
|
int count = hierarchy.Count;
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
_hierarchyMap.TryAdd(hierarchy[i].name, i);
|
|
}
|
|
|
|
_cachedHierarchyPose = new List<KTransform>();
|
|
}
|
|
|
|
public void AnimateVirtualElements()
|
|
{
|
|
foreach (var virtualElement in _virtualElements)
|
|
{
|
|
virtualElement.Animate();
|
|
}
|
|
}
|
|
|
|
public Transform[] GetRigTransforms()
|
|
{
|
|
return hierarchy.ToArray();
|
|
}
|
|
|
|
public Transform GetRigTransform(KRigElement rigElement)
|
|
{
|
|
int index = rigElement.index;
|
|
|
|
// Invalid index, try to use the element name instead.
|
|
if (index < 0 || index > hierarchy.Count - 1)
|
|
{
|
|
index = _hierarchyMap[rigElement.name];
|
|
}
|
|
|
|
// Total failure, return null.
|
|
if (index < 0 || index > hierarchy.Count - 1)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return hierarchy[index].transform;
|
|
}
|
|
|
|
public Transform GetRigTransform(string elementName)
|
|
{
|
|
if (_hierarchyMap.TryGetValue(elementName, out var element))
|
|
{
|
|
return hierarchy[element];
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public Transform GetRigTransform(int elementIndex)
|
|
{
|
|
if (elementIndex < 0 || elementIndex > hierarchy.Count - 1)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return hierarchy[elementIndex].transform;
|
|
}
|
|
|
|
public void CacheHierarchyPose()
|
|
{
|
|
_cachedHierarchyPose.Clear();
|
|
foreach (var element in hierarchy) _cachedHierarchyPose.Add(new KTransform(element,
|
|
false));
|
|
}
|
|
|
|
public void ApplyHierarchyCachedPose()
|
|
{
|
|
int count = hierarchy.Count;
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
var cachedPose = _cachedHierarchyPose[i];
|
|
|
|
hierarchy[i].localPosition = cachedPose.position;
|
|
hierarchy[i].localRotation = cachedPose.rotation;
|
|
}
|
|
}
|
|
}
|
|
} |