mirror of
https://github.com/hanetzer/sdraw_mods_cvr.git
synced 2025-09-03 10:29:22 +00:00
604 lines
23 KiB
C#
604 lines
23 KiB
C#
using ABI.CCK.Components;
|
|
using ABI_RC.Core.InteractionSystem;
|
|
using ABI_RC.Core.Player;
|
|
using ABI_RC.Systems.VRModeSwitch;
|
|
using RootMotion.FinalIK;
|
|
using System.Collections;
|
|
using UnityEngine;
|
|
|
|
namespace ml_pam
|
|
{
|
|
[DisallowMultipleComponent]
|
|
class ArmMover : MonoBehaviour
|
|
{
|
|
enum HandState
|
|
{
|
|
Empty = 0,
|
|
Pickup,
|
|
Extended
|
|
}
|
|
struct IKInfo
|
|
{
|
|
public Vector4 m_armsWeights;
|
|
public Transform m_leftHandTarget;
|
|
public Transform m_rightHandTarget;
|
|
}
|
|
|
|
const KeyCode c_leftKey = KeyCode.Q;
|
|
const KeyCode c_rightKey = KeyCode.E;
|
|
|
|
static ArmMover ms_instance = null;
|
|
|
|
static readonly Quaternion ms_offsetLeft = Quaternion.Euler(270f, 90f, 0f);
|
|
static readonly Quaternion ms_offsetRight = Quaternion.Euler(270f, 270f, 0f);
|
|
|
|
VRIK m_vrIK = null;
|
|
Vector4 m_armsLength; // x,y - from upper arm to hand; z,w - from center to upper arm
|
|
Transform m_camera = null;
|
|
IKInfo m_ikInfo;
|
|
|
|
Transform m_root = null;
|
|
Transform m_leftTarget = null;
|
|
Transform m_rightTarget = null;
|
|
Transform m_leftRotationTarget = null;
|
|
Transform m_rightRotationTarget = null;
|
|
ArmIK m_armIKLeft = null;
|
|
ArmIK m_armIKRight = null;
|
|
CVRPickupObject m_pickup = null;
|
|
Matrix4x4 m_offset;
|
|
|
|
HandState m_leftHandState = HandState.Empty;
|
|
HandState m_rightHandState = HandState.Empty;
|
|
Vector2 m_handsWeights;
|
|
|
|
AvatarBoolParameter m_leftHandParameter = null;
|
|
AvatarBoolParameter m_rightHandParameter = null;
|
|
|
|
Coroutine m_disableTask = null;
|
|
|
|
// Unity events
|
|
void Awake()
|
|
{
|
|
if(ms_instance != null)
|
|
{
|
|
DestroyImmediate(this);
|
|
return;
|
|
}
|
|
|
|
ms_instance = this;
|
|
DontDestroyOnLoad(this);
|
|
}
|
|
|
|
void Start()
|
|
{
|
|
m_camera = PlayerSetup.Instance.GetActiveCamera().transform;
|
|
|
|
m_root = new GameObject("Root").transform;
|
|
m_root.parent = this.transform;
|
|
m_root.localPosition = Vector3.zero;
|
|
m_root.localRotation = Quaternion.identity;
|
|
|
|
m_leftTarget = new GameObject("TargetLeft").transform;
|
|
m_leftTarget.parent = m_root;
|
|
m_leftTarget.localPosition = Vector3.zero;
|
|
m_leftTarget.localRotation = Quaternion.identity;
|
|
|
|
m_leftRotationTarget = new GameObject("RotationTarget").transform;
|
|
m_leftRotationTarget.parent = m_leftTarget;
|
|
m_leftRotationTarget.localPosition = Vector3.zero;
|
|
m_leftRotationTarget.localRotation = Quaternion.identity;
|
|
|
|
m_rightTarget = new GameObject("TargetRight").transform;
|
|
m_rightTarget.parent = m_root;
|
|
m_rightTarget.localPosition = Vector3.zero;
|
|
m_rightTarget.localRotation = Quaternion.identity;
|
|
|
|
m_rightRotationTarget = new GameObject("RotationTarget").transform;
|
|
m_rightRotationTarget.parent = m_rightTarget;
|
|
m_rightRotationTarget.localPosition = Vector3.zero;
|
|
m_rightRotationTarget.localRotation = Quaternion.identity;
|
|
|
|
Settings.OnEnabledChanged.AddListener(this.OnEnabledChanged);
|
|
Settings.OnGrabOffsetChanged.AddListener(this.OnGrabOffsetChanged);
|
|
Settings.OnLeadingHandChanged.AddListener(this.OnLeadingHandChanged);
|
|
Settings.OnHandsExtensionChanged.AddListener(this.OnHandsExtensionChanged);
|
|
|
|
GameEvents.OnAvatarClear.AddListener(this.OnAvatarClear);
|
|
GameEvents.OnAvatarSetup.AddListener(this.OnAvatarSetup);
|
|
GameEvents.OnAvatarReuse.AddListener(this.OnAvatarReuse);
|
|
GameEvents.OnIKScaling.AddListener(this.OnIKScaling);
|
|
GameEvents.OnPickupGrab.AddListener(this.OnPickupGrab);
|
|
GameEvents.OnPickupDrop.AddListener(this.OnPickupDrop);
|
|
|
|
VRModeSwitchEvents.OnCompletedVRModeSwitch.AddListener(this.OnVRModeSwitch);
|
|
}
|
|
|
|
void OnDestroy()
|
|
{
|
|
if(ms_instance == this)
|
|
ms_instance = null;
|
|
|
|
if(m_disableTask != null)
|
|
StopCoroutine(m_disableTask);
|
|
m_disableTask = null;
|
|
|
|
RemoveArmIK();
|
|
|
|
if(m_leftRotationTarget != null)
|
|
Destroy(m_leftRotationTarget.gameObject);
|
|
m_leftRotationTarget = null;
|
|
|
|
if(m_leftTarget != null)
|
|
Destroy(m_leftTarget.gameObject);
|
|
m_leftTarget = null;
|
|
|
|
if(m_rightRotationTarget != null)
|
|
Destroy(m_rightRotationTarget.gameObject);
|
|
m_rightRotationTarget = null;
|
|
|
|
if(m_rightTarget != null)
|
|
Destroy(m_rightTarget.gameObject);
|
|
m_rightTarget = null;
|
|
|
|
if(m_root != null)
|
|
Destroy(m_root.gameObject);
|
|
m_root = null;
|
|
|
|
m_pickup = null;
|
|
m_vrIK = null;
|
|
|
|
Settings.OnEnabledChanged.RemoveListener(this.OnEnabledChanged);
|
|
Settings.OnGrabOffsetChanged.RemoveListener(this.OnGrabOffsetChanged);
|
|
Settings.OnLeadingHandChanged.RemoveListener(this.OnLeadingHandChanged);
|
|
Settings.OnHandsExtensionChanged.RemoveListener(this.OnHandsExtensionChanged);
|
|
|
|
GameEvents.OnAvatarClear.RemoveListener(this.OnAvatarClear);
|
|
GameEvents.OnAvatarSetup.RemoveListener(this.OnAvatarSetup);
|
|
GameEvents.OnAvatarReuse.RemoveListener(this.OnAvatarReuse);
|
|
GameEvents.OnIKScaling.AddListener(this.OnIKScaling);
|
|
GameEvents.OnPickupGrab.RemoveListener(this.OnPickupGrab);
|
|
GameEvents.OnPickupDrop.RemoveListener(this.OnPickupDrop);
|
|
|
|
VRModeSwitchEvents.OnCompletedVRModeSwitch.RemoveListener(this.OnVRModeSwitch);
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if((m_root != null) && (m_camera != null))
|
|
{
|
|
m_root.position = m_camera.position;
|
|
m_root.rotation = m_camera.rotation;
|
|
}
|
|
|
|
if(!ReferenceEquals(m_pickup, null) && (m_pickup == null))
|
|
OnPickupDrop(m_pickup);
|
|
|
|
switch(m_leftHandState)
|
|
{
|
|
case HandState.Empty:
|
|
{
|
|
if(Settings.Enabled && Settings.HandsExtension && Input.GetKey(c_leftKey) && !ViewManager.Instance.IsAnyMenuOpen)
|
|
m_leftHandState = HandState.Extended;
|
|
}
|
|
break;
|
|
case HandState.Extended:
|
|
{
|
|
if(!Input.GetKey(c_leftKey))
|
|
m_leftHandState = HandState.Empty;
|
|
}
|
|
break;
|
|
}
|
|
switch(m_rightHandState)
|
|
{
|
|
case HandState.Empty:
|
|
{
|
|
if(Settings.Enabled && Settings.HandsExtension && Input.GetKey(c_rightKey) && !ViewManager.Instance.IsAnyMenuOpen)
|
|
m_rightHandState = HandState.Extended;
|
|
}
|
|
break;
|
|
case HandState.Extended:
|
|
{
|
|
if(!Input.GetKey(c_rightKey))
|
|
m_rightHandState = HandState.Empty;
|
|
}
|
|
break;
|
|
}
|
|
|
|
m_handsWeights.x = Mathf.Clamp01(m_handsWeights.x + ((m_leftHandState != HandState.Empty) ? 1f : -1f) * Time.unscaledDeltaTime * Settings.ExtensionSpeed);
|
|
m_handsWeights.y = Mathf.Clamp01(m_handsWeights.y + ((m_rightHandState != HandState.Empty) ? 1f : -1f) * Time.unscaledDeltaTime * Settings.ExtensionSpeed);
|
|
|
|
UpdateArmIK(m_armIKLeft, m_handsWeights.x);
|
|
UpdateArmIK(m_armIKRight, m_handsWeights.y);
|
|
|
|
m_leftHandParameter?.SetValue(m_leftHandState != HandState.Empty);
|
|
m_rightHandParameter?.SetValue(m_rightHandState != HandState.Empty);
|
|
|
|
if(m_leftHandState != HandState.Empty)
|
|
{
|
|
if(m_pickup != null)
|
|
{
|
|
Matrix4x4 l_result = m_pickup.transform.GetMatrix() * m_offset;
|
|
m_leftTarget.position = l_result.GetPosition();
|
|
m_leftTarget.rotation = l_result.rotation;
|
|
m_leftTarget.localPosition = Vector3.ClampMagnitude(m_leftTarget.localPosition, m_armsLength.x);
|
|
}
|
|
else
|
|
{
|
|
m_leftTarget.localPosition = new Vector3(0f, 0f, m_armsLength.x);
|
|
m_leftTarget.localRotation = Quaternion.identity;
|
|
}
|
|
}
|
|
if(m_rightHandState != HandState.Empty)
|
|
{
|
|
if(m_pickup != null)
|
|
{
|
|
Matrix4x4 l_result = m_pickup.transform.GetMatrix() * m_offset;
|
|
m_rightTarget.position = l_result.GetPosition();
|
|
m_rightTarget.rotation = l_result.rotation;
|
|
m_rightTarget.localPosition = Vector3.ClampMagnitude(m_rightTarget.localPosition, m_armsLength.y);
|
|
}
|
|
else
|
|
{
|
|
m_rightTarget.localPosition = new Vector3(0f, 0f, m_armsLength.y);
|
|
m_rightTarget.localRotation = Quaternion.identity;
|
|
}
|
|
}
|
|
}
|
|
|
|
void LateUpdate()
|
|
{
|
|
if((m_root != null) && (m_camera != null))
|
|
{
|
|
m_root.position = m_camera.position;
|
|
m_root.rotation = m_camera.rotation;
|
|
}
|
|
}
|
|
|
|
// VRIK updates
|
|
void OnIKPreUpdate()
|
|
{
|
|
if(!Mathf.Approximately(m_handsWeights.x, 0f))
|
|
{
|
|
m_ikInfo.m_leftHandTarget = m_vrIK.solver.leftArm.target;
|
|
m_ikInfo.m_armsWeights.x = m_vrIK.solver.leftArm.positionWeight;
|
|
m_ikInfo.m_armsWeights.y = m_vrIK.solver.leftArm.rotationWeight;
|
|
|
|
m_vrIK.solver.leftArm.positionWeight = m_handsWeights.x;
|
|
m_vrIK.solver.leftArm.rotationWeight = m_handsWeights.x;
|
|
m_vrIK.solver.leftArm.target = m_leftRotationTarget;
|
|
}
|
|
if(!Mathf.Approximately(m_handsWeights.y, 0f))
|
|
{
|
|
m_ikInfo.m_rightHandTarget = m_vrIK.solver.rightArm.target;
|
|
m_ikInfo.m_armsWeights.z = m_vrIK.solver.rightArm.positionWeight;
|
|
m_ikInfo.m_armsWeights.w = m_vrIK.solver.rightArm.rotationWeight;
|
|
|
|
m_vrIK.solver.rightArm.positionWeight = m_handsWeights.y;
|
|
m_vrIK.solver.rightArm.rotationWeight = m_handsWeights.y;
|
|
m_vrIK.solver.rightArm.target = m_rightRotationTarget;
|
|
}
|
|
}
|
|
void OnIKPostUpdate()
|
|
{
|
|
if(!Mathf.Approximately(m_handsWeights.x, 0f))
|
|
{
|
|
m_vrIK.solver.leftArm.target = m_ikInfo.m_leftHandTarget;
|
|
m_vrIK.solver.leftArm.positionWeight = m_ikInfo.m_armsWeights.x;
|
|
m_vrIK.solver.leftArm.rotationWeight = m_ikInfo.m_armsWeights.y;
|
|
}
|
|
if(!Mathf.Approximately(m_handsWeights.y, 0f))
|
|
{
|
|
m_vrIK.solver.rightArm.target = m_ikInfo.m_rightHandTarget;
|
|
m_vrIK.solver.rightArm.positionWeight = m_ikInfo.m_armsWeights.z;
|
|
m_vrIK.solver.rightArm.rotationWeight = m_ikInfo.m_armsWeights.w;
|
|
}
|
|
}
|
|
|
|
// Settings
|
|
void OnEnabledChanged(bool p_state)
|
|
{
|
|
if(p_state)
|
|
{
|
|
if(this.enabled)
|
|
{
|
|
if(m_disableTask != null)
|
|
{
|
|
StopCoroutine(m_disableTask);
|
|
m_disableTask = null;
|
|
}
|
|
}
|
|
else
|
|
this.enabled = true;
|
|
|
|
OnLeadingHandChanged(Settings.LeadingHand);
|
|
}
|
|
else
|
|
{
|
|
m_leftHandState = HandState.Empty;
|
|
m_rightHandState = HandState.Empty;
|
|
|
|
m_disableTask = StartCoroutine(WaitToDisable());
|
|
}
|
|
}
|
|
|
|
void OnGrabOffsetChanged(float p_value)
|
|
{
|
|
if(m_leftRotationTarget != null)
|
|
m_leftRotationTarget.localPosition = new Vector3(-m_armsLength.z * p_value * 2f, 0f, 0f);
|
|
if(m_rightRotationTarget != null)
|
|
m_rightRotationTarget.localPosition = new Vector3(m_armsLength.w * p_value * 2f, 0f, 0f);
|
|
}
|
|
|
|
void OnLeadingHandChanged(Settings.LeadHand p_hand)
|
|
{
|
|
SetLeadingHandState((m_pickup != null) ? HandState.Pickup : HandState.Empty);
|
|
SetUnleadingHandState(HandState.Empty);
|
|
}
|
|
|
|
void OnHandsExtensionChanged(bool p_state)
|
|
{
|
|
if(m_leftHandState == HandState.Extended)
|
|
m_leftHandState = HandState.Empty;
|
|
if(m_rightHandState == HandState.Extended)
|
|
m_rightHandState = HandState.Empty;
|
|
}
|
|
|
|
// Game events
|
|
void OnAvatarClear()
|
|
{
|
|
m_vrIK = null;
|
|
m_armIKLeft = null;
|
|
m_armIKRight = null;
|
|
m_armsLength.Set(0f, 0f, 0f, 0f);
|
|
m_leftHandParameter = null;
|
|
m_rightHandParameter = null;
|
|
}
|
|
|
|
void OnAvatarSetup()
|
|
{
|
|
m_camera = PlayerSetup.Instance.GetActiveCamera().transform;
|
|
|
|
if(PlayerSetup.Instance._animator.isHuman)
|
|
{
|
|
m_vrIK = PlayerSetup.Instance._animator.GetComponent<VRIK>();
|
|
Utils.SetAvatarTPose();
|
|
|
|
Animator l_animator = PlayerSetup.Instance._animator;
|
|
Matrix4x4 l_avatarMatrixInv = l_animator.transform.GetMatrix().inverse; // Animator and avatar are on same game object
|
|
|
|
Transform l_leftHand = l_animator.GetBoneTransform(HumanBodyBones.LeftHand);
|
|
if(l_leftHand != null)
|
|
m_leftRotationTarget.localRotation = ms_offsetLeft * (l_avatarMatrixInv * l_leftHand.GetMatrix()).rotation;
|
|
Transform l_rightHand = l_animator.GetBoneTransform(HumanBodyBones.RightHand);
|
|
if(l_rightHand != null)
|
|
m_rightRotationTarget.localRotation = ms_offsetRight * (l_avatarMatrixInv * l_rightHand.GetMatrix()).rotation;
|
|
|
|
m_armsLength.x = GetChainLength(new Transform[]{
|
|
l_animator.GetBoneTransform(HumanBodyBones.LeftUpperArm),
|
|
l_animator.GetBoneTransform(HumanBodyBones.LeftLowerArm),
|
|
l_animator.GetBoneTransform(HumanBodyBones.LeftHand)
|
|
});
|
|
m_armsLength.y = GetChainLength(new Transform[]{
|
|
l_animator.GetBoneTransform(HumanBodyBones.RightUpperArm),
|
|
l_animator.GetBoneTransform(HumanBodyBones.RightLowerArm),
|
|
l_animator.GetBoneTransform(HumanBodyBones.RightHand)
|
|
});
|
|
m_armsLength.z = Mathf.Abs((l_avatarMatrixInv * l_animator.GetBoneTransform(HumanBodyBones.LeftUpperArm).GetMatrix()).GetPosition().x);
|
|
m_armsLength.w = Mathf.Abs((l_avatarMatrixInv * l_animator.GetBoneTransform(HumanBodyBones.RightUpperArm).GetMatrix()).GetPosition().x);
|
|
|
|
if(!Utils.IsInVR())
|
|
{
|
|
if(m_vrIK != null)
|
|
{
|
|
m_vrIK.onPreSolverUpdate.AddListener(this.OnIKPreUpdate);
|
|
m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate);
|
|
}
|
|
else
|
|
SetupArmIK();
|
|
}
|
|
}
|
|
|
|
m_leftHandParameter = new AvatarBoolParameter("LeftHandExtended", PlayerSetup.Instance.animatorManager);
|
|
m_rightHandParameter = new AvatarBoolParameter("RightHandExtended", PlayerSetup.Instance.animatorManager);
|
|
|
|
OnEnabledChanged(Settings.Enabled);
|
|
OnGrabOffsetChanged(Settings.GrabOffset);
|
|
OnIKScaling(1f); // Reset scaling, game doesn't do this anymore on avatar switch
|
|
}
|
|
|
|
void OnAvatarReuse()
|
|
{
|
|
// Old VRIK is destroyed by game
|
|
m_vrIK = PlayerSetup.Instance._animator.GetComponent<VRIK>();
|
|
|
|
if(Utils.IsInVR())
|
|
RemoveArmIK();
|
|
else
|
|
{
|
|
if(m_vrIK != null)
|
|
{
|
|
m_vrIK.onPreSolverUpdate.AddListener(this.OnIKPreUpdate);
|
|
m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate);
|
|
}
|
|
else
|
|
SetupArmIK();
|
|
}
|
|
|
|
OnEnabledChanged(Settings.Enabled);
|
|
}
|
|
|
|
void OnPickupGrab(CVRPickupObject p_pickup, Vector3 p_hit)
|
|
{
|
|
if(p_pickup.IsGrabbedByMe && (p_pickup.ControllerRay == ViewManager.Instance.desktopControllerRay))
|
|
{
|
|
m_pickup = p_pickup;
|
|
|
|
// Set offsets
|
|
if(m_pickup.gripType == CVRPickupObject.GripType.Origin)
|
|
{
|
|
if(m_pickup.ikReference != null)
|
|
m_offset = (m_pickup.transform.GetMatrix().inverse * m_pickup.ikReference.GetMatrix());
|
|
else
|
|
{
|
|
if(m_pickup.gripOrigin != null)
|
|
m_offset = m_pickup.transform.GetMatrix().inverse * m_pickup.gripOrigin.GetMatrix();
|
|
}
|
|
}
|
|
else
|
|
m_offset = m_pickup.transform.GetMatrix().inverse * Matrix4x4.TRS(p_hit, m_camera.rotation, Vector3.one);
|
|
|
|
if(Settings.Enabled)
|
|
OnLeadingHandChanged(Settings.LeadingHand);
|
|
}
|
|
}
|
|
|
|
void OnPickupDrop(CVRPickupObject p_pickup)
|
|
{
|
|
if(ReferenceEquals(m_pickup, p_pickup) || (m_pickup == p_pickup))
|
|
{
|
|
m_pickup = null;
|
|
|
|
if(Settings.Enabled)
|
|
SetLeadingHandState(HandState.Empty);
|
|
}
|
|
}
|
|
|
|
void OnIKScaling(float p_relation)
|
|
{
|
|
if(m_root != null)
|
|
m_root.localScale = Vector3.one * p_relation;
|
|
}
|
|
|
|
void OnVRModeSwitch(bool p_state)
|
|
{
|
|
try
|
|
{
|
|
m_camera = PlayerSetup.Instance.GetActiveCamera().transform;
|
|
this.enabled = !Utils.IsInVR();
|
|
}
|
|
catch(System.Exception e)
|
|
{
|
|
MelonLoader.MelonLogger.Error(e);
|
|
}
|
|
}
|
|
|
|
// Arbitrary
|
|
void SetupArmIK()
|
|
{
|
|
Animator l_animator = PlayerSetup.Instance._animator;
|
|
|
|
Transform l_chest = l_animator.GetBoneTransform(HumanBodyBones.UpperChest);
|
|
if(l_chest == null)
|
|
l_chest = l_animator.GetBoneTransform(HumanBodyBones.Chest);
|
|
if(l_chest == null)
|
|
l_chest = l_animator.GetBoneTransform(HumanBodyBones.Spine);
|
|
|
|
m_armIKLeft = PlayerSetup.Instance._avatar.AddComponent<ArmIK>();
|
|
m_armIKLeft.solver.isLeft = true;
|
|
m_armIKLeft.solver.SetChain(
|
|
l_chest,
|
|
l_animator.GetBoneTransform(HumanBodyBones.LeftShoulder),
|
|
l_animator.GetBoneTransform(HumanBodyBones.LeftUpperArm),
|
|
l_animator.GetBoneTransform(HumanBodyBones.LeftLowerArm),
|
|
l_animator.GetBoneTransform(HumanBodyBones.LeftHand),
|
|
l_animator.transform
|
|
);
|
|
m_armIKLeft.solver.arm.target = m_leftRotationTarget;
|
|
m_armIKLeft.solver.arm.positionWeight = 1f;
|
|
m_armIKLeft.solver.arm.rotationWeight = 1f;
|
|
m_armIKLeft.solver.IKPositionWeight = 0f;
|
|
m_armIKLeft.solver.IKRotationWeight = 0f;
|
|
m_armIKLeft.enabled = false;
|
|
|
|
m_armIKRight = PlayerSetup.Instance._avatar.AddComponent<ArmIK>();
|
|
m_armIKRight.solver.isLeft = false;
|
|
m_armIKRight.solver.SetChain(
|
|
l_chest,
|
|
l_animator.GetBoneTransform(HumanBodyBones.RightShoulder),
|
|
l_animator.GetBoneTransform(HumanBodyBones.RightUpperArm),
|
|
l_animator.GetBoneTransform(HumanBodyBones.RightLowerArm),
|
|
l_animator.GetBoneTransform(HumanBodyBones.RightHand),
|
|
l_animator.transform
|
|
);
|
|
m_armIKRight.solver.arm.target = m_rightRotationTarget;
|
|
m_armIKRight.solver.arm.positionWeight = 1f;
|
|
m_armIKRight.solver.arm.rotationWeight = 1f;
|
|
m_armIKRight.solver.IKPositionWeight = 0f;
|
|
m_armIKRight.solver.IKRotationWeight = 0f;
|
|
m_armIKRight.enabled = false;
|
|
}
|
|
|
|
void RemoveArmIK()
|
|
{
|
|
if(m_armIKLeft != null)
|
|
Object.Destroy(m_armIKLeft);
|
|
m_armIKLeft = null;
|
|
|
|
if(m_armIKRight != null)
|
|
Object.Destroy(m_armIKRight);
|
|
m_armIKRight = null;
|
|
}
|
|
|
|
void UpdateArmIK(ArmIK p_ik, float p_weight)
|
|
{
|
|
if(p_ik != null)
|
|
{
|
|
bool l_state = !Mathf.Approximately(p_weight, 0f);
|
|
p_ik.solver.IKPositionWeight = p_weight;
|
|
p_ik.solver.IKRotationWeight = p_weight;
|
|
p_ik.enabled = l_state;
|
|
}
|
|
}
|
|
|
|
void SetLeadingHandState(HandState p_state)
|
|
{
|
|
switch(Settings.LeadingHand)
|
|
{
|
|
case Settings.LeadHand.Left:
|
|
m_leftHandState = p_state;
|
|
break;
|
|
case Settings.LeadHand.Right:
|
|
m_rightHandState = p_state;
|
|
break;
|
|
case Settings.LeadHand.Both:
|
|
{
|
|
m_leftHandState = p_state;
|
|
m_rightHandState = p_state;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
void SetUnleadingHandState(HandState p_state)
|
|
{
|
|
switch(Settings.LeadingHand)
|
|
{
|
|
case Settings.LeadHand.Left:
|
|
m_rightHandState = p_state;
|
|
break;
|
|
case Settings.LeadHand.Right:
|
|
m_leftHandState = p_state;
|
|
break;
|
|
}
|
|
}
|
|
|
|
IEnumerator WaitToDisable()
|
|
{
|
|
while(!Mathf.Approximately(m_handsWeights.x + m_handsWeights.y, 0f))
|
|
yield return null;
|
|
|
|
this.enabled = false;
|
|
m_disableTask = null;
|
|
}
|
|
|
|
static float GetChainLength(Transform[] p_chain)
|
|
{
|
|
float l_result = 0f;
|
|
for(int i = 0, j = p_chain.Length - 1; i < j; i++)
|
|
{
|
|
if((p_chain[i] != null) && (p_chain[i + 1] != null))
|
|
l_result += Vector3.Distance(p_chain[i].position, p_chain[i + 1].position);
|
|
}
|
|
return l_result;
|
|
}
|
|
}
|
|
}
|