// 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 rigHierarchy = new List(); [CustomElementChainDrawer(false, true)] public List rigElementChains = new List(); public KRigElement[] GetHierarchy() { return rigHierarchy.ToArray(); } } // Character skeleton asset. public class KRig : KRigBase { public UserInputConfig inputConfig; public List rigCurves = new List(); 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 rigDepths = new List(); private List _rigObservers = new List(); 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 validObservers = new List(); foreach (var observer in _rigObservers) { if (observer is IRigObserver obj) { obj.OnRigUpdated(); validObservers.Add(observer); } } _rigObservers = validObservers; } #endif } }