-
-
Save TigerHix/8413f8e10e508f37bb946d8802ee4e0b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Cysharp.Threading.Tasks; | |
using RootMotion.FinalIK; | |
using UnityEngine; | |
using Warudo.Core; | |
using Warudo.Core.Attributes; | |
using Warudo.Core.Utils; | |
using Warudo.Plugins.Core; | |
using Warudo.Plugins.Core.Assets.Character; | |
using Object = UnityEngine.Object; | |
namespace Playground { | |
[AssetType(Id = "CharacterPoser")] | |
public class CharacterPoserAsset : CharacterDaemonAsset { | |
public bool IsPosing { get; private set; } = false; | |
private Transform poserRoot; | |
private VRIK vrik; | |
private Transform headTarget; | |
private Transform pelvisTarget; | |
private Transform leftHandTarget; | |
private Transform rightHandTarget; | |
private Transform leftFootTarget; | |
private Transform rightFootTarget; | |
[Trigger] | |
[HiddenIf(nameof(HideEnterPoseMode))] | |
public async void EnterPoseMode() { | |
if (IsPosing) return; | |
await UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate); | |
CharacterDaemon.GameObject.transform.position = Character.MainTransform.position; | |
CharacterDaemon.GameObject.transform.rotation = Character.MainTransform.rotation; | |
for (var i = 0; i < (int)HumanBodyBones.LastBone; i++) { | |
var bt = CharacterDaemon.Animator.GetBoneTransform((HumanBodyBones)i); | |
if (bt != null) { | |
bt.localRotation = Character.EndOfFrameBoneRotations[i]; | |
if (i == (int) HumanBodyBones.Hips) { | |
bt.localPosition = Character.EndOfFrameBonePositions[i]; | |
} | |
} | |
} | |
vrik = CharacterDaemon.GameObject.GetOrAddComponent<VRIK>(); | |
vrik.AutoDetectReferences(); | |
poserRoot = new GameObject("Poser Root").transform; | |
headTarget = new GameObject("Poser Head Target").transform; | |
pelvisTarget = new GameObject("Poser Pelvis Target").transform; | |
leftHandTarget = new GameObject("Poser Left Hand Target").transform; | |
rightHandTarget = new GameObject("Poser Right Hand Target").transform; | |
leftFootTarget = new GameObject("Poser Left Foot Target").transform; | |
rightFootTarget = new GameObject("Poser Right Foot Target").transform; | |
headTarget.SetParent(poserRoot.transform); | |
pelvisTarget.SetParent(poserRoot.transform); | |
leftHandTarget.SetParent(poserRoot.transform); | |
rightHandTarget.SetParent(poserRoot.transform); | |
leftFootTarget.SetParent(poserRoot.transform); | |
rightFootTarget.SetParent(poserRoot.transform); | |
bool Copy(HumanBodyBones bone, Transform to) { | |
var hasTransform = Character.Animator.GetBoneTransform(bone) != null; | |
if (!hasTransform) return false; | |
to.position = Character.EndOfFrameBoneWorldPositions[(int)bone]; | |
to.rotation = Character.EndOfFrameBoneWorldRotations[(int)bone]; | |
return true; | |
} | |
Copy(HumanBodyBones.Head, headTarget); | |
Copy(HumanBodyBones.Hips, pelvisTarget); | |
Copy(HumanBodyBones.LeftHand, leftHandTarget); | |
Copy(HumanBodyBones.RightHand, rightHandTarget); | |
if (!Copy(HumanBodyBones.LeftToes, leftFootTarget)) Copy(HumanBodyBones.LeftFoot, leftFootTarget); | |
if (!Copy(HumanBodyBones.RightToes, rightFootTarget)) Copy(HumanBodyBones.RightFoot, rightFootTarget); | |
vrik.solver.plantFeet = false; | |
vrik.solver.spine.minHeadHeight = 0f; | |
vrik.solver.spine.headTarget = headTarget; | |
vrik.solver.spine.pelvisTarget = pelvisTarget; | |
vrik.solver.spine.maintainPelvisPosition = 0f; | |
vrik.solver.spine.neckStiffness = 0f; | |
vrik.solver.spine.bodyPosStiffness = 0f; | |
vrik.solver.spine.bodyRotStiffness = 0f; | |
vrik.solver.spine.moveBodyBackWhenCrouching = 0f; | |
vrik.solver.leftArm.target = leftHandTarget; | |
vrik.solver.rightArm.target = rightHandTarget; | |
vrik.solver.leftLeg.target = leftFootTarget; | |
vrik.solver.rightLeg.target = rightFootTarget; | |
vrik.solver.spine.pelvisPositionWeight = 1f; | |
vrik.solver.spine.pelvisRotationWeight = 1f; | |
vrik.solver.leftLeg.positionWeight = 1f; | |
vrik.solver.leftLeg.rotationWeight = 1f; | |
vrik.solver.rightLeg.positionWeight = 1f; | |
vrik.solver.rightLeg.rotationWeight = 1f; | |
vrik.solver.locomotion.weight = 0f; | |
IsPosing = true; | |
EnableTransformGizmo(); | |
} | |
protected bool HideEnterPoseMode() => IsPosing; | |
[Trigger] | |
[HiddenIf(nameof(HideExitPoseMode))] | |
public void ExitPoseMode() { | |
if (!IsPosing) return; | |
IsPosing = false; | |
DisableTransformGizmo(); | |
if (poserRoot != null) { | |
Object.Destroy(poserRoot.gameObject); | |
} | |
if (vrik != null) { | |
Object.Destroy(vrik); | |
} | |
} | |
protected bool HideExitPoseMode() => !IsPosing; | |
protected override void OnCreate() { | |
base.OnCreate(); | |
OnSelectedStateChange.AddListener(selected => { | |
if (selected) { | |
EnableTransformGizmo(); | |
} else { | |
DisableTransformGizmo(); | |
} | |
}); | |
SetActive(true); | |
} | |
protected override void OnDestroy() { | |
base.OnDestroy(); | |
if (poserRoot != null) { | |
Object.Destroy(poserRoot.gameObject); | |
} | |
DisableTransformGizmo(); | |
} | |
protected override async void OnCreateCharacterDaemon() { | |
base.OnCreateCharacterDaemon(); | |
CharacterDaemon.Animancer.enabled = false; | |
CharacterDaemon.Animator.enabled = true; | |
} | |
public override async void OnPostLateUpdate() { | |
base.OnPostLateUpdate(); | |
if (!CharacterDaemon.IsCreated()) return; | |
if (IsPosing) { | |
for (var i = 0; i < (int)HumanBodyBones.LastBone; i++) { | |
var bt = CharacterDaemon.Animator.GetBoneTransform((HumanBodyBones) i); | |
var originalBt = Character.Animator.GetBoneTransform((HumanBodyBones) i); | |
if (bt != null && originalBt != null) { | |
originalBt.position = bt.position; | |
originalBt.rotation = bt.rotation; | |
} | |
} | |
} | |
} | |
private void EnableTransformGizmo() { | |
if (!IsSelected || !Active || !IsPosing) return; | |
var tg = Context.PluginManager.GetPlugin<CorePlugin>().TransformGizmo; | |
tg.AddTargets(new [] { | |
headTarget, | |
pelvisTarget, | |
leftHandTarget, | |
rightHandTarget, | |
leftFootTarget, | |
rightFootTarget, | |
}, null, gizmo => { | |
gizmo.handleLength = .025f; | |
gizmo.handleWidth = .0004f; | |
gizmo.planeSize = .005f; | |
gizmo.triangleSize = .006f; | |
gizmo.circleDetail = 16; | |
}); | |
} | |
private void DisableTransformGizmo() { | |
if (!IsPosing) return; | |
var tg = Context.PluginManager.GetPlugin<CorePlugin>().TransformGizmo; | |
tg.RemoveTargets(new [] { | |
headTarget, | |
pelvisTarget, | |
leftHandTarget, | |
rightHandTarget, | |
leftFootTarget, | |
rightFootTarget, | |
}); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment