CreateState() method must return a new instance of the desired FPSAnimatorLayerState-type. When you are linking a new Animator Profile, the system iterates over all animation features (Layer Settings) and then invokes the CreateState() method to create the Layer State.
Now let's actually create a custom animator layer.
Example
First, create new FPSAnimatorLayerSettings- and FPSAnimatorLayer-derived classes:
YourFeatureLayerSettings.cs
publicclassYourFeatureLayerSettings:FPSAnimatorLayerSettings{ //Define your settings here, including the KRigElements.publicKRigElement myRigElement;publicoverrideYourFeatureLayerStateCreateState() {returnnewYourFeatureLayerState(); }#if UNITY_EDITORpublicoverridevoidOnRigUpdated() { base.OnRigUpdated(); // (!) Always update KRigElements here. // Called when a rig asset is updated/changed.UpdateRigElement(ref myRigElement); }#endif}
YourFeatureLayerState.cs
publicclassAdditiveLayerState:FPSAnimatorLayerState{privateYourFeatureLayerSettings _settings;publicoverridevoidInitializeState(FPSAnimatorLayerSettings newSettings) { base.InitializeState(newSettings); _settings = (YourFeatureLayerSettings) newSettings; }publicoverridevoidOnEntityUpdated(FPSAnimatorEntity newEntity) { // Called when a weapon/item is equipped. // Use this callback for weapon/item-related features. }publicoverridevoidOnGameThreadUpdate() { // Use this to collect general, game-thread data. // It is safe to access character references here. // Called on Update() before the main animation pass. }publicoverridevoidOnEvaluatePose() { // Apply procedural features here. }publicoverridevoidOnPostEvaluatePose() { // Called when all layers are applied. }}
If you want to leverage features like blending or dynamic layer linking, make sure to implement these methods:
YourFeatureLayerState.cs
publicclassAdditiveLayerState:FPSAnimatorLayerState{ ... // Use this callback to re-initialize values. // It is only called when the Link Dynamically is true.publicoverridevoidOnLayerLinked(FPSAnimatorLayerSettings newSettings) { _settings = (YourFeatureLayerSettings) newSettings; } // Make sure to manually register all the bones affected by this state. // This is required for smooth blending and pose caching.publicoverridevoidRegisterBones(refHashSet<int> registeredBones) {registeredBones.Add(_settings.myRigElement); } // Make sure to cache the poses for active bones.publicoverridevoidCachePoses(refList<KPose> cachedPoses) {cachedPoses.Add(newKPose() { element =_settings.myRigElement, modifyMode =EModifyMode.Add, pose =KTransform.Identity, space =ESpaceType.ComponentSpace }); // Add other poses here. }}