mirror of
https://github.com/hanetzer/sdraw_mods_cvr.git
synced 2025-09-03 10:29:22 +00:00
Too many changes
This commit is contained in:
parent
45557943c4
commit
a22e5992d0
72 changed files with 1064 additions and 927 deletions
|
@ -1,7 +1,9 @@
|
|||
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
|
||||
|
@ -22,61 +24,79 @@ namespace ml_pam
|
|||
public Transform m_rightHandTarget;
|
||||
}
|
||||
|
||||
const float c_offsetLimit = 0.5f;
|
||||
const KeyCode c_leftKey = KeyCode.Q;
|
||||
const KeyCode c_rightKey = KeyCode.E;
|
||||
|
||||
static readonly Vector4 ms_pointVector = new Vector4(0f, 0f, 0f, 1f);
|
||||
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);
|
||||
|
||||
bool m_inVR = false;
|
||||
VRIK m_vrIK = null;
|
||||
float m_armLength = 0f;
|
||||
float m_playspaceScale = 1f;
|
||||
Vector4 m_armsLength; // x,y - from upper arm to hand; z,w - from center to upper arm
|
||||
Transform m_camera = null;
|
||||
IKInfo m_ikInfo;
|
||||
|
||||
bool m_enabled = true;
|
||||
IKInfo m_vrIKInfo;
|
||||
Transform m_rootLeft = null;
|
||||
Transform m_rootRight = null;
|
||||
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_inVR = Utils.IsInVR();
|
||||
m_camera = PlayerSetup.Instance.GetActiveCamera().transform;
|
||||
|
||||
m_rootLeft = new GameObject("[ArmPickupLeft]").transform;
|
||||
m_rootLeft.parent = PlayerSetup.Instance.GetActiveCamera().transform;
|
||||
m_rootLeft.localPosition = Vector3.zero;
|
||||
m_rootLeft.localRotation = Quaternion.identity;
|
||||
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("Target").transform;
|
||||
m_leftTarget.parent = m_rootLeft;
|
||||
m_leftTarget.localPosition = new Vector3(c_offsetLimit * -Settings.GrabOffset, 0f, 0f);
|
||||
m_leftTarget = new GameObject("TargetLeft").transform;
|
||||
m_leftTarget.parent = m_root;
|
||||
m_leftTarget.localPosition = Vector3.zero;
|
||||
m_leftTarget.localRotation = Quaternion.identity;
|
||||
|
||||
m_rootRight = new GameObject("[ArmPickupRight]").transform;
|
||||
m_rootRight.parent = PlayerSetup.Instance.GetActiveCamera().transform;
|
||||
m_rootRight.localPosition = Vector3.zero;
|
||||
m_rootRight.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("Target").transform;
|
||||
m_rightTarget.parent = m_rootRight;
|
||||
m_rightTarget.localPosition = new Vector3(c_offsetLimit * Settings.GrabOffset, 0f, 0f);
|
||||
m_rightTarget = new GameObject("TargetRight").transform;
|
||||
m_rightTarget.parent = m_root;
|
||||
m_rightTarget.localPosition = Vector3.zero;
|
||||
m_rightTarget.localRotation = Quaternion.identity;
|
||||
|
||||
m_enabled = Settings.Enabled;
|
||||
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);
|
||||
|
@ -86,25 +106,44 @@ namespace ml_pam
|
|||
GameEvents.OnAvatarClear.AddListener(this.OnAvatarClear);
|
||||
GameEvents.OnAvatarSetup.AddListener(this.OnAvatarSetup);
|
||||
GameEvents.OnAvatarReuse.AddListener(this.OnAvatarReuse);
|
||||
GameEvents.OnPlayspaceScale.AddListener(this.OnPlayspaceScale);
|
||||
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_rootLeft != null)
|
||||
Destroy(m_rootLeft);
|
||||
m_rootLeft = null;
|
||||
if(m_leftRotationTarget != null)
|
||||
Destroy(m_leftRotationTarget.gameObject);
|
||||
m_leftRotationTarget = null;
|
||||
|
||||
if(m_leftTarget != null)
|
||||
Destroy(m_leftTarget.gameObject);
|
||||
m_leftTarget = null;
|
||||
|
||||
if(m_rootRight != null)
|
||||
Destroy(m_rootRight);
|
||||
m_rootRight = 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;
|
||||
|
||||
|
@ -116,13 +155,21 @@ namespace ml_pam
|
|||
GameEvents.OnAvatarClear.RemoveListener(this.OnAvatarClear);
|
||||
GameEvents.OnAvatarSetup.RemoveListener(this.OnAvatarSetup);
|
||||
GameEvents.OnAvatarReuse.RemoveListener(this.OnAvatarReuse);
|
||||
GameEvents.OnPlayspaceScale.RemoveListener(this.OnPlayspaceScale);
|
||||
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);
|
||||
|
||||
|
@ -130,205 +177,170 @@ namespace ml_pam
|
|||
{
|
||||
case HandState.Empty:
|
||||
{
|
||||
if(Settings.HandsExtension && Input.GetKeyDown(c_leftKey))
|
||||
{
|
||||
if(Settings.Enabled && Settings.HandsExtension && Input.GetKey(c_leftKey) && !ViewManager.Instance.IsAnyMenuOpen)
|
||||
m_leftHandState = HandState.Extended;
|
||||
m_rootLeft.localPosition = new Vector3(0f, 0f, m_armLength * m_playspaceScale);
|
||||
SetArmActive(Settings.LeadHand.Left, true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HandState.Extended:
|
||||
{
|
||||
if(Input.GetKeyUp(c_leftKey))
|
||||
{
|
||||
if(!Input.GetKey(c_leftKey))
|
||||
m_leftHandState = HandState.Empty;
|
||||
SetArmActive(Settings.LeadHand.Left, false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HandState.Pickup:
|
||||
{
|
||||
if(m_pickup != null)
|
||||
{
|
||||
Matrix4x4 l_result = m_pickup.transform.GetMatrix() * m_offset;
|
||||
m_rootLeft.position = l_result * ms_pointVector;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch(m_rightHandState)
|
||||
{
|
||||
case HandState.Empty:
|
||||
{
|
||||
if(Settings.HandsExtension && Input.GetKeyDown(c_rightKey))
|
||||
{
|
||||
if(Settings.Enabled && Settings.HandsExtension && Input.GetKey(c_rightKey) && !ViewManager.Instance.IsAnyMenuOpen)
|
||||
m_rightHandState = HandState.Extended;
|
||||
m_rootRight.localPosition = new Vector3(0f, 0f, m_armLength * m_playspaceScale);
|
||||
SetArmActive(Settings.LeadHand.Right, true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HandState.Extended:
|
||||
{
|
||||
if(Input.GetKeyUp(c_rightKey))
|
||||
{
|
||||
if(!Input.GetKey(c_rightKey))
|
||||
m_rightHandState = HandState.Empty;
|
||||
SetArmActive(Settings.LeadHand.Right, false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HandState.Pickup:
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if(m_pickup != null)
|
||||
{
|
||||
Matrix4x4 l_result = m_pickup.transform.GetMatrix() * m_offset;
|
||||
m_rootRight.position = l_result * ms_pointVector;
|
||||
}
|
||||
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);
|
||||
}
|
||||
break;
|
||||
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(m_enabled)
|
||||
if(!Mathf.Approximately(m_handsWeights.x, 0f))
|
||||
{
|
||||
if(m_leftHandState != HandState.Empty)
|
||||
{
|
||||
m_vrIKInfo.m_leftHandTarget = m_vrIK.solver.leftArm.target;
|
||||
m_vrIKInfo.m_armsWeights.x = m_vrIK.solver.leftArm.positionWeight;
|
||||
m_vrIKInfo.m_armsWeights.y = m_vrIK.solver.leftArm.rotationWeight;
|
||||
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 = 1f;
|
||||
m_vrIK.solver.leftArm.rotationWeight = 1f;
|
||||
m_vrIK.solver.leftArm.target = m_leftTarget;
|
||||
}
|
||||
if(m_rightHandState != HandState.Empty)
|
||||
{
|
||||
m_vrIKInfo.m_rightHandTarget = m_vrIK.solver.rightArm.target;
|
||||
m_vrIKInfo.m_armsWeights.z = m_vrIK.solver.rightArm.positionWeight;
|
||||
m_vrIKInfo.m_armsWeights.w = m_vrIK.solver.rightArm.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 = 1f;
|
||||
m_vrIK.solver.rightArm.rotationWeight = 1f;
|
||||
m_vrIK.solver.rightArm.target = m_rightTarget;
|
||||
}
|
||||
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(m_enabled)
|
||||
if(!Mathf.Approximately(m_handsWeights.x, 0f))
|
||||
{
|
||||
if(m_leftHandState != HandState.Empty)
|
||||
{
|
||||
m_vrIK.solver.leftArm.target = m_vrIKInfo.m_leftHandTarget;
|
||||
m_vrIK.solver.leftArm.positionWeight = m_vrIKInfo.m_armsWeights.x;
|
||||
m_vrIK.solver.leftArm.rotationWeight = m_vrIKInfo.m_armsWeights.y;
|
||||
}
|
||||
if(m_rightHandState != HandState.Empty)
|
||||
{
|
||||
m_vrIK.solver.rightArm.target = m_vrIKInfo.m_rightHandTarget;
|
||||
m_vrIK.solver.rightArm.positionWeight = m_vrIKInfo.m_armsWeights.z;
|
||||
m_vrIK.solver.rightArm.rotationWeight = m_vrIKInfo.m_armsWeights.w;
|
||||
}
|
||||
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)
|
||||
{
|
||||
m_enabled = p_state;
|
||||
|
||||
if(p_state)
|
||||
{
|
||||
if(m_leftHandState != HandState.Empty)
|
||||
SetArmActive(Settings.LeadHand.Left, true);
|
||||
if(m_rightHandState != HandState.Empty)
|
||||
SetArmActive(Settings.LeadHand.Right, true);
|
||||
if(this.enabled)
|
||||
{
|
||||
if(m_disableTask != null)
|
||||
{
|
||||
StopCoroutine(m_disableTask);
|
||||
m_disableTask = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
this.enabled = true;
|
||||
|
||||
OnHandsExtensionChanged(Settings.HandsExtension);
|
||||
OnLeadingHandChanged(Settings.LeadingHand);
|
||||
}
|
||||
else
|
||||
SetArmActive(Settings.LeadHand.Both, false, true);
|
||||
{
|
||||
m_leftHandState = HandState.Empty;
|
||||
m_rightHandState = HandState.Empty;
|
||||
|
||||
m_disableTask = StartCoroutine(WaitToDisable());
|
||||
}
|
||||
}
|
||||
|
||||
void OnGrabOffsetChanged(float p_value)
|
||||
{
|
||||
if(m_leftTarget != null)
|
||||
m_leftTarget.localPosition = new Vector3(c_offsetLimit * m_playspaceScale * -p_value, 0f, 0f);
|
||||
if(m_rightTarget != null)
|
||||
m_rightTarget.localPosition = new Vector3(c_offsetLimit * m_playspaceScale * p_value, 0f, 0f);
|
||||
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)
|
||||
{
|
||||
if(m_pickup != null)
|
||||
{
|
||||
if(m_leftHandState == HandState.Pickup)
|
||||
{
|
||||
m_leftHandState = HandState.Empty;
|
||||
SetArmActive(Settings.LeadHand.Left, false);
|
||||
}
|
||||
if(m_rightHandState == HandState.Pickup)
|
||||
{
|
||||
m_rightHandState = HandState.Empty;
|
||||
SetArmActive(Settings.LeadHand.Right, false);
|
||||
}
|
||||
|
||||
switch(p_hand)
|
||||
{
|
||||
case Settings.LeadHand.Left:
|
||||
m_leftHandState = HandState.Pickup;
|
||||
break;
|
||||
case Settings.LeadHand.Right:
|
||||
m_rightHandState = HandState.Pickup;
|
||||
break;
|
||||
case Settings.LeadHand.Both:
|
||||
{
|
||||
m_leftHandState = HandState.Pickup;
|
||||
m_rightHandState = HandState.Pickup;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
SetArmActive(p_hand, true);
|
||||
}
|
||||
SetLeadingHandState((m_pickup != null) ? HandState.Pickup : HandState.Empty);
|
||||
SetUnleadingHandState(HandState.Empty);
|
||||
}
|
||||
|
||||
void OnHandsExtensionChanged(bool p_state)
|
||||
{
|
||||
if(m_enabled)
|
||||
{
|
||||
if(p_state)
|
||||
{
|
||||
if((m_leftHandState == HandState.Empty) && Input.GetKey(c_leftKey))
|
||||
{
|
||||
m_leftHandState = HandState.Extended;
|
||||
SetArmActive(Settings.LeadHand.Left, true);
|
||||
}
|
||||
if((m_rightHandState == HandState.Empty) && Input.GetKey(c_rightKey))
|
||||
{
|
||||
m_rightHandState = HandState.Extended;
|
||||
SetArmActive(Settings.LeadHand.Right, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_leftHandState == HandState.Extended)
|
||||
{
|
||||
m_leftHandState = HandState.Empty;
|
||||
SetArmActive(Settings.LeadHand.Left, false);
|
||||
}
|
||||
if(m_rightHandState == HandState.Extended)
|
||||
{
|
||||
m_rightHandState = HandState.Empty;
|
||||
SetArmActive(Settings.LeadHand.Right, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(m_leftHandState == HandState.Extended)
|
||||
m_leftHandState = HandState.Empty;
|
||||
if(m_rightHandState == HandState.Extended)
|
||||
m_rightHandState = HandState.Empty;
|
||||
}
|
||||
|
||||
// Game events
|
||||
|
@ -337,65 +349,81 @@ namespace ml_pam
|
|||
m_vrIK = null;
|
||||
m_armIKLeft = null;
|
||||
m_armIKRight = null;
|
||||
m_armLength = 0f;
|
||||
m_armsLength.Set(0f, 0f, 0f, 0f);
|
||||
m_leftHandParameter = null;
|
||||
m_rightHandParameter = null;
|
||||
}
|
||||
|
||||
void OnAvatarSetup()
|
||||
{
|
||||
m_inVR = Utils.IsInVR();
|
||||
m_vrIK = PlayerSetup.Instance._animator.GetComponent<VRIK>();
|
||||
|
||||
ReparentRoots();
|
||||
m_camera = PlayerSetup.Instance.GetActiveCamera().transform;
|
||||
|
||||
if(PlayerSetup.Instance._animator.isHuman)
|
||||
{
|
||||
m_vrIK = PlayerSetup.Instance._animator.GetComponent<VRIK>();
|
||||
Utils.SetAvatarTPose();
|
||||
|
||||
Transform l_leftHand = PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.LeftHand);
|
||||
if(l_leftHand != null)
|
||||
m_leftTarget.localRotation = ms_offsetLeft * (PlayerSetup.Instance._avatar.transform.GetMatrix().inverse * l_leftHand.GetMatrix()).rotation;
|
||||
Transform l_rightHand = PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.RightHand);
|
||||
if(l_rightHand != null)
|
||||
m_rightTarget.localRotation = ms_offsetRight * (PlayerSetup.Instance._avatar.transform.GetMatrix().inverse * l_rightHand.GetMatrix()).rotation;
|
||||
Animator l_animator = PlayerSetup.Instance._animator;
|
||||
Matrix4x4 l_avatarMatrixInv = l_animator.transform.GetMatrix().inverse; // Animator and avatar are on same game object
|
||||
|
||||
if(m_vrIK != null)
|
||||
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())
|
||||
{
|
||||
m_armLength = m_vrIK.solver.leftArm.mag * 1.25f;
|
||||
m_vrIK.onPreSolverUpdate.AddListener(this.OnIKPreUpdate);
|
||||
m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate);
|
||||
if(m_vrIK != null)
|
||||
{
|
||||
m_vrIK.onPreSolverUpdate.AddListener(this.OnIKPreUpdate);
|
||||
m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate);
|
||||
}
|
||||
else
|
||||
SetupArmIK();
|
||||
}
|
||||
else if(!m_inVR)
|
||||
SetupArmIK();
|
||||
}
|
||||
|
||||
m_leftHandParameter = new AvatarBoolParameter("LeftHandExtended", PlayerSetup.Instance.animatorManager);
|
||||
m_rightHandParameter = new AvatarBoolParameter("RightHandExtended", PlayerSetup.Instance.animatorManager);
|
||||
|
||||
OnEnabledChanged(m_enabled);
|
||||
OnEnabledChanged(Settings.Enabled);
|
||||
OnGrabOffsetChanged(Settings.GrabOffset);
|
||||
}
|
||||
|
||||
void OnAvatarReuse()
|
||||
{
|
||||
// Old VRIK is destroyed by game
|
||||
m_inVR = Utils.IsInVR();
|
||||
m_vrIK = PlayerSetup.Instance._animator.GetComponent<VRIK>();
|
||||
|
||||
ReparentRoots();
|
||||
|
||||
if(m_inVR)
|
||||
if(Utils.IsInVR())
|
||||
RemoveArmIK();
|
||||
|
||||
if(m_vrIK != null)
|
||||
else
|
||||
{
|
||||
m_vrIK.onPreSolverUpdate.AddListener(this.OnIKPreUpdate);
|
||||
m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate);
|
||||
if(m_vrIK != null)
|
||||
{
|
||||
m_vrIK.onPreSolverUpdate.AddListener(this.OnIKPreUpdate);
|
||||
m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate);
|
||||
}
|
||||
else
|
||||
SetupArmIK();
|
||||
}
|
||||
else if(!m_inVR)
|
||||
SetupArmIK();
|
||||
|
||||
OnEnabledChanged(m_enabled);
|
||||
OnEnabledChanged(Settings.Enabled);
|
||||
}
|
||||
|
||||
void OnPickupGrab(CVRPickupObject p_pickup, Vector3 p_hit)
|
||||
|
@ -416,97 +444,82 @@ namespace ml_pam
|
|||
}
|
||||
}
|
||||
else
|
||||
m_offset = m_pickup.transform.GetMatrix().inverse * Matrix4x4.Translate(p_hit);
|
||||
m_offset = m_pickup.transform.GetMatrix().inverse * Matrix4x4.TRS(p_hit, m_camera.rotation, Vector3.one);
|
||||
|
||||
switch(Settings.LeadingHand)
|
||||
{
|
||||
case Settings.LeadHand.Left:
|
||||
m_leftHandState = HandState.Pickup;
|
||||
break;
|
||||
case Settings.LeadHand.Right:
|
||||
m_rightHandState = HandState.Pickup;
|
||||
break;
|
||||
case Settings.LeadHand.Both:
|
||||
{
|
||||
m_leftHandState = HandState.Pickup;
|
||||
m_rightHandState = HandState.Pickup;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
SetArmActive(Settings.LeadingHand, true);
|
||||
if(Settings.Enabled)
|
||||
OnLeadingHandChanged(Settings.LeadingHand);
|
||||
}
|
||||
}
|
||||
|
||||
void OnPickupDrop(CVRPickupObject p_pickup)
|
||||
{
|
||||
if(m_pickup == p_pickup)
|
||||
if(ReferenceEquals(m_pickup, p_pickup) || (m_pickup == p_pickup))
|
||||
{
|
||||
m_pickup = null;
|
||||
switch(Settings.LeadingHand)
|
||||
{
|
||||
case Settings.LeadHand.Left:
|
||||
m_leftHandState = HandState.Empty;
|
||||
break;
|
||||
case Settings.LeadHand.Right:
|
||||
m_rightHandState = HandState.Empty;
|
||||
break;
|
||||
case Settings.LeadHand.Both:
|
||||
{
|
||||
m_leftHandState = HandState.Empty;
|
||||
m_rightHandState = HandState.Empty;
|
||||
}
|
||||
break;
|
||||
}
|
||||
SetArmActive(Settings.LeadingHand, false);
|
||||
|
||||
if(Settings.Enabled)
|
||||
SetLeadingHandState(HandState.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
void OnPlayspaceScale(float p_relation)
|
||||
void OnIKScaling(float p_relation)
|
||||
{
|
||||
m_playspaceScale = p_relation;
|
||||
OnGrabOffsetChanged(Settings.GrabOffset);
|
||||
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()
|
||||
{
|
||||
Transform l_chest = PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.UpperChest);
|
||||
Animator l_animator = PlayerSetup.Instance._animator;
|
||||
|
||||
Transform l_chest = l_animator.GetBoneTransform(HumanBodyBones.UpperChest);
|
||||
if(l_chest == null)
|
||||
l_chest = PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.Chest);
|
||||
l_chest = l_animator.GetBoneTransform(HumanBodyBones.Chest);
|
||||
if(l_chest == null)
|
||||
l_chest = PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.Spine);
|
||||
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,
|
||||
PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.LeftShoulder),
|
||||
PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.LeftUpperArm),
|
||||
PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.LeftLowerArm),
|
||||
PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.LeftHand),
|
||||
PlayerSetup.Instance._animator.transform
|
||||
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_leftTarget;
|
||||
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_armLength = m_armIKLeft.solver.arm.mag * 1.25f;
|
||||
|
||||
m_armIKRight = PlayerSetup.Instance._avatar.AddComponent<ArmIK>();
|
||||
m_armIKRight.solver.isLeft = false;
|
||||
m_armIKRight.solver.SetChain(
|
||||
l_chest,
|
||||
PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.RightShoulder),
|
||||
PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.RightUpperArm),
|
||||
PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.RightLowerArm),
|
||||
PlayerSetup.Instance._animator.GetBoneTransform(HumanBodyBones.RightHand),
|
||||
PlayerSetup.Instance._animator.transform
|
||||
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_rightTarget;
|
||||
m_armIKRight.solver.arm.target = m_rightRotationTarget;
|
||||
m_armIKRight.solver.arm.positionWeight = 1f;
|
||||
m_armIKRight.solver.arm.rotationWeight = 1f;
|
||||
m_armIKRight.solver.IKPositionWeight = 0f;
|
||||
|
@ -525,39 +538,66 @@ namespace ml_pam
|
|||
m_armIKRight = null;
|
||||
}
|
||||
|
||||
void SetArmActive(Settings.LeadHand p_hand, bool p_state, bool p_forced = false)
|
||||
void UpdateArmIK(ArmIK p_ik, float p_weight)
|
||||
{
|
||||
if(m_enabled || p_forced)
|
||||
if(p_ik != null)
|
||||
{
|
||||
if(((p_hand == Settings.LeadHand.Left) || (p_hand == Settings.LeadHand.Both)) && (m_armIKLeft != null))
|
||||
{
|
||||
m_armIKLeft.enabled = m_enabled;
|
||||
m_armIKLeft.solver.IKPositionWeight = (p_state ? 1f : 0f);
|
||||
m_armIKLeft.solver.IKRotationWeight = (p_state ? 1f : 0f);
|
||||
}
|
||||
if(((p_hand == Settings.LeadHand.Right) || (p_hand == Settings.LeadHand.Both)) && (m_armIKRight != null))
|
||||
{
|
||||
m_armIKRight.enabled = m_enabled;
|
||||
m_armIKRight.solver.IKPositionWeight = (p_state ? 1f : 0f);
|
||||
m_armIKRight.solver.IKRotationWeight = (p_state ? 1f : 0f);
|
||||
}
|
||||
|
||||
if((p_hand == Settings.LeadHand.Left) || (p_hand == Settings.LeadHand.Both))
|
||||
m_leftHandParameter?.SetValue(p_state);
|
||||
if((p_hand == Settings.LeadHand.Right) || (p_hand == Settings.LeadHand.Both))
|
||||
m_rightHandParameter?.SetValue(p_state);
|
||||
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 ReparentRoots()
|
||||
void SetLeadingHandState(HandState p_state)
|
||||
{
|
||||
m_rootLeft.parent = PlayerSetup.Instance.GetActiveCamera().transform;
|
||||
m_rootLeft.localPosition = Vector3.zero;
|
||||
m_rootLeft.localRotation = Quaternion.identity;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
m_rootRight.parent = PlayerSetup.Instance.GetActiveCamera().transform;
|
||||
m_rootRight.localPosition = Vector3.zero;
|
||||
m_rootRight.localRotation = Quaternion.identity;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace ml_pam
|
|||
public static readonly GameEvent OnAvatarSetup = new GameEvent();
|
||||
public static readonly GameEvent OnAvatarClear = new GameEvent();
|
||||
public static readonly GameEvent OnAvatarReuse = new GameEvent();
|
||||
public static readonly GameEvent<float> OnPlayspaceScale = new GameEvent<float>();
|
||||
public static readonly GameEvent<float> OnIKScaling = new GameEvent<float>();
|
||||
public static readonly GameEvent<CVRPickupObject, Vector3> OnPickupGrab = new GameEvent<CVRPickupObject, Vector3>();
|
||||
public static readonly GameEvent<CVRPickupObject> OnPickupDrop = new GameEvent<CVRPickupObject>();
|
||||
|
||||
|
@ -61,9 +61,9 @@ namespace ml_pam
|
|||
);
|
||||
|
||||
p_instance.Patch(
|
||||
typeof(PlayerSetup).GetMethod("SetPlaySpaceScale", BindingFlags.NonPublic | BindingFlags.Instance),
|
||||
typeof(PlayerSetup).GetMethod("SetupIKScaling", BindingFlags.NonPublic | BindingFlags.Instance),
|
||||
null,
|
||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnPlayspaceScale_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnSetupIKScaling_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
||||
);
|
||||
|
||||
p_instance.Patch(
|
||||
|
@ -120,11 +120,11 @@ namespace ml_pam
|
|||
}
|
||||
}
|
||||
|
||||
static void OnPlayspaceScale_Postfix(float ____avatarScaleRelation)
|
||||
static void OnSetupIKScaling_Postfix(ref UnityEngine.Vector3 ___scaleDifference)
|
||||
{
|
||||
try
|
||||
{
|
||||
OnPlayspaceScale.Invoke(____avatarScaleRelation);
|
||||
OnIKScaling.Invoke(1f + ___scaleDifference.y);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
|
|
|
@ -1,32 +1,34 @@
|
|||
using ABI_RC.Core.Player;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ml_pam
|
||||
{
|
||||
public class PickupArmMovement : MelonLoader.MelonMod
|
||||
{
|
||||
ArmMover m_localMover = null;
|
||||
ArmMover m_mover = null;
|
||||
|
||||
public override void OnInitializeMelon()
|
||||
{
|
||||
Settings.Init();
|
||||
GameEvents.Init(HarmonyInstance);
|
||||
|
||||
MelonLoader.MelonCoroutines.Start(WaitForLocalPlayer());
|
||||
MelonLoader.MelonCoroutines.Start(WaitForRootLogic());
|
||||
}
|
||||
|
||||
System.Collections.IEnumerator WaitForLocalPlayer()
|
||||
System.Collections.IEnumerator WaitForRootLogic()
|
||||
{
|
||||
while(PlayerSetup.Instance == null)
|
||||
while(ABI_RC.Core.RootLogic.Instance == null)
|
||||
yield return null;
|
||||
while(ABI_RC.Core.Player.PlayerSetup.Instance == null)
|
||||
yield return null;
|
||||
|
||||
m_localMover = PlayerSetup.Instance.gameObject.AddComponent<ArmMover>();
|
||||
m_mover = new GameObject("[PickupArmMovement]").AddComponent<ArmMover>();
|
||||
}
|
||||
|
||||
public override void OnDeinitializeMelon()
|
||||
{
|
||||
if(m_localMover != null)
|
||||
UnityEngine.Object.Destroy(m_localMover);
|
||||
m_localMover = null;
|
||||
if(m_mover != null)
|
||||
Object.Destroy(m_mover.gameObject);
|
||||
m_mover = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[assembly: MelonLoader.MelonInfo(typeof(ml_pam.PickupArmMovement), "PickupArmMovement", "1.1.4", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
||||
[assembly: MelonLoader.MelonInfo(typeof(ml_pam.PickupArmMovement), "PickupArmMovement", "1.2.0", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
||||
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
||||
[assembly: MelonLoader.MelonPriority(1)]
|
||||
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||
|
|
|
@ -4,14 +4,15 @@ This mod adds arm tracking upon holding pickup in desktop mode.
|
|||
# Installation
|
||||
* Install [latest MelonLoader](https://github.com/LavaGang/MelonLoader)
|
||||
* Get [latest release DLL](../../../releases/latest):
|
||||
* Put `ml_pam.dll` in `Mods` folder of game
|
||||
* Put `PickupArmMovement.dll` in `Mods` folder of game
|
||||
|
||||
# Usage
|
||||
Available mod's settings in `Settings - Interactions - Pickup Arm Movement`:
|
||||
Available mod's settings in `Settings - Input & Key-Bindings - Pickup Arm Movement`:
|
||||
* **Enable hand movement:** enables/disables arm tracking; default value - `true`.
|
||||
* **Grab offset:** offset from pickup grab point; default value - `25`.
|
||||
* **Leading hand:** hand that will be extended when gragging pickup; available values: `Left`, `Right`, `Both`; default value - `Right`.
|
||||
* **Hands extension (Q\E):** extend left and right hand if `Q` and `E` keys are pressed; default value - `true`.
|
||||
* **Hand extension speed::** smoothing speed multiplier between extended and animated hands; default value - `25`.
|
||||
|
||||
Available animator boolean parameters:
|
||||
* **LeftHandExtended:`` indicates if left hand is extended.
|
||||
|
|
|
@ -6,15 +6,16 @@ namespace ml_pam
|
|||
{
|
||||
static class ResourcesHandler
|
||||
{
|
||||
readonly static string ms_namespace = typeof(ResourcesHandler).Namespace;
|
||||
|
||||
public static string GetEmbeddedResources(string p_name)
|
||||
{
|
||||
string l_result = "";
|
||||
Assembly l_assembly = Assembly.GetExecutingAssembly();
|
||||
string l_assemblyName = l_assembly.GetName().Name;
|
||||
|
||||
try
|
||||
{
|
||||
Stream l_libraryStream = l_assembly.GetManifestResourceStream(l_assemblyName + ".resources." + p_name);
|
||||
Stream l_libraryStream = l_assembly.GetManifestResourceStream(ms_namespace + ".resources." + p_name);
|
||||
StreamReader l_streadReader = new StreamReader(l_libraryStream);
|
||||
l_result = l_streadReader.ReadToEnd();
|
||||
}
|
||||
|
|
|
@ -19,7 +19,8 @@ namespace ml_pam
|
|||
Enabled = 0,
|
||||
GrabOffset,
|
||||
LeadHand,
|
||||
HandsExtension
|
||||
HandsExtension,
|
||||
ExtensionSpeed
|
||||
}
|
||||
public enum LeadHand
|
||||
{
|
||||
|
@ -29,9 +30,10 @@ namespace ml_pam
|
|||
}
|
||||
|
||||
public static bool Enabled { get; private set; } = true;
|
||||
public static float GrabOffset { get; private set; } = 0.25f;
|
||||
public static float GrabOffset { get; private set; } = 0.5f;
|
||||
public static LeadHand LeadingHand { get; private set; } = LeadHand.Right;
|
||||
public static bool HandsExtension { get; private set; } = true;
|
||||
public static float ExtensionSpeed { get; private set; } = 10f;
|
||||
|
||||
static MelonLoader.MelonPreferences_Category ms_category = null;
|
||||
static List<MelonLoader.MelonPreferences_Entry> ms_entries = null;
|
||||
|
@ -40,6 +42,7 @@ namespace ml_pam
|
|||
public static readonly SettingEvent<float> OnGrabOffsetChanged = new SettingEvent<float>();
|
||||
public static readonly SettingEvent<LeadHand> OnLeadingHandChanged = new SettingEvent<LeadHand>();
|
||||
public static readonly SettingEvent<bool> OnHandsExtensionChanged = new SettingEvent<bool>();
|
||||
public static readonly SettingEvent<float> OnExtensionSpeedChanged = new SettingEvent<float>();
|
||||
|
||||
internal static void Init()
|
||||
{
|
||||
|
@ -51,12 +54,14 @@ namespace ml_pam
|
|||
ms_category.CreateEntry(ModSetting.GrabOffset.ToString(), (int)(GrabOffset * 100f)),
|
||||
ms_category.CreateEntry(ModSetting.LeadHand.ToString(), (int)LeadHand.Right),
|
||||
ms_category.CreateEntry(ModSetting.HandsExtension.ToString(), HandsExtension),
|
||||
ms_category.CreateEntry(ModSetting.ExtensionSpeed.ToString(), (int)ExtensionSpeed),
|
||||
};
|
||||
|
||||
Enabled = (bool)ms_entries[(int)ModSetting.Enabled].BoxedValue;
|
||||
GrabOffset = (int)ms_entries[(int)ModSetting.GrabOffset].BoxedValue * 0.01f;
|
||||
LeadingHand = (LeadHand)(int)ms_entries[(int)ModSetting.LeadHand].BoxedValue;
|
||||
HandsExtension = (bool)ms_entries[(int)ModSetting.HandsExtension].BoxedValue;
|
||||
ExtensionSpeed = Math.Clamp((int)ms_entries[(int)ModSetting.ExtensionSpeed].BoxedValue, 1f, 50f);
|
||||
|
||||
MelonLoader.MelonCoroutines.Start(WaitMainMenuUi());
|
||||
}
|
||||
|
@ -72,6 +77,7 @@ namespace ml_pam
|
|||
|
||||
ViewManager.Instance.gameMenuView.Listener.ReadyForBindings += () =>
|
||||
{
|
||||
|
||||
ViewManager.Instance.gameMenuView.View.BindCall("OnToggleUpdate_" + ms_category.Identifier, new Action<string, string>(OnToggleUpdate));
|
||||
ViewManager.Instance.gameMenuView.View.BindCall("OnSliderUpdate_" + ms_category.Identifier, new Action<string, string>(OnSliderUpdate));
|
||||
ViewManager.Instance.gameMenuView.View.BindCall("OnDropdownUpdate_" + ms_category.Identifier, new Action<string, string>(OnDropdownUpdate));
|
||||
|
@ -131,6 +137,13 @@ namespace ml_pam
|
|||
OnGrabOffsetChanged.Invoke(GrabOffset);
|
||||
}
|
||||
break;
|
||||
|
||||
case ModSetting.ExtensionSpeed:
|
||||
{
|
||||
ExtensionSpeed = l_value;
|
||||
OnExtensionSpeedChanged.Invoke(ExtensionSpeed);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ms_entries[(int)l_setting].BoxedValue = l_value;
|
||||
|
|
|
@ -4,10 +4,11 @@
|
|||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<Platforms>x64</Platforms>
|
||||
<PackageId>PickupArmMovement</PackageId>
|
||||
<Version>1.1.4</Version>
|
||||
<Version>1.2.0</Version>
|
||||
<Authors>SDraw</Authors>
|
||||
<Company>None</Company>
|
||||
<Company>SDraw</Company>
|
||||
<Product>PickupArmMovement</Product>
|
||||
<AssemblyName>PickupArmMovement</AssemblyName>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<div class ="row-wrapper">
|
||||
<div class ="option-caption">Grab offset: </div>
|
||||
<div class ="option-input">
|
||||
<div id="GrabOffset" class ="inp_slider no-scroll" data-min="0" data-max="100" data-current="25"></div>
|
||||
<div id="GrabOffset" class ="inp_slider no-scroll" data-min="0" data-max="100" data-current="50"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -33,8 +33,15 @@
|
|||
<div id="HandsExtension" class ="inp_toggle no-scroll" data-current="true"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class ="row-wrapper">
|
||||
<div class ="option-caption">Hand extension speed: </div>
|
||||
<div class ="option-input">
|
||||
<div id="ExtensionSpeed" class ="inp_slider no-scroll" data-min="1" data-max="50" data-current="10"></div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
document.getElementById('settings-interaction').appendChild(l_block);
|
||||
document.getElementById('settings-input').appendChild(l_block);
|
||||
|
||||
// Toggles
|
||||
for (let l_toggle of l_block.querySelectorAll('.inp_toggle'))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue