138 lines
4.1 KiB
C#
138 lines
4.1 KiB
C#
// Designed by KINEMATION, 2024.
|
|
|
|
using KINEMATION.KAnimationCore.Runtime.Input;
|
|
|
|
using System.Collections.Generic;
|
|
using KINEMATION.KAnimationCore.Runtime.Attributes;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using Object = UnityEngine.Object;
|
|
|
|
namespace KINEMATION.KAnimationCore.Runtime.Rig
|
|
{
|
|
public abstract class KRigBase : ScriptableObject, IRigProvider
|
|
{
|
|
public RuntimeAnimatorController targetAnimator;
|
|
public List<KRigElement> rigHierarchy = new List<KRigElement>();
|
|
|
|
[CustomElementChainDrawer(false, true)]
|
|
public List<KRigElementChain> rigElementChains = new List<KRigElementChain>();
|
|
|
|
public KRigElement[] GetHierarchy()
|
|
{
|
|
return rigHierarchy.ToArray();
|
|
}
|
|
}
|
|
|
|
// Character skeleton asset.
|
|
public class KRig : KRigBase
|
|
{
|
|
public UserInputConfig inputConfig;
|
|
public List<string> rigCurves = new List<string>();
|
|
|
|
public KRigElementChain GetElementChainByName(string chainName)
|
|
{
|
|
var chain = rigElementChains.Find(item => item.chainName.Equals(chainName));
|
|
return chain;
|
|
}
|
|
|
|
public KTransformChain GetPopulatedChain(string chainName, KRigComponent rigComponent)
|
|
{
|
|
KTransformChain result = new KTransformChain();
|
|
var targetChain = GetElementChainByName(chainName);
|
|
|
|
if (targetChain == null)
|
|
{
|
|
Debug.LogError($"Rig `{name}`: `{chainName}` chain not found!");
|
|
return null;
|
|
}
|
|
|
|
foreach (var element in targetChain.elementChain)
|
|
{
|
|
result.transformChain.Add(rigComponent.GetRigTransform(element));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
public List<int> rigDepths = new List<int>();
|
|
private List<Object> _rigObservers = new List<Object>();
|
|
|
|
private void OnEnable()
|
|
{
|
|
// Force update rig depths for compatibility reasons.
|
|
int count = rigHierarchy.Count;
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
var element = rigHierarchy[i];
|
|
element.depth = rigDepths[i];
|
|
rigHierarchy[i] = element;
|
|
}
|
|
}
|
|
|
|
public void ImportRig(KRigComponent rigComponent)
|
|
{
|
|
rigHierarchy.Clear();
|
|
rigDepths.Clear();
|
|
|
|
rigComponent.RefreshHierarchy();
|
|
|
|
var hierarchy = rigComponent.GetRigTransforms();
|
|
var depths = rigComponent.GetHierarchyDepths();
|
|
|
|
for (int i = 0; i < hierarchy.Length; i++)
|
|
{
|
|
rigHierarchy.Add(new KRigElement(i, hierarchy[i].transform.name));
|
|
rigDepths.Add(depths[i]);
|
|
}
|
|
|
|
NotifyObservers();
|
|
|
|
EditorUtility.SetDirty(this);
|
|
AssetDatabase.SaveAssetIfDirty(this);
|
|
}
|
|
|
|
public KRigElement GetElementByName(string targetName)
|
|
{
|
|
return rigHierarchy.Find(item => item.name.Equals(targetName));
|
|
}
|
|
|
|
public void RegisterRigObserver(Object newRigObserver)
|
|
{
|
|
// Only register Rig Observers.
|
|
IRigObserver observer = (IRigObserver) newRigObserver;
|
|
if (observer == null) return;
|
|
|
|
if (_rigObservers.Contains(newRigObserver))
|
|
{
|
|
return;
|
|
}
|
|
|
|
_rigObservers.Add(newRigObserver);
|
|
EditorUtility.SetDirty(this);
|
|
}
|
|
|
|
public void UnRegisterObserver(Object rigObserver)
|
|
{
|
|
_rigObservers.Remove(rigObserver);
|
|
EditorUtility.SetDirty(this);
|
|
}
|
|
|
|
public void NotifyObservers()
|
|
{
|
|
List<Object> validObservers = new List<Object>();
|
|
foreach (var observer in _rigObservers)
|
|
{
|
|
if (observer is IRigObserver obj)
|
|
{
|
|
obj.OnRigUpdated();
|
|
validObservers.Add(observer);
|
|
}
|
|
}
|
|
|
|
_rigObservers = validObservers;
|
|
}
|
|
#endif
|
|
}
|
|
} |