mirror of
https://github.com/hanetzer/sdraw_mods_cvr.git
synced 2025-09-03 18:39:23 +00:00
Additional nightly fixes
This commit is contained in:
parent
40b683d33c
commit
5261203833
16 changed files with 570 additions and 750 deletions
|
@ -15,8 +15,6 @@ namespace ml_amt
|
||||||
public void Invoke() => m_action?.Invoke();
|
public void Invoke() => m_action?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
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 OnAvatarReuse = new GameEvent();
|
||||||
public static readonly GameEvent OnPlayspaceScale = new GameEvent();
|
public static readonly GameEvent OnPlayspaceScale = new GameEvent();
|
||||||
|
|
||||||
|
@ -24,18 +22,6 @@ namespace ml_amt
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
p_instance.Patch(
|
|
||||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.ClearAvatar), BindingFlags.Instance | BindingFlags.Public),
|
|
||||||
null,
|
|
||||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnAvatarClear_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
|
||||||
);
|
|
||||||
|
|
||||||
p_instance.Patch(
|
|
||||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.SetupAvatar), BindingFlags.Instance | BindingFlags.Public),
|
|
||||||
null,
|
|
||||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnSetupAvatar_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
|
||||||
);
|
|
||||||
|
|
||||||
p_instance.Patch(
|
p_instance.Patch(
|
||||||
typeof(IKSystem).GetMethod(nameof(IKSystem.ReinitializeAvatar), BindingFlags.Instance | BindingFlags.Public),
|
typeof(IKSystem).GetMethod(nameof(IKSystem.ReinitializeAvatar), BindingFlags.Instance | BindingFlags.Public),
|
||||||
null,
|
null,
|
||||||
|
@ -54,30 +40,6 @@ namespace ml_amt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OnAvatarClear_Postfix()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
OnAvatarClear.Invoke();
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
MelonLoader.MelonLogger.Error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void OnSetupAvatar_Postfix()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
OnAvatarSetup.Invoke();
|
|
||||||
}
|
|
||||||
catch(Exception l_exception)
|
|
||||||
{
|
|
||||||
MelonLoader.MelonLogger.Error(l_exception);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void OnAvatarReinitialize_Postfix()
|
static void OnAvatarReinitialize_Postfix()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using ABI_RC.Core.Player;
|
using ABI.CCK.Components;
|
||||||
|
using ABI_RC.Core.Player;
|
||||||
using ABI_RC.Core.Util.AnimatorManager;
|
using ABI_RC.Core.Util.AnimatorManager;
|
||||||
|
using ABI_RC.Systems.GameEventSystem;
|
||||||
using ABI_RC.Systems.IK.SubSystems;
|
using ABI_RC.Systems.IK.SubSystems;
|
||||||
using ABI_RC.Systems.Movement;
|
using ABI_RC.Systems.Movement;
|
||||||
using RootMotion.FinalIK;
|
using RootMotion.FinalIK;
|
||||||
|
@ -59,8 +61,8 @@ namespace ml_amt
|
||||||
Settings.OnProneLimitChanged.AddListener(this.OnProneLimitChanged);
|
Settings.OnProneLimitChanged.AddListener(this.OnProneLimitChanged);
|
||||||
Settings.OnMassCenterChanged.AddListener(this.OnMassCenterChanged);
|
Settings.OnMassCenterChanged.AddListener(this.OnMassCenterChanged);
|
||||||
|
|
||||||
GameEvents.OnAvatarSetup.AddListener(this.OnAvatarSetup);
|
CVRGameEventSystem.Avatar.OnLocalAvatarLoad.AddListener(this.OnAvatarSetup);
|
||||||
GameEvents.OnAvatarClear.AddListener(this.OnAvatarClear);
|
CVRGameEventSystem.Avatar.OnLocalAvatarClear.AddListener(this.OnAvatarClear);
|
||||||
GameEvents.OnAvatarReuse.AddListener(this.OnAvatarReuse);
|
GameEvents.OnAvatarReuse.AddListener(this.OnAvatarReuse);
|
||||||
GameEvents.OnPlayspaceScale.AddListener(this.OnPlayspaceScale);
|
GameEvents.OnPlayspaceScale.AddListener(this.OnPlayspaceScale);
|
||||||
}
|
}
|
||||||
|
@ -78,8 +80,8 @@ namespace ml_amt
|
||||||
Settings.OnProneLimitChanged.RemoveListener(this.OnProneLimitChanged);
|
Settings.OnProneLimitChanged.RemoveListener(this.OnProneLimitChanged);
|
||||||
Settings.OnMassCenterChanged.RemoveListener(this.OnMassCenterChanged);
|
Settings.OnMassCenterChanged.RemoveListener(this.OnMassCenterChanged);
|
||||||
|
|
||||||
GameEvents.OnAvatarSetup.RemoveListener(this.OnAvatarSetup);
|
CVRGameEventSystem.Avatar.OnLocalAvatarLoad.RemoveListener(this.OnAvatarSetup);
|
||||||
GameEvents.OnAvatarClear.RemoveListener(this.OnAvatarClear);
|
CVRGameEventSystem.Avatar.OnLocalAvatarClear.RemoveListener(this.OnAvatarClear);
|
||||||
GameEvents.OnAvatarReuse.RemoveListener(this.OnAvatarReuse);
|
GameEvents.OnAvatarReuse.RemoveListener(this.OnAvatarReuse);
|
||||||
GameEvents.OnPlayspaceScale.RemoveListener(this.OnPlayspaceScale);
|
GameEvents.OnPlayspaceScale.RemoveListener(this.OnPlayspaceScale);
|
||||||
}
|
}
|
||||||
|
@ -96,68 +98,82 @@ namespace ml_amt
|
||||||
}
|
}
|
||||||
|
|
||||||
// Game events
|
// Game events
|
||||||
void OnAvatarClear()
|
void OnAvatarClear(CVRAvatar p_avatar)
|
||||||
{
|
{
|
||||||
m_vrIk = null;
|
try
|
||||||
m_avatarReady = false;
|
{
|
||||||
m_avatarScale = 1f;
|
m_vrIk = null;
|
||||||
m_locomotionOffset = Vector3.zero;
|
m_avatarReady = false;
|
||||||
m_massCenter = Vector3.zero;
|
m_avatarScale = 1f;
|
||||||
m_ikLimits = null;
|
m_locomotionOffset = Vector3.zero;
|
||||||
m_parameters.Clear();
|
m_massCenter = Vector3.zero;
|
||||||
|
m_ikLimits = null;
|
||||||
|
m_parameters.Clear();
|
||||||
|
|
||||||
BetterBetterCharacterController.Instance.avatarCrouchLimit = Mathf.Clamp01(Settings.CrouchLimit);
|
BetterBetterCharacterController.Instance.avatarCrouchLimit = Mathf.Clamp01(Settings.CrouchLimit);
|
||||||
BetterBetterCharacterController.Instance.avatarProneLimit = Mathf.Clamp01(Settings.ProneLimit);
|
BetterBetterCharacterController.Instance.avatarProneLimit = Mathf.Clamp01(Settings.ProneLimit);
|
||||||
|
}
|
||||||
|
catch(System.Exception e)
|
||||||
|
{
|
||||||
|
MelonLoader.MelonLogger.Error(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnAvatarSetup()
|
void OnAvatarSetup(CVRAvatar p_avatar)
|
||||||
{
|
{
|
||||||
Utils.SetAvatarTPose();
|
try
|
||||||
|
|
||||||
m_vrIk = PlayerSetup.Instance.AvatarObject.GetComponent<VRIK>();
|
|
||||||
m_avatarScale = Mathf.Abs(PlayerSetup.Instance.AvatarTransform.localScale.y);
|
|
||||||
|
|
||||||
// Parse animator parameters
|
|
||||||
m_parameters.Add(new AvatarParameter(AvatarParameter.ParameterType.Moving, PlayerSetup.Instance.AnimatorManager));
|
|
||||||
m_parameters.Add(new AvatarParameter(AvatarParameter.ParameterType.MovementSpeed, PlayerSetup.Instance.AnimatorManager));
|
|
||||||
m_parameters.Add(new AvatarParameter(AvatarParameter.ParameterType.Velocity, PlayerSetup.Instance.AnimatorManager));
|
|
||||||
m_parameters.RemoveAll(p => !p.IsValid());
|
|
||||||
|
|
||||||
// Avatar custom IK limits
|
|
||||||
m_ikLimits = PlayerSetup.Instance.AvatarTransform.Find("[IKLimits]");
|
|
||||||
UpdateIKLimits();
|
|
||||||
|
|
||||||
// Apply VRIK tweaks
|
|
||||||
if(m_vrIk != null)
|
|
||||||
{
|
{
|
||||||
m_locomotionOffset = m_vrIk.solver.locomotion.offset;
|
Utils.SetAvatarTPose();
|
||||||
m_massCenter = m_locomotionOffset;
|
|
||||||
|
|
||||||
if(m_vrIk.solver.HasToes())
|
m_vrIk = PlayerSetup.Instance.AvatarObject.GetComponent<VRIK>();
|
||||||
|
m_avatarScale = Mathf.Abs(PlayerSetup.Instance.AvatarTransform.localScale.y);
|
||||||
|
|
||||||
|
// Parse animator parameters
|
||||||
|
m_parameters.Add(new AvatarParameter(AvatarParameter.ParameterType.Moving, PlayerSetup.Instance.AnimatorManager));
|
||||||
|
m_parameters.Add(new AvatarParameter(AvatarParameter.ParameterType.MovementSpeed, PlayerSetup.Instance.AnimatorManager));
|
||||||
|
m_parameters.Add(new AvatarParameter(AvatarParameter.ParameterType.Velocity, PlayerSetup.Instance.AnimatorManager));
|
||||||
|
m_parameters.RemoveAll(p => !p.IsValid());
|
||||||
|
|
||||||
|
// Avatar custom IK limits
|
||||||
|
m_ikLimits = PlayerSetup.Instance.AvatarTransform.Find("[IKLimits]");
|
||||||
|
UpdateIKLimits();
|
||||||
|
|
||||||
|
// Apply VRIK tweaks
|
||||||
|
if(m_vrIk != null)
|
||||||
{
|
{
|
||||||
Transform l_foot = PlayerSetup.Instance.Animator.GetBoneTransform(HumanBodyBones.LeftFoot);
|
m_locomotionOffset = m_vrIk.solver.locomotion.offset;
|
||||||
if(l_foot == null)
|
m_massCenter = m_locomotionOffset;
|
||||||
l_foot = PlayerSetup.Instance.Animator.GetBoneTransform(HumanBodyBones.RightFoot);
|
|
||||||
|
|
||||||
Transform l_toe = PlayerSetup.Instance.Animator.GetBoneTransform(HumanBodyBones.LeftToes);
|
if(m_vrIk.solver.HasToes())
|
||||||
if(l_toe == null)
|
|
||||||
l_toe = PlayerSetup.Instance.Animator.GetBoneTransform(HumanBodyBones.RightToes);
|
|
||||||
|
|
||||||
if((l_foot != null) && (l_toe != null))
|
|
||||||
{
|
{
|
||||||
Vector3 l_footPos = (PlayerSetup.Instance.AvatarTransform.GetMatrix().inverse * l_foot.GetMatrix()).GetPosition();
|
Transform l_foot = PlayerSetup.Instance.Animator.GetBoneTransform(HumanBodyBones.LeftFoot);
|
||||||
Vector3 l_toePos = (PlayerSetup.Instance.AvatarTransform.GetMatrix().inverse * l_toe.GetMatrix()).GetPosition();
|
if(l_foot == null)
|
||||||
m_massCenter = new Vector3(0f, 0f, l_toePos.z - l_footPos.z);
|
l_foot = PlayerSetup.Instance.Animator.GetBoneTransform(HumanBodyBones.RightFoot);
|
||||||
|
|
||||||
|
Transform l_toe = PlayerSetup.Instance.Animator.GetBoneTransform(HumanBodyBones.LeftToes);
|
||||||
|
if(l_toe == null)
|
||||||
|
l_toe = PlayerSetup.Instance.Animator.GetBoneTransform(HumanBodyBones.RightToes);
|
||||||
|
|
||||||
|
if((l_foot != null) && (l_toe != null))
|
||||||
|
{
|
||||||
|
Vector3 l_footPos = (PlayerSetup.Instance.AvatarTransform.GetMatrix().inverse * l_foot.GetMatrix()).GetPosition();
|
||||||
|
Vector3 l_toePos = (PlayerSetup.Instance.AvatarTransform.GetMatrix().inverse * l_toe.GetMatrix()).GetPosition();
|
||||||
|
m_massCenter = new Vector3(0f, 0f, l_toePos.z - l_footPos.z);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_vrIk.solver.locomotion.offset = (Settings.MassCenter ? m_massCenter : m_locomotionOffset);
|
||||||
|
|
||||||
|
m_vrIk.onPreSolverUpdate.AddListener(this.OnIKPreSolverUpdate);
|
||||||
|
m_vrIk.onPostSolverUpdate.AddListener(this.OnIKPostSolverUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_vrIk.solver.locomotion.offset = (Settings.MassCenter ? m_massCenter : m_locomotionOffset);
|
m_avatarReady = true;
|
||||||
|
}
|
||||||
m_vrIk.onPreSolverUpdate.AddListener(this.OnIKPreSolverUpdate);
|
catch(System.Exception e)
|
||||||
m_vrIk.onPostSolverUpdate.AddListener(this.OnIKPostSolverUpdate);
|
{
|
||||||
|
MelonLoader.MelonLogger.Error(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_avatarReady = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnPlayspaceScale()
|
void OnPlayspaceScale()
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using ABI_RC.Core.Player;
|
using ABI.CCK.Components;
|
||||||
|
using ABI_RC.Core.Player;
|
||||||
using ABI_RC.Core.Savior;
|
using ABI_RC.Core.Savior;
|
||||||
|
using ABI_RC.Systems.GameEventSystem;
|
||||||
using ABI_RC.Systems.IK;
|
using ABI_RC.Systems.IK;
|
||||||
using ABI_RC.Systems.InputManagement;
|
using ABI_RC.Systems.InputManagement;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -92,8 +94,8 @@ namespace ml_bft
|
||||||
m_pose = new HumanPose();
|
m_pose = new HumanPose();
|
||||||
m_lastValues = new float[40];
|
m_lastValues = new float[40];
|
||||||
|
|
||||||
GameEvents.OnAvatarSetup.AddListener(this.OnAvatarSetup);
|
CVRGameEventSystem.Avatar.OnLocalAvatarLoad.AddListener(this.OnAvatarSetup);
|
||||||
GameEvents.OnAvatarClear.AddListener(this.OnAvatarClear);
|
CVRGameEventSystem.Avatar.OnLocalAvatarClear.AddListener(this.OnAvatarClear);
|
||||||
GameEvents.OnAvatarReuse.AddListener(this.OnAvatarReuse);
|
GameEvents.OnAvatarReuse.AddListener(this.OnAvatarReuse);
|
||||||
GameEvents.OnIKSystemLateUpdate.AddListener(this.OnIKSystemLateUpdate);
|
GameEvents.OnIKSystemLateUpdate.AddListener(this.OnIKSystemLateUpdate);
|
||||||
}
|
}
|
||||||
|
@ -106,99 +108,113 @@ namespace ml_bft
|
||||||
m_rightFingerOffsets.Clear();
|
m_rightFingerOffsets.Clear();
|
||||||
m_ready = false;
|
m_ready = false;
|
||||||
|
|
||||||
GameEvents.OnAvatarSetup.RemoveListener(this.OnAvatarSetup);
|
CVRGameEventSystem.Avatar.OnLocalAvatarLoad.RemoveListener(this.OnAvatarSetup);
|
||||||
GameEvents.OnAvatarClear.RemoveListener(this.OnAvatarClear);
|
CVRGameEventSystem.Avatar.OnLocalAvatarClear.RemoveListener(this.OnAvatarClear);
|
||||||
GameEvents.OnAvatarReuse.RemoveListener(this.OnAvatarReuse);
|
GameEvents.OnAvatarReuse.RemoveListener(this.OnAvatarReuse);
|
||||||
GameEvents.OnIKSystemLateUpdate.RemoveListener(this.OnIKSystemLateUpdate);
|
GameEvents.OnIKSystemLateUpdate.RemoveListener(this.OnIKSystemLateUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void OnAvatarSetup()
|
internal void OnAvatarSetup(CVRAvatar p_avatar)
|
||||||
{
|
{
|
||||||
Animator l_animator = PlayerSetup.Instance.Animator;
|
try
|
||||||
if(l_animator.isHuman)
|
|
||||||
{
|
{
|
||||||
Utils.SetAvatarTPose();
|
Animator l_animator = PlayerSetup.Instance.Animator;
|
||||||
InputHandler.Instance.Rebind(PlayerSetup.Instance.transform.rotation);
|
if(l_animator.isHuman)
|
||||||
|
|
||||||
foreach(var l_tuple in ms_fingersChains)
|
|
||||||
{
|
{
|
||||||
ReorientateTowards(
|
Utils.SetAvatarTPose();
|
||||||
PlayerSetup.Instance.transform,
|
InputHandler.Instance.Rebind(PlayerSetup.Instance.transform.rotation);
|
||||||
l_animator.GetBoneTransform(l_tuple.Item1),
|
|
||||||
(l_tuple.Item2 != HumanBodyBones.LastBone) ? l_animator.GetBoneTransform(l_tuple.Item2) : null,
|
|
||||||
InputHandler.Instance.GetSourceForBone(l_tuple.Item1, l_tuple.Item3),
|
|
||||||
InputHandler.Instance.GetSourceForBone(l_tuple.Item2, l_tuple.Item3),
|
|
||||||
PlaneType.OXZ
|
|
||||||
);
|
|
||||||
ReorientateTowards(
|
|
||||||
PlayerSetup.Instance.transform,
|
|
||||||
l_animator.GetBoneTransform(l_tuple.Item1),
|
|
||||||
(l_tuple.Item2 != HumanBodyBones.LastBone) ? l_animator.GetBoneTransform(l_tuple.Item2) : null,
|
|
||||||
InputHandler.Instance.GetSourceForBone(l_tuple.Item1, l_tuple.Item3),
|
|
||||||
InputHandler.Instance.GetSourceForBone(l_tuple.Item2, l_tuple.Item3),
|
|
||||||
PlaneType.OYX
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind hands
|
foreach(var l_tuple in ms_fingersChains)
|
||||||
m_leftHandOffset.m_source = l_animator.GetBoneTransform(HumanBodyBones.LeftHand);
|
|
||||||
m_leftHandOffset.m_target = InputHandler.Instance.GetSourceForBone(HumanBodyBones.LeftHand, true);
|
|
||||||
if((m_leftHandOffset.m_source != null) && (m_leftHandOffset.m_target != null))
|
|
||||||
m_leftHandOffset.m_offset = Quaternion.Inverse(m_leftHandOffset.m_source.rotation) * m_leftHandOffset.m_target.rotation;
|
|
||||||
|
|
||||||
m_rightHandOffset.m_source = l_animator.GetBoneTransform(HumanBodyBones.RightHand);
|
|
||||||
m_rightHandOffset.m_target = InputHandler.Instance.GetSourceForBone(HumanBodyBones.RightHand, false);
|
|
||||||
if((m_rightHandOffset.m_source != null) && (m_rightHandOffset.m_target != null))
|
|
||||||
m_rightHandOffset.m_offset = Quaternion.Inverse(m_rightHandOffset.m_source.rotation) * m_rightHandOffset.m_target.rotation;
|
|
||||||
|
|
||||||
// Bind fingers
|
|
||||||
foreach(HumanBodyBones p_bone in ms_leftFingerBones)
|
|
||||||
{
|
|
||||||
Transform l_avatarBone = l_animator.GetBoneTransform(p_bone);
|
|
||||||
Transform l_controllerBone = InputHandler.Instance.GetSourceForBone(p_bone, true);
|
|
||||||
if((l_avatarBone != null) && (l_controllerBone != null))
|
|
||||||
{
|
{
|
||||||
RotationOffset l_offset = new RotationOffset();
|
ReorientateTowards(
|
||||||
l_offset.m_source = l_controllerBone;
|
PlayerSetup.Instance.transform,
|
||||||
l_offset.m_target = l_avatarBone;
|
l_animator.GetBoneTransform(l_tuple.Item1),
|
||||||
l_offset.m_offset = Quaternion.Inverse(l_controllerBone.rotation) * l_avatarBone.rotation;
|
(l_tuple.Item2 != HumanBodyBones.LastBone) ? l_animator.GetBoneTransform(l_tuple.Item2) : null,
|
||||||
m_leftFingerOffsets.Add(l_offset);
|
InputHandler.Instance.GetSourceForBone(l_tuple.Item1, l_tuple.Item3),
|
||||||
|
InputHandler.Instance.GetSourceForBone(l_tuple.Item2, l_tuple.Item3),
|
||||||
|
PlaneType.OXZ
|
||||||
|
);
|
||||||
|
ReorientateTowards(
|
||||||
|
PlayerSetup.Instance.transform,
|
||||||
|
l_animator.GetBoneTransform(l_tuple.Item1),
|
||||||
|
(l_tuple.Item2 != HumanBodyBones.LastBone) ? l_animator.GetBoneTransform(l_tuple.Item2) : null,
|
||||||
|
InputHandler.Instance.GetSourceForBone(l_tuple.Item1, l_tuple.Item3),
|
||||||
|
InputHandler.Instance.GetSourceForBone(l_tuple.Item2, l_tuple.Item3),
|
||||||
|
PlaneType.OYX
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
foreach(HumanBodyBones p_bone in ms_rightFingerBones)
|
|
||||||
{
|
|
||||||
Transform l_avatarBone = l_animator.GetBoneTransform(p_bone);
|
|
||||||
Transform l_controllerBone = InputHandler.Instance.GetSourceForBone(p_bone, false);
|
|
||||||
if((l_avatarBone != null) && (l_controllerBone != null))
|
|
||||||
{
|
|
||||||
RotationOffset l_offset = new RotationOffset();
|
|
||||||
l_offset.m_source = l_controllerBone;
|
|
||||||
l_offset.m_target = l_avatarBone;
|
|
||||||
l_offset.m_offset = Quaternion.Inverse(l_controllerBone.rotation) * l_avatarBone.rotation;
|
|
||||||
m_rightFingerOffsets.Add(l_offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_ready = ((m_leftFingerOffsets.Count > 0) || (m_rightFingerOffsets.Count > 0));
|
// Bind hands
|
||||||
|
m_leftHandOffset.m_source = l_animator.GetBoneTransform(HumanBodyBones.LeftHand);
|
||||||
|
m_leftHandOffset.m_target = InputHandler.Instance.GetSourceForBone(HumanBodyBones.LeftHand, true);
|
||||||
|
if((m_leftHandOffset.m_source != null) && (m_leftHandOffset.m_target != null))
|
||||||
|
m_leftHandOffset.m_offset = Quaternion.Inverse(m_leftHandOffset.m_source.rotation) * m_leftHandOffset.m_target.rotation;
|
||||||
|
|
||||||
|
m_rightHandOffset.m_source = l_animator.GetBoneTransform(HumanBodyBones.RightHand);
|
||||||
|
m_rightHandOffset.m_target = InputHandler.Instance.GetSourceForBone(HumanBodyBones.RightHand, false);
|
||||||
|
if((m_rightHandOffset.m_source != null) && (m_rightHandOffset.m_target != null))
|
||||||
|
m_rightHandOffset.m_offset = Quaternion.Inverse(m_rightHandOffset.m_source.rotation) * m_rightHandOffset.m_target.rotation;
|
||||||
|
|
||||||
|
// Bind fingers
|
||||||
|
foreach(HumanBodyBones p_bone in ms_leftFingerBones)
|
||||||
|
{
|
||||||
|
Transform l_avatarBone = l_animator.GetBoneTransform(p_bone);
|
||||||
|
Transform l_controllerBone = InputHandler.Instance.GetSourceForBone(p_bone, true);
|
||||||
|
if((l_avatarBone != null) && (l_controllerBone != null))
|
||||||
|
{
|
||||||
|
RotationOffset l_offset = new RotationOffset();
|
||||||
|
l_offset.m_source = l_controllerBone;
|
||||||
|
l_offset.m_target = l_avatarBone;
|
||||||
|
l_offset.m_offset = Quaternion.Inverse(l_controllerBone.rotation) * l_avatarBone.rotation;
|
||||||
|
m_leftFingerOffsets.Add(l_offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach(HumanBodyBones p_bone in ms_rightFingerBones)
|
||||||
|
{
|
||||||
|
Transform l_avatarBone = l_animator.GetBoneTransform(p_bone);
|
||||||
|
Transform l_controllerBone = InputHandler.Instance.GetSourceForBone(p_bone, false);
|
||||||
|
if((l_avatarBone != null) && (l_controllerBone != null))
|
||||||
|
{
|
||||||
|
RotationOffset l_offset = new RotationOffset();
|
||||||
|
l_offset.m_source = l_controllerBone;
|
||||||
|
l_offset.m_target = l_avatarBone;
|
||||||
|
l_offset.m_offset = Quaternion.Inverse(l_controllerBone.rotation) * l_avatarBone.rotation;
|
||||||
|
m_rightFingerOffsets.Add(l_offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ready = ((m_leftFingerOffsets.Count > 0) || (m_rightFingerOffsets.Count > 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(System.Exception e)
|
||||||
|
{
|
||||||
|
MelonLoader.MelonLogger.Error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void OnAvatarClear()
|
internal void OnAvatarClear(CVRAvatar p_avatar)
|
||||||
{
|
{
|
||||||
m_ready = false;
|
try
|
||||||
m_pose = new HumanPose();
|
{
|
||||||
|
m_ready = false;
|
||||||
|
m_pose = new HumanPose();
|
||||||
|
|
||||||
m_leftHandOffset.Reset();
|
m_leftHandOffset.Reset();
|
||||||
m_rightHandOffset.Reset();
|
m_rightHandOffset.Reset();
|
||||||
|
|
||||||
m_leftFingerOffsets.Clear();
|
m_leftFingerOffsets.Clear();
|
||||||
m_rightFingerOffsets.Clear();
|
m_rightFingerOffsets.Clear();
|
||||||
|
}
|
||||||
|
catch(System.Exception e)
|
||||||
|
{
|
||||||
|
MelonLoader.MelonLogger.Error(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void OnAvatarReuse()
|
internal void OnAvatarReuse()
|
||||||
{
|
{
|
||||||
OnAvatarClear();
|
OnAvatarClear(PlayerSetup.Instance.AvatarDescriptor);
|
||||||
OnAvatarSetup();
|
OnAvatarSetup(PlayerSetup.Instance.AvatarDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void OnIKSystemLateUpdate(HumanPoseHandler p_handler, Transform p_hips)
|
internal void OnIKSystemLateUpdate(HumanPoseHandler p_handler, Transform p_hips)
|
||||||
|
|
|
@ -24,8 +24,6 @@ namespace ml_bft
|
||||||
public void Invoke(T1 p_objA, T2 p_objB) => m_action?.Invoke(p_objA, p_objB);
|
public void Invoke(T1 p_objA, T2 p_objB) => m_action?.Invoke(p_objA, p_objB);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 OnAvatarReuse = new GameEvent();
|
||||||
public static readonly GameEvent OnInputUpdate = new GameEvent();
|
public static readonly GameEvent OnInputUpdate = new GameEvent();
|
||||||
public static readonly GameEvent<HumanPoseHandler, Transform> OnIKSystemLateUpdate = new GameEvent<HumanPoseHandler, Transform>();
|
public static readonly GameEvent<HumanPoseHandler, Transform> OnIKSystemLateUpdate = new GameEvent<HumanPoseHandler, Transform>();
|
||||||
|
@ -34,18 +32,6 @@ namespace ml_bft
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
p_instance.Patch(
|
|
||||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.SetupAvatar), BindingFlags.Instance | BindingFlags.Public),
|
|
||||||
null,
|
|
||||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnSetupAvatar_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
|
||||||
);
|
|
||||||
|
|
||||||
p_instance.Patch(
|
|
||||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.ClearAvatar), BindingFlags.Instance | BindingFlags.Public),
|
|
||||||
null,
|
|
||||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnAvatarClear_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
|
||||||
);
|
|
||||||
|
|
||||||
p_instance.Patch(
|
p_instance.Patch(
|
||||||
typeof(IKSystem).GetMethod(nameof(IKSystem.ReinitializeAvatar), BindingFlags.Instance | BindingFlags.Public),
|
typeof(IKSystem).GetMethod(nameof(IKSystem.ReinitializeAvatar), BindingFlags.Instance | BindingFlags.Public),
|
||||||
null,
|
null,
|
||||||
|
@ -70,30 +56,6 @@ namespace ml_bft
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OnAvatarClear_Postfix()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
OnAvatarClear.Invoke();
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
MelonLoader.MelonLogger.Error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void OnSetupAvatar_Postfix()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
OnAvatarSetup.Invoke();
|
|
||||||
}
|
|
||||||
catch(Exception l_exception)
|
|
||||||
{
|
|
||||||
MelonLoader.MelonLogger.Error(l_exception);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void OnAvatarReinitialize_Postfix()
|
static void OnAvatarReinitialize_Postfix()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
@ -35,8 +35,6 @@ namespace ml_dht
|
||||||
public void Invoke(T1 p_objA, T2 p_objB) => m_action?.Invoke(p_objA, p_objB);
|
public void Invoke(T1 p_objA, T2 p_objB) => m_action?.Invoke(p_objA, p_objB);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 OnAvatarReuse = new GameEvent();
|
||||||
public static readonly GameEvent<EyeMovementController> OnEyeControllerUpdate = new GameEvent<EyeMovementController>();
|
public static readonly GameEvent<EyeMovementController> OnEyeControllerUpdate = new GameEvent<EyeMovementController>();
|
||||||
public static readonly GameEvent<CVRFaceTracking, EventResult> OnFaceTrackingUpdate = new GameEvent<CVRFaceTracking, EventResult>();
|
public static readonly GameEvent<CVRFaceTracking, EventResult> OnFaceTrackingUpdate = new GameEvent<CVRFaceTracking, EventResult>();
|
||||||
|
@ -47,18 +45,6 @@ namespace ml_dht
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
p_instance.Patch(
|
|
||||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.ClearAvatar), BindingFlags.Instance | BindingFlags.Public),
|
|
||||||
null,
|
|
||||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnAvatarClear_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
|
||||||
);
|
|
||||||
|
|
||||||
p_instance.Patch(
|
|
||||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.SetupAvatar), BindingFlags.Instance | BindingFlags.Public),
|
|
||||||
null,
|
|
||||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnSetupAvatar_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
|
||||||
);
|
|
||||||
|
|
||||||
p_instance.Patch(
|
p_instance.Patch(
|
||||||
typeof(IKSystem).GetMethod(nameof(IKSystem.ReinitializeAvatar), BindingFlags.Instance | BindingFlags.Public),
|
typeof(IKSystem).GetMethod(nameof(IKSystem.ReinitializeAvatar), BindingFlags.Instance | BindingFlags.Public),
|
||||||
null,
|
null,
|
||||||
|
@ -92,30 +78,6 @@ namespace ml_dht
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OnSetupAvatar_Postfix()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
OnAvatarSetup.Invoke();
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
MelonLoader.MelonLogger.Error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void OnAvatarClear_Postfix()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
OnAvatarClear.Invoke();
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
MelonLoader.MelonLogger.Error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void OnAvatarReinitialize_Postfix()
|
static void OnAvatarReinitialize_Postfix()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using ABI_RC.Core.Player;
|
using ABI_RC.Core.Player;
|
||||||
using ABI_RC.Core.Player.EyeMovement;
|
using ABI_RC.Core.Player.EyeMovement;
|
||||||
using ABI_RC.Systems.FaceTracking;
|
using ABI_RC.Systems.FaceTracking;
|
||||||
|
using ABI_RC.Systems.GameEventSystem;
|
||||||
using ABI_RC.Systems.IK;
|
using ABI_RC.Systems.IK;
|
||||||
using ABI_RC.Systems.VRModeSwitch;
|
using ABI_RC.Systems.VRModeSwitch;
|
||||||
using RootMotion.FinalIK;
|
using RootMotion.FinalIK;
|
||||||
|
@ -69,8 +70,8 @@ namespace ml_dht
|
||||||
Settings.OnHeadTrackingChanged.AddListener(this.OnEnabledOrHeadTrackingChanged);
|
Settings.OnHeadTrackingChanged.AddListener(this.OnEnabledOrHeadTrackingChanged);
|
||||||
Settings.OnSmoothingChanged.AddListener(this.OnSmoothingChanged);
|
Settings.OnSmoothingChanged.AddListener(this.OnSmoothingChanged);
|
||||||
|
|
||||||
GameEvents.OnAvatarClear.AddListener(this.OnAvatarClear);
|
CVRGameEventSystem.Avatar.OnLocalAvatarLoad.AddListener(this.OnAvatarClear);
|
||||||
GameEvents.OnAvatarSetup.AddListener(this.OnAvatarSetup);
|
CVRGameEventSystem.Avatar.OnLocalAvatarClear.AddListener(this.OnAvatarSetup);
|
||||||
GameEvents.OnAvatarReuse.AddListener(this.OnAvatarReuse);
|
GameEvents.OnAvatarReuse.AddListener(this.OnAvatarReuse);
|
||||||
GameEvents.OnEyeControllerUpdate.AddListener(this.OnEyeControllerUpdate);
|
GameEvents.OnEyeControllerUpdate.AddListener(this.OnEyeControllerUpdate);
|
||||||
GameEvents.OnFaceTrackingUpdate.AddListener(this.UpdateFaceTracking);
|
GameEvents.OnFaceTrackingUpdate.AddListener(this.UpdateFaceTracking);
|
||||||
|
@ -89,8 +90,8 @@ namespace ml_dht
|
||||||
Settings.OnHeadTrackingChanged.RemoveListener(this.OnEnabledOrHeadTrackingChanged);
|
Settings.OnHeadTrackingChanged.RemoveListener(this.OnEnabledOrHeadTrackingChanged);
|
||||||
Settings.OnSmoothingChanged.RemoveListener(this.OnSmoothingChanged);
|
Settings.OnSmoothingChanged.RemoveListener(this.OnSmoothingChanged);
|
||||||
|
|
||||||
GameEvents.OnAvatarClear.RemoveListener(this.OnAvatarClear);
|
CVRGameEventSystem.Avatar.OnLocalAvatarLoad.RemoveListener(this.OnAvatarClear);
|
||||||
GameEvents.OnAvatarSetup.RemoveListener(this.OnAvatarSetup);
|
CVRGameEventSystem.Avatar.OnLocalAvatarClear.RemoveListener(this.OnAvatarSetup);
|
||||||
GameEvents.OnAvatarReuse.RemoveListener(this.OnAvatarReuse);
|
GameEvents.OnAvatarReuse.RemoveListener(this.OnAvatarReuse);
|
||||||
GameEvents.OnEyeControllerUpdate.RemoveListener(this.OnEyeControllerUpdate);
|
GameEvents.OnEyeControllerUpdate.RemoveListener(this.OnEyeControllerUpdate);
|
||||||
GameEvents.OnFaceTrackingUpdate.RemoveListener(this.UpdateFaceTracking);
|
GameEvents.OnFaceTrackingUpdate.RemoveListener(this.UpdateFaceTracking);
|
||||||
|
@ -137,33 +138,47 @@ namespace ml_dht
|
||||||
}
|
}
|
||||||
|
|
||||||
// Game events
|
// Game events
|
||||||
internal void OnAvatarSetup()
|
internal void OnAvatarSetup(CVRAvatar p_avatar)
|
||||||
{
|
{
|
||||||
m_camera = PlayerSetup.Instance.activeCam.transform;
|
try
|
||||||
m_avatarDescriptor = PlayerSetup.Instance.AvatarObject.GetComponent<CVRAvatar>();
|
|
||||||
|
|
||||||
if(PlayerSetup.Instance.Animator.isHuman)
|
|
||||||
{
|
{
|
||||||
IKSystem.Instance.SetAvatarPose(IKSystem.AvatarPose.TPose);
|
m_camera = PlayerSetup.Instance.activeCam.transform;
|
||||||
PlayerSetup.Instance.AvatarTransform.localPosition = Vector3.zero;
|
m_avatarDescriptor = PlayerSetup.Instance.AvatarObject.GetComponent<CVRAvatar>();
|
||||||
PlayerSetup.Instance.AvatarTransform.localRotation = Quaternion.identity;
|
|
||||||
|
|
||||||
m_headBone = PlayerSetup.Instance.Animator.GetBoneTransform(HumanBodyBones.Head);
|
if(PlayerSetup.Instance.Animator.isHuman)
|
||||||
if(m_headBone != null)
|
{
|
||||||
m_bindRotation = Quaternion.Inverse(m_avatarDescriptor.transform.rotation) * m_headBone.rotation;
|
IKSystem.Instance.SetAvatarPose(IKSystem.AvatarPose.TPose);
|
||||||
|
PlayerSetup.Instance.AvatarTransform.localPosition = Vector3.zero;
|
||||||
|
PlayerSetup.Instance.AvatarTransform.localRotation = Quaternion.identity;
|
||||||
|
|
||||||
m_lookIK = PlayerSetup.Instance.AvatarObject.GetComponent<LookAtIK>();
|
m_headBone = PlayerSetup.Instance.Animator.GetBoneTransform(HumanBodyBones.Head);
|
||||||
if(m_lookIK != null)
|
if(m_headBone != null)
|
||||||
m_lookIK.onPostSolverUpdate.AddListener(this.OnLookIKPostUpdate);
|
m_bindRotation = Quaternion.Inverse(m_avatarDescriptor.transform.rotation) * m_headBone.rotation;
|
||||||
|
|
||||||
|
m_lookIK = PlayerSetup.Instance.AvatarObject.GetComponent<LookAtIK>();
|
||||||
|
if(m_lookIK != null)
|
||||||
|
m_lookIK.onPostSolverUpdate.AddListener(this.OnLookIKPostUpdate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
MelonLoader.MelonLogger.Error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void OnAvatarClear()
|
void OnAvatarClear(CVRAvatar p_avatar)
|
||||||
{
|
{
|
||||||
m_avatarDescriptor = null;
|
try
|
||||||
m_lookIK = null;
|
{
|
||||||
m_headBone = null;
|
m_avatarDescriptor = null;
|
||||||
m_lastHeadRotation = Quaternion.identity;
|
m_lookIK = null;
|
||||||
m_bindRotation = Quaternion.identity;
|
m_headBone = null;
|
||||||
|
m_lastHeadRotation = Quaternion.identity;
|
||||||
|
m_bindRotation = Quaternion.identity;
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
MelonLoader.MelonLogger.Error(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void OnAvatarReuse()
|
void OnAvatarReuse()
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,8 +23,6 @@ namespace ml_lme
|
||||||
public void Invoke(T1 p_obj) => m_action?.Invoke(p_obj);
|
public void Invoke(T1 p_obj) => m_action?.Invoke(p_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 OnAvatarReuse = new GameEvent();
|
||||||
public static readonly GameEvent<float> OnRayScale = new GameEvent<float>();
|
public static readonly GameEvent<float> OnRayScale = new GameEvent<float>();
|
||||||
public static readonly GameEvent<float> OnPlayspaceScale = new GameEvent<float>();
|
public static readonly GameEvent<float> OnPlayspaceScale = new GameEvent<float>();
|
||||||
|
@ -34,18 +32,6 @@ namespace ml_lme
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
p_instance.Patch(
|
|
||||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.ClearAvatar), BindingFlags.Instance | BindingFlags.Public),
|
|
||||||
null,
|
|
||||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnAvatarClear_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
|
||||||
);
|
|
||||||
|
|
||||||
p_instance.Patch(
|
|
||||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.SetupAvatar), BindingFlags.Instance | BindingFlags.Public),
|
|
||||||
null,
|
|
||||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnSetupAvatar_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
|
||||||
);
|
|
||||||
|
|
||||||
p_instance.Patch(
|
p_instance.Patch(
|
||||||
typeof(IKSystem).GetMethod(nameof(IKSystem.ReinitializeAvatar), BindingFlags.Instance | BindingFlags.Public),
|
typeof(IKSystem).GetMethod(nameof(IKSystem.ReinitializeAvatar), BindingFlags.Instance | BindingFlags.Public),
|
||||||
null,
|
null,
|
||||||
|
@ -76,30 +62,6 @@ namespace ml_lme
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OnAvatarClear_Postfix()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
OnAvatarClear.Invoke();
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
MelonLoader.MelonLogger.Error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void OnSetupAvatar_Postfix()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
OnAvatarSetup.Invoke();
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
MelonLoader.MelonLogger.Error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void OnAvatarReinitialize_Postfix()
|
static void OnAvatarReinitialize_Postfix()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
using ABI_RC.Core.Player;
|
using ABI.CCK.Components;
|
||||||
|
using ABI_RC.Core.Player;
|
||||||
|
using ABI_RC.Systems.GameEventSystem;
|
||||||
using ABI_RC.Systems.IK;
|
using ABI_RC.Systems.IK;
|
||||||
using RootMotion.FinalIK;
|
using RootMotion.FinalIK;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -148,8 +150,8 @@ namespace ml_lme
|
||||||
Settings.OnFingersOnlyChanged.AddListener(this.OnEnabledOrFingersOnlyChanged);
|
Settings.OnFingersOnlyChanged.AddListener(this.OnEnabledOrFingersOnlyChanged);
|
||||||
Settings.OnTrackElbowsChanged.AddListener(this.OnTrackElbowsChanged);
|
Settings.OnTrackElbowsChanged.AddListener(this.OnTrackElbowsChanged);
|
||||||
|
|
||||||
GameEvents.OnAvatarClear.AddListener(this.OnAvatarClear);
|
CVRGameEventSystem.Avatar.OnLocalAvatarLoad.AddListener(this.OnAvatarSetup);
|
||||||
GameEvents.OnAvatarSetup.AddListener(this.OnAvatarSetup);
|
CVRGameEventSystem.Avatar.OnLocalAvatarClear.AddListener(this.OnAvatarClear);
|
||||||
GameEvents.OnAvatarReuse.AddListener(this.OnAvatarReuse);
|
GameEvents.OnAvatarReuse.AddListener(this.OnAvatarReuse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,8 +176,8 @@ namespace ml_lme
|
||||||
Settings.OnFingersOnlyChanged.RemoveListener(this.OnEnabledOrFingersOnlyChanged);
|
Settings.OnFingersOnlyChanged.RemoveListener(this.OnEnabledOrFingersOnlyChanged);
|
||||||
Settings.OnTrackElbowsChanged.RemoveListener(this.OnTrackElbowsChanged);
|
Settings.OnTrackElbowsChanged.RemoveListener(this.OnTrackElbowsChanged);
|
||||||
|
|
||||||
GameEvents.OnAvatarClear.RemoveListener(this.OnAvatarClear);
|
CVRGameEventSystem.Avatar.OnLocalAvatarLoad.RemoveListener(this.OnAvatarSetup);
|
||||||
GameEvents.OnAvatarSetup.RemoveListener(this.OnAvatarSetup);
|
CVRGameEventSystem.Avatar.OnLocalAvatarClear.RemoveListener(this.OnAvatarClear);
|
||||||
GameEvents.OnAvatarReuse.RemoveListener(this.OnAvatarReuse);
|
GameEvents.OnAvatarReuse.RemoveListener(this.OnAvatarReuse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,58 +257,72 @@ namespace ml_lme
|
||||||
}
|
}
|
||||||
|
|
||||||
// Game events
|
// Game events
|
||||||
void OnAvatarClear()
|
void OnAvatarClear(CVRAvatar p_avatar)
|
||||||
{
|
{
|
||||||
m_vrIK = null;
|
try
|
||||||
m_hips = null;
|
{
|
||||||
m_leftArmIK = null;
|
m_vrIK = null;
|
||||||
m_rightArmIK = null;
|
m_hips = null;
|
||||||
m_leftTargetActive = false;
|
m_leftArmIK = null;
|
||||||
m_rightTargetActive = false;
|
m_rightArmIK = null;
|
||||||
|
m_leftTargetActive = false;
|
||||||
|
m_rightTargetActive = false;
|
||||||
|
|
||||||
m_poseHandler?.Dispose();
|
m_poseHandler?.Dispose();
|
||||||
m_poseHandler = null;
|
m_poseHandler = null;
|
||||||
|
|
||||||
m_leftHandTarget.localPosition = Vector3.zero;
|
m_leftHandTarget.localPosition = Vector3.zero;
|
||||||
m_leftHandTarget.localRotation = Quaternion.identity;
|
m_leftHandTarget.localRotation = Quaternion.identity;
|
||||||
m_rightHandTarget.localPosition = Vector3.zero;
|
m_rightHandTarget.localPosition = Vector3.zero;
|
||||||
m_rightHandTarget.localRotation = Quaternion.identity;
|
m_rightHandTarget.localRotation = Quaternion.identity;
|
||||||
|
|
||||||
m_leftHandOffset.Reset();
|
m_leftHandOffset.Reset();
|
||||||
m_rightHandOffset.Reset();
|
m_rightHandOffset.Reset();
|
||||||
|
|
||||||
m_leftFingerOffsets.Clear();
|
m_leftFingerOffsets.Clear();
|
||||||
m_rightFingerOffsets.Clear();
|
m_rightFingerOffsets.Clear();
|
||||||
|
}
|
||||||
|
catch(System.Exception e)
|
||||||
|
{
|
||||||
|
MelonLoader.MelonLogger.Error(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnAvatarSetup()
|
void OnAvatarSetup(CVRAvatar p_avatar)
|
||||||
{
|
{
|
||||||
Animator l_animator = PlayerSetup.Instance.Animator;
|
try
|
||||||
if(l_animator.isHuman)
|
|
||||||
{
|
{
|
||||||
Utils.SetAvatarTPose();
|
Animator l_animator = PlayerSetup.Instance.Animator;
|
||||||
|
if(l_animator.isHuman)
|
||||||
m_poseHandler = new HumanPoseHandler(l_animator.avatar, l_animator.transform);
|
|
||||||
m_poseHandler.GetHumanPose(ref m_pose);
|
|
||||||
|
|
||||||
m_hips = l_animator.GetBoneTransform(HumanBodyBones.Hips);
|
|
||||||
|
|
||||||
m_leftHandOffset.m_source = l_animator.GetBoneTransform(HumanBodyBones.LeftHand);
|
|
||||||
m_leftHandTarget.localRotation = ms_offsetLeft * (Quaternion.Inverse(l_animator.transform.rotation) * m_leftHandOffset.m_source.rotation);
|
|
||||||
|
|
||||||
m_rightHandOffset.m_source = l_animator.GetBoneTransform(HumanBodyBones.RightHand);
|
|
||||||
m_rightHandTarget.localRotation = ms_offsetRight * (Quaternion.Inverse(l_animator.transform.rotation) * m_rightHandOffset.m_source.rotation);
|
|
||||||
|
|
||||||
ParseFingersBones();
|
|
||||||
|
|
||||||
m_vrIK = l_animator.GetComponent<VRIK>();
|
|
||||||
if(m_vrIK != null)
|
|
||||||
{
|
{
|
||||||
m_vrIK.onPreSolverUpdate.AddListener(this.OnIKPreSolverUpdate);
|
Utils.SetAvatarTPose();
|
||||||
m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostSolverUpdate);
|
|
||||||
|
m_poseHandler = new HumanPoseHandler(l_animator.avatar, l_animator.transform);
|
||||||
|
m_poseHandler.GetHumanPose(ref m_pose);
|
||||||
|
|
||||||
|
m_hips = l_animator.GetBoneTransform(HumanBodyBones.Hips);
|
||||||
|
|
||||||
|
m_leftHandOffset.m_source = l_animator.GetBoneTransform(HumanBodyBones.LeftHand);
|
||||||
|
m_leftHandTarget.localRotation = ms_offsetLeft * (Quaternion.Inverse(l_animator.transform.rotation) * m_leftHandOffset.m_source.rotation);
|
||||||
|
|
||||||
|
m_rightHandOffset.m_source = l_animator.GetBoneTransform(HumanBodyBones.RightHand);
|
||||||
|
m_rightHandTarget.localRotation = ms_offsetRight * (Quaternion.Inverse(l_animator.transform.rotation) * m_rightHandOffset.m_source.rotation);
|
||||||
|
|
||||||
|
ParseFingersBones();
|
||||||
|
|
||||||
|
m_vrIK = l_animator.GetComponent<VRIK>();
|
||||||
|
if(m_vrIK != null)
|
||||||
|
{
|
||||||
|
m_vrIK.onPreSolverUpdate.AddListener(this.OnIKPreSolverUpdate);
|
||||||
|
m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostSolverUpdate);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SetupArmIK();
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
SetupArmIK();
|
catch(System.Exception e)
|
||||||
|
{
|
||||||
|
MelonLoader.MelonLogger.Error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using ABI.CCK.Components;
|
using ABI.CCK.Components;
|
||||||
using ABI_RC.Core.InteractionSystem;
|
using ABI_RC.Core.InteractionSystem;
|
||||||
using ABI_RC.Core.Player;
|
using ABI_RC.Core.Player;
|
||||||
|
using ABI_RC.Systems.GameEventSystem;
|
||||||
using ABI_RC.Systems.VRModeSwitch;
|
using ABI_RC.Systems.VRModeSwitch;
|
||||||
using RootMotion.FinalIK;
|
using RootMotion.FinalIK;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
@ -100,8 +101,8 @@ namespace ml_pam
|
||||||
Settings.OnLeadingHandChanged.AddListener(this.OnLeadingHandChanged);
|
Settings.OnLeadingHandChanged.AddListener(this.OnLeadingHandChanged);
|
||||||
Settings.OnHandsExtensionChanged.AddListener(this.OnHandsExtensionChanged);
|
Settings.OnHandsExtensionChanged.AddListener(this.OnHandsExtensionChanged);
|
||||||
|
|
||||||
GameEvents.OnAvatarClear.AddListener(this.OnAvatarClear);
|
CVRGameEventSystem.Avatar.OnLocalAvatarClear.AddListener(this.OnAvatarClear);
|
||||||
GameEvents.OnAvatarSetup.AddListener(this.OnAvatarSetup);
|
CVRGameEventSystem.Avatar.OnLocalAvatarLoad.AddListener(this.OnAvatarSetup);
|
||||||
GameEvents.OnAvatarReuse.AddListener(this.OnAvatarReuse);
|
GameEvents.OnAvatarReuse.AddListener(this.OnAvatarReuse);
|
||||||
GameEvents.OnIKScaling.AddListener(this.OnIKScaling);
|
GameEvents.OnIKScaling.AddListener(this.OnIKScaling);
|
||||||
GameEvents.OnPickupGrab.AddListener(this.OnPickupGrab);
|
GameEvents.OnPickupGrab.AddListener(this.OnPickupGrab);
|
||||||
|
@ -149,10 +150,10 @@ namespace ml_pam
|
||||||
Settings.OnLeadingHandChanged.RemoveListener(this.OnLeadingHandChanged);
|
Settings.OnLeadingHandChanged.RemoveListener(this.OnLeadingHandChanged);
|
||||||
Settings.OnHandsExtensionChanged.RemoveListener(this.OnHandsExtensionChanged);
|
Settings.OnHandsExtensionChanged.RemoveListener(this.OnHandsExtensionChanged);
|
||||||
|
|
||||||
GameEvents.OnAvatarClear.RemoveListener(this.OnAvatarClear);
|
CVRGameEventSystem.Avatar.OnLocalAvatarClear.RemoveListener(this.OnAvatarClear);
|
||||||
GameEvents.OnAvatarSetup.RemoveListener(this.OnAvatarSetup);
|
CVRGameEventSystem.Avatar.OnLocalAvatarLoad.RemoveListener(this.OnAvatarSetup);
|
||||||
GameEvents.OnAvatarReuse.RemoveListener(this.OnAvatarReuse);
|
GameEvents.OnAvatarReuse.RemoveListener(this.OnAvatarReuse);
|
||||||
GameEvents.OnIKScaling.AddListener(this.OnIKScaling);
|
GameEvents.OnIKScaling.RemoveListener(this.OnIKScaling);
|
||||||
GameEvents.OnPickupGrab.RemoveListener(this.OnPickupGrab);
|
GameEvents.OnPickupGrab.RemoveListener(this.OnPickupGrab);
|
||||||
GameEvents.OnPickupDrop.RemoveListener(this.OnPickupDrop);
|
GameEvents.OnPickupDrop.RemoveListener(this.OnPickupDrop);
|
||||||
|
|
||||||
|
@ -341,66 +342,80 @@ namespace ml_pam
|
||||||
}
|
}
|
||||||
|
|
||||||
// Game events
|
// Game events
|
||||||
void OnAvatarClear()
|
void OnAvatarClear(CVRAvatar p_avatar)
|
||||||
{
|
{
|
||||||
m_vrIK = null;
|
try
|
||||||
m_armIKLeft = null;
|
{
|
||||||
m_armIKRight = null;
|
m_vrIK = null;
|
||||||
m_armsLength.Set(0f, 0f, 0f, 0f);
|
m_armIKLeft = null;
|
||||||
m_leftHandParameter = null;
|
m_armIKRight = null;
|
||||||
m_rightHandParameter = null;
|
m_armsLength.Set(0f, 0f, 0f, 0f);
|
||||||
|
m_leftHandParameter = null;
|
||||||
|
m_rightHandParameter = null;
|
||||||
|
}
|
||||||
|
catch(System.Exception e)
|
||||||
|
{
|
||||||
|
MelonLoader.MelonLogger.Error(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnAvatarSetup()
|
void OnAvatarSetup(CVRAvatar p_avatar)
|
||||||
{
|
{
|
||||||
m_camera = PlayerSetup.Instance.activeCam.transform;
|
try
|
||||||
|
|
||||||
if(PlayerSetup.Instance.Animator.isHuman)
|
|
||||||
{
|
{
|
||||||
m_vrIK = PlayerSetup.Instance.Animator.GetComponent<VRIK>();
|
m_camera = PlayerSetup.Instance.activeCam.transform;
|
||||||
Utils.SetAvatarTPose();
|
|
||||||
|
|
||||||
Animator l_animator = PlayerSetup.Instance.Animator;
|
if(PlayerSetup.Instance.Animator.isHuman)
|
||||||
Matrix4x4 l_avatarMatrixInv = l_animator.transform.GetMatrix().inverse; // Animator and avatar are on same game object
|
{
|
||||||
|
m_vrIK = PlayerSetup.Instance.Animator.GetComponent<VRIK>();
|
||||||
|
Utils.SetAvatarTPose();
|
||||||
|
|
||||||
Transform l_leftHand = l_animator.GetBoneTransform(HumanBodyBones.LeftHand);
|
Animator l_animator = PlayerSetup.Instance.Animator;
|
||||||
if(l_leftHand != null)
|
Matrix4x4 l_avatarMatrixInv = l_animator.transform.GetMatrix().inverse; // Animator and avatar are on same game object
|
||||||
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[]{
|
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.LeftUpperArm),
|
||||||
l_animator.GetBoneTransform(HumanBodyBones.LeftLowerArm),
|
l_animator.GetBoneTransform(HumanBodyBones.LeftLowerArm),
|
||||||
l_animator.GetBoneTransform(HumanBodyBones.LeftHand)
|
l_animator.GetBoneTransform(HumanBodyBones.LeftHand)
|
||||||
});
|
});
|
||||||
m_armsLength.y = GetChainLength(new Transform[]{
|
m_armsLength.y = GetChainLength(new Transform[]{
|
||||||
l_animator.GetBoneTransform(HumanBodyBones.RightUpperArm),
|
l_animator.GetBoneTransform(HumanBodyBones.RightUpperArm),
|
||||||
l_animator.GetBoneTransform(HumanBodyBones.RightLowerArm),
|
l_animator.GetBoneTransform(HumanBodyBones.RightLowerArm),
|
||||||
l_animator.GetBoneTransform(HumanBodyBones.RightHand)
|
l_animator.GetBoneTransform(HumanBodyBones.RightHand)
|
||||||
});
|
});
|
||||||
m_armsLength.z = Mathf.Abs((l_avatarMatrixInv * l_animator.GetBoneTransform(HumanBodyBones.LeftUpperArm).GetMatrix()).GetPosition().x);
|
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);
|
m_armsLength.w = Mathf.Abs((l_avatarMatrixInv * l_animator.GetBoneTransform(HumanBodyBones.RightUpperArm).GetMatrix()).GetPosition().x);
|
||||||
|
|
||||||
if(!Utils.IsInVR())
|
if(!Utils.IsInVR())
|
||||||
{
|
|
||||||
if(m_vrIK != null)
|
|
||||||
{
|
{
|
||||||
m_vrIK.onPreSolverUpdate.AddListener(this.OnIKPreUpdate);
|
if(m_vrIK != null)
|
||||||
m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate);
|
{
|
||||||
|
m_vrIK.onPreSolverUpdate.AddListener(this.OnIKPreUpdate);
|
||||||
|
m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SetupArmIK();
|
||||||
}
|
}
|
||||||
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
|
||||||
|
}
|
||||||
|
catch(System.Exception e)
|
||||||
|
{
|
||||||
|
MelonLoader.MelonLogger.Error(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
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()
|
void OnAvatarReuse()
|
||||||
|
|
|
@ -31,8 +31,6 @@ namespace ml_pam
|
||||||
public void Invoke(T1 p_objA, T2 p_objB) => m_action?.Invoke(p_objA, p_objB);
|
public void Invoke(T1 p_objA, T2 p_objB) => m_action?.Invoke(p_objA, p_objB);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 OnAvatarReuse = new GameEvent();
|
||||||
public static readonly GameEvent<float> OnIKScaling = 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, Vector3> OnPickupGrab = new GameEvent<CVRPickupObject, Vector3>();
|
||||||
|
@ -42,18 +40,6 @@ namespace ml_pam
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
p_instance.Patch(
|
|
||||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.ClearAvatar), BindingFlags.Instance | BindingFlags.Public),
|
|
||||||
null,
|
|
||||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnAvatarClear_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
|
||||||
);
|
|
||||||
|
|
||||||
p_instance.Patch(
|
|
||||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.SetupAvatar), BindingFlags.Instance | BindingFlags.Public),
|
|
||||||
null,
|
|
||||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnSetupAvatar_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
|
||||||
);
|
|
||||||
|
|
||||||
p_instance.Patch(
|
p_instance.Patch(
|
||||||
typeof(IKSystem).GetMethod(nameof(IKSystem.ReinitializeAvatar), BindingFlags.Instance | BindingFlags.Public),
|
typeof(IKSystem).GetMethod(nameof(IKSystem.ReinitializeAvatar), BindingFlags.Instance | BindingFlags.Public),
|
||||||
null,
|
null,
|
||||||
|
@ -84,30 +70,6 @@ namespace ml_pam
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OnAvatarClear_Postfix()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
OnAvatarClear.Invoke();
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
MelonLoader.MelonLogger.Error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void OnSetupAvatar_Postfix()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
OnAvatarSetup.Invoke();
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
MelonLoader.MelonLogger.Error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void OnAvatarReinitialize_Postfix()
|
static void OnAvatarReinitialize_Postfix()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
@ -15,8 +15,6 @@ namespace ml_pmc
|
||||||
public void Invoke() => m_action?.Invoke();
|
public void Invoke() => m_action?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly GameEvent OnAvatarSetup = new GameEvent();
|
|
||||||
public static readonly GameEvent OnAvatarClear = new GameEvent();
|
|
||||||
public static readonly GameEvent OnAvatarPreReuse = new GameEvent();
|
public static readonly GameEvent OnAvatarPreReuse = new GameEvent();
|
||||||
public static readonly GameEvent OnAvatarPostReuse = new GameEvent();
|
public static readonly GameEvent OnAvatarPostReuse = new GameEvent();
|
||||||
|
|
||||||
|
@ -24,18 +22,6 @@ namespace ml_pmc
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
p_instance.Patch(
|
|
||||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.ClearAvatar), BindingFlags.Instance | BindingFlags.Public),
|
|
||||||
null,
|
|
||||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnAvatarClear_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
|
||||||
);
|
|
||||||
|
|
||||||
p_instance.Patch(
|
|
||||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.SetupAvatar), BindingFlags.Instance | BindingFlags.Public),
|
|
||||||
null,
|
|
||||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnSetupAvatar_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
|
||||||
);
|
|
||||||
|
|
||||||
p_instance.Patch(
|
p_instance.Patch(
|
||||||
typeof(IKSystem).GetMethod(nameof(IKSystem.ReinitializeAvatar), BindingFlags.Instance | BindingFlags.Public),
|
typeof(IKSystem).GetMethod(nameof(IKSystem.ReinitializeAvatar), BindingFlags.Instance | BindingFlags.Public),
|
||||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnAvatarReinitialize_Prefix), BindingFlags.Static | BindingFlags.NonPublic)),
|
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnAvatarReinitialize_Prefix), BindingFlags.Static | BindingFlags.NonPublic)),
|
||||||
|
@ -48,30 +34,6 @@ namespace ml_pmc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OnAvatarClear_Postfix()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
OnAvatarClear.Invoke();
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
MelonLoader.MelonLogger.Error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void OnSetupAvatar_Postfix()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
OnAvatarSetup.Invoke();
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
MelonLoader.MelonLogger.Error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void OnAvatarReinitialize_Prefix()
|
static void OnAvatarReinitialize_Prefix()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using ABI_RC.Core.Networking.IO.Social;
|
using ABI.CCK.Components;
|
||||||
|
using ABI_RC.Core.Networking.IO.Social;
|
||||||
using ABI_RC.Core.Player;
|
using ABI_RC.Core.Player;
|
||||||
|
using ABI_RC.Systems.GameEventSystem;
|
||||||
using ABI_RC.Systems.IK;
|
using ABI_RC.Systems.IK;
|
||||||
using ABI_RC.Systems.IK.SubSystems;
|
using ABI_RC.Systems.IK.SubSystems;
|
||||||
using ABI_RC.Systems.InputManagement;
|
using ABI_RC.Systems.InputManagement;
|
||||||
|
@ -55,8 +57,8 @@ namespace ml_pmc
|
||||||
|
|
||||||
void Start()
|
void Start()
|
||||||
{
|
{
|
||||||
GameEvents.OnAvatarClear.AddListener(this.OnAvatarClear);
|
CVRGameEventSystem.Avatar.OnLocalAvatarClear.AddListener(this.OnAvatarClear);
|
||||||
GameEvents.OnAvatarSetup.AddListener(this.OnAvatarSetup);
|
CVRGameEventSystem.Avatar.OnLocalAvatarLoad.AddListener(this.OnAvatarSetup);
|
||||||
GameEvents.OnAvatarPreReuse.AddListener(this.OnAvatarPreReuse);
|
GameEvents.OnAvatarPreReuse.AddListener(this.OnAvatarPreReuse);
|
||||||
GameEvents.OnAvatarPostReuse.AddListener(this.OnAvatarPostReuse);
|
GameEvents.OnAvatarPostReuse.AddListener(this.OnAvatarPostReuse);
|
||||||
|
|
||||||
|
@ -78,8 +80,8 @@ namespace ml_pmc
|
||||||
m_vrIk = null;
|
m_vrIk = null;
|
||||||
m_lookAtIk = null;
|
m_lookAtIk = null;
|
||||||
|
|
||||||
GameEvents.OnAvatarClear.RemoveListener(this.OnAvatarClear);
|
CVRGameEventSystem.Avatar.OnLocalAvatarClear.RemoveListener(this.OnAvatarClear);
|
||||||
GameEvents.OnAvatarSetup.RemoveListener(this.OnAvatarSetup);
|
CVRGameEventSystem.Avatar.OnLocalAvatarLoad.RemoveListener(this.OnAvatarSetup);
|
||||||
GameEvents.OnAvatarPreReuse.RemoveListener(this.OnAvatarPreReuse);
|
GameEvents.OnAvatarPreReuse.RemoveListener(this.OnAvatarPreReuse);
|
||||||
GameEvents.OnAvatarPostReuse.RemoveListener(this.OnAvatarPostReuse);
|
GameEvents.OnAvatarPostReuse.RemoveListener(this.OnAvatarPostReuse);
|
||||||
|
|
||||||
|
@ -229,58 +231,72 @@ namespace ml_pmc
|
||||||
}
|
}
|
||||||
|
|
||||||
// Game events
|
// Game events
|
||||||
void OnAvatarClear()
|
void OnAvatarClear(CVRAvatar p_avatar)
|
||||||
{
|
{
|
||||||
if(m_active)
|
try
|
||||||
{
|
{
|
||||||
RestoreIK();
|
if(m_active)
|
||||||
RestoreFingerTracking();
|
{
|
||||||
OnCopycatChanged.Invoke(false);
|
RestoreIK();
|
||||||
|
RestoreFingerTracking();
|
||||||
|
OnCopycatChanged.Invoke(false);
|
||||||
|
}
|
||||||
|
m_active = false;
|
||||||
|
|
||||||
|
if(m_puppetParser != null)
|
||||||
|
Object.Destroy(m_puppetParser);
|
||||||
|
m_puppetParser = null;
|
||||||
|
|
||||||
|
m_animator = null;
|
||||||
|
m_vrIk = null;
|
||||||
|
m_lookAtIk = null;
|
||||||
|
|
||||||
|
m_poseHandler?.Dispose();
|
||||||
|
m_poseHandler = null;
|
||||||
|
|
||||||
|
m_distanceLimit = float.MaxValue;
|
||||||
|
m_fingerTracking = false;
|
||||||
|
m_pose = new HumanPose();
|
||||||
|
}
|
||||||
|
catch(System.Exception e)
|
||||||
|
{
|
||||||
|
MelonLoader.MelonLogger.Error(e);
|
||||||
}
|
}
|
||||||
m_active = false;
|
|
||||||
|
|
||||||
if(m_puppetParser != null)
|
|
||||||
Object.Destroy(m_puppetParser);
|
|
||||||
m_puppetParser = null;
|
|
||||||
|
|
||||||
m_animator = null;
|
|
||||||
m_vrIk = null;
|
|
||||||
m_lookAtIk = null;
|
|
||||||
|
|
||||||
m_poseHandler?.Dispose();
|
|
||||||
m_poseHandler = null;
|
|
||||||
|
|
||||||
m_distanceLimit = float.MaxValue;
|
|
||||||
m_fingerTracking = false;
|
|
||||||
m_pose = new HumanPose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnAvatarSetup()
|
void OnAvatarSetup(CVRAvatar p_avatar)
|
||||||
{
|
{
|
||||||
m_inVr = Utils.IsInVR();
|
try
|
||||||
m_animator = PlayerSetup.Instance.Animator;
|
|
||||||
m_vrIk = PlayerSetup.Instance.AvatarObject.GetComponent<VRIK>();
|
|
||||||
m_lookAtIk = PlayerSetup.Instance.AvatarObject.GetComponent<LookAtIK>();
|
|
||||||
|
|
||||||
if((m_animator != null) && m_animator.isHuman)
|
|
||||||
{
|
{
|
||||||
m_poseHandler = new HumanPoseHandler(m_animator.avatar, m_animator.transform);
|
m_inVr = Utils.IsInVR();
|
||||||
m_poseHandler.GetHumanPose(ref m_pose);
|
m_animator = PlayerSetup.Instance.Animator;
|
||||||
|
m_vrIk = PlayerSetup.Instance.AvatarObject.GetComponent<VRIK>();
|
||||||
|
m_lookAtIk = PlayerSetup.Instance.AvatarObject.GetComponent<LookAtIK>();
|
||||||
|
|
||||||
if(m_vrIk != null)
|
if((m_animator != null) && m_animator.isHuman)
|
||||||
{
|
{
|
||||||
m_vrIk.onPreSolverUpdate.AddListener(this.OnVRIKPreUpdate);
|
m_poseHandler = new HumanPoseHandler(m_animator.avatar, m_animator.transform);
|
||||||
m_vrIk.onPostSolverUpdate.AddListener(this.OnVRIKPostUpdate);
|
m_poseHandler.GetHumanPose(ref m_pose);
|
||||||
}
|
|
||||||
|
|
||||||
if(m_lookAtIk != null)
|
if(m_vrIk != null)
|
||||||
{
|
{
|
||||||
m_lookAtIk.onPreSolverUpdate.AddListener(this.OnLookAtIKPreUpdate);
|
m_vrIk.onPreSolverUpdate.AddListener(this.OnVRIKPreUpdate);
|
||||||
m_lookAtIk.onPostSolverUpdate.AddListener(this.OnLookAtIKPostUpdate);
|
m_vrIk.onPostSolverUpdate.AddListener(this.OnVRIKPostUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_lookAtIk != null)
|
||||||
|
{
|
||||||
|
m_lookAtIk.onPreSolverUpdate.AddListener(this.OnLookAtIKPreUpdate);
|
||||||
|
m_lookAtIk.onPostSolverUpdate.AddListener(this.OnLookAtIKPostUpdate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
m_animator = null;
|
||||||
|
}
|
||||||
|
catch(System.Exception e)
|
||||||
|
{
|
||||||
|
MelonLoader.MelonLogger.Error(e);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
m_animator = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnAvatarPreReuse()
|
void OnAvatarPreReuse()
|
||||||
|
|
|
@ -23,8 +23,6 @@ namespace ml_ppu
|
||||||
public void Invoke(T1 p_obj) => m_action?.Invoke(p_obj);
|
public void Invoke(T1 p_obj) => m_action?.Invoke(p_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly GameEvent OnAvatarSetup = new GameEvent();
|
|
||||||
public static readonly GameEvent OnAvatarClear = new GameEvent();
|
|
||||||
public static readonly GameEvent<float> OnIKScaling = new GameEvent<float>();
|
public static readonly GameEvent<float> OnIKScaling = new GameEvent<float>();
|
||||||
public static readonly GameEvent OnWorldPreSpawn = new GameEvent();
|
public static readonly GameEvent OnWorldPreSpawn = new GameEvent();
|
||||||
public static readonly GameEvent<CVRSeat> OnSeatPreSit = new GameEvent<CVRSeat>();
|
public static readonly GameEvent<CVRSeat> OnSeatPreSit = new GameEvent<CVRSeat>();
|
||||||
|
@ -33,18 +31,6 @@ namespace ml_ppu
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
p_instance.Patch(
|
|
||||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.ClearAvatar), BindingFlags.Instance | BindingFlags.Public),
|
|
||||||
null,
|
|
||||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnAvatarClear_Postfix), BindingFlags.Static |BindingFlags.NonPublic))
|
|
||||||
);
|
|
||||||
|
|
||||||
p_instance.Patch(
|
|
||||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.SetupAvatar), BindingFlags.Instance | BindingFlags.Public),
|
|
||||||
null,
|
|
||||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnSetupAvatar_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
|
||||||
);
|
|
||||||
|
|
||||||
p_instance.Patch(
|
p_instance.Patch(
|
||||||
typeof(PlayerSetup).GetMethod("SetupIKScaling", BindingFlags.Instance | BindingFlags.NonPublic),
|
typeof(PlayerSetup).GetMethod("SetupIKScaling", BindingFlags.Instance | BindingFlags.NonPublic),
|
||||||
null,
|
null,
|
||||||
|
@ -69,30 +55,6 @@ namespace ml_ppu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OnAvatarClear_Postfix()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
OnAvatarClear.Invoke();
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
MelonLoader.MelonLogger.Error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void OnSetupAvatar_Postfix()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
OnAvatarSetup.Invoke();
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
MelonLoader.MelonLogger.Error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void OnSetupIKScaling_Postfix(ref UnityEngine.Vector3 ___scaleDifference)
|
static void OnSetupIKScaling_Postfix(ref UnityEngine.Vector3 ___scaleDifference)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using ABI_RC.Core;
|
using ABI_RC.Core;
|
||||||
using ABI_RC.Core.InteractionSystem;
|
using ABI_RC.Core.InteractionSystem;
|
||||||
using ABI_RC.Core.Player;
|
using ABI_RC.Core.Player;
|
||||||
|
using ABI_RC.Systems.GameEventSystem;
|
||||||
using ABI_RC.Systems.IK;
|
using ABI_RC.Systems.IK;
|
||||||
using ABI_RC.Systems.Movement;
|
using ABI_RC.Systems.Movement;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
@ -46,8 +47,8 @@ namespace ml_ppu
|
||||||
|
|
||||||
void Start()
|
void Start()
|
||||||
{
|
{
|
||||||
GameEvents.OnAvatarSetup.AddListener(this.OnAvatarSetup);
|
CVRGameEventSystem.Avatar.OnLocalAvatarLoad.AddListener(this.OnAvatarSetup);
|
||||||
GameEvents.OnAvatarClear.AddListener(this.OnAvatarClear);
|
CVRGameEventSystem.Avatar.OnLocalAvatarClear.AddListener(this.OnAvatarClear);
|
||||||
GameEvents.OnIKScaling.AddListener(this.OnIKScaling);
|
GameEvents.OnIKScaling.AddListener(this.OnIKScaling);
|
||||||
GameEvents.OnWorldPreSpawn.AddListener(this.OnWorldPreSpawn);
|
GameEvents.OnWorldPreSpawn.AddListener(this.OnWorldPreSpawn);
|
||||||
GameEvents.OnSeatPreSit.AddListener(this.OnSeatPreSit);
|
GameEvents.OnSeatPreSit.AddListener(this.OnSeatPreSit);
|
||||||
|
@ -60,8 +61,8 @@ namespace ml_ppu
|
||||||
if(Instance == this)
|
if(Instance == this)
|
||||||
Instance = null;
|
Instance = null;
|
||||||
|
|
||||||
GameEvents.OnAvatarSetup.RemoveListener(this.OnAvatarSetup);
|
CVRGameEventSystem.Avatar.OnLocalAvatarLoad.RemoveListener(this.OnAvatarSetup);
|
||||||
GameEvents.OnAvatarClear.RemoveListener(this.OnAvatarClear);
|
CVRGameEventSystem.Avatar.OnLocalAvatarClear.RemoveListener(this.OnAvatarClear);
|
||||||
GameEvents.OnIKScaling.RemoveListener(this.OnIKScaling);
|
GameEvents.OnIKScaling.RemoveListener(this.OnIKScaling);
|
||||||
GameEvents.OnWorldPreSpawn.RemoveListener(this.OnWorldPreSpawn);
|
GameEvents.OnWorldPreSpawn.RemoveListener(this.OnWorldPreSpawn);
|
||||||
GameEvents.OnSeatPreSit.RemoveListener(this.OnSeatPreSit);
|
GameEvents.OnSeatPreSit.RemoveListener(this.OnSeatPreSit);
|
||||||
|
@ -126,53 +127,67 @@ namespace ml_ppu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnAvatarSetup()
|
void OnAvatarSetup(CVRAvatar p_avatar)
|
||||||
{
|
{
|
||||||
Animator l_animator = PlayerSetup.Instance.Animator;
|
try
|
||||||
if((l_animator != null) && l_animator.isHuman)
|
|
||||||
{
|
{
|
||||||
IKSystem.Instance.SetAvatarPose(IKSystem.AvatarPose.TPose);
|
Animator l_animator = PlayerSetup.Instance.Animator;
|
||||||
PlayerSetup.Instance.AvatarTransform.localPosition = Vector3.zero;
|
if((l_animator != null) && l_animator.isHuman)
|
||||||
PlayerSetup.Instance.AvatarTransform.localRotation = Quaternion.identity;
|
|
||||||
|
|
||||||
m_hips = l_animator.GetBoneTransform(HumanBodyBones.Hips);
|
|
||||||
m_armLeft = l_animator.GetBoneTransform(HumanBodyBones.LeftUpperArm);
|
|
||||||
m_armRight = l_animator.GetBoneTransform(HumanBodyBones.RightUpperArm);
|
|
||||||
|
|
||||||
if((m_hips != null) && (m_armLeft != null) && (m_armRight != null))
|
|
||||||
{
|
{
|
||||||
Matrix4x4 l_avatarMatInv = PlayerSetup.Instance.AvatarTransform.GetMatrix().inverse;
|
IKSystem.Instance.SetAvatarPose(IKSystem.AvatarPose.TPose);
|
||||||
Vector3 l_hipsPos = (l_avatarMatInv * m_hips.GetMatrix()).GetPosition();
|
PlayerSetup.Instance.AvatarTransform.localPosition = Vector3.zero;
|
||||||
Vector3 l_armPos = (l_avatarMatInv * m_armLeft.GetMatrix()).GetPosition();
|
PlayerSetup.Instance.AvatarTransform.localRotation = Quaternion.identity;
|
||||||
|
|
||||||
m_collider = new GameObject("[Collider]").AddComponent<CapsuleCollider>();
|
m_hips = l_animator.GetBoneTransform(HumanBodyBones.Hips);
|
||||||
m_collider.gameObject.layer = CVRLayers.PlayerClone;
|
m_armLeft = l_animator.GetBoneTransform(HumanBodyBones.LeftUpperArm);
|
||||||
m_collider.transform.parent = this.transform;
|
m_armRight = l_animator.GetBoneTransform(HumanBodyBones.RightUpperArm);
|
||||||
m_collider.isTrigger = true;
|
|
||||||
m_collider.height = Vector3.Distance(l_hipsPos, new Vector3(0f, l_armPos.y, l_armPos.z));
|
|
||||||
m_collider.radius = new Vector2(l_armPos.x, l_armPos.z).magnitude;
|
|
||||||
m_collider.center = new Vector3(0f, m_collider.height * 0.5f, 0f);
|
|
||||||
m_collider.gameObject.AddComponent<GrabDetector>();
|
|
||||||
|
|
||||||
m_ready = true;
|
if((m_hips != null) && (m_armLeft != null) && (m_armRight != null))
|
||||||
|
{
|
||||||
|
Matrix4x4 l_avatarMatInv = PlayerSetup.Instance.AvatarTransform.GetMatrix().inverse;
|
||||||
|
Vector3 l_hipsPos = (l_avatarMatInv * m_hips.GetMatrix()).GetPosition();
|
||||||
|
Vector3 l_armPos = (l_avatarMatInv * m_armLeft.GetMatrix()).GetPosition();
|
||||||
|
|
||||||
|
m_collider = new GameObject("[Collider]").AddComponent<CapsuleCollider>();
|
||||||
|
m_collider.gameObject.layer = CVRLayers.PlayerClone;
|
||||||
|
m_collider.transform.parent = this.transform;
|
||||||
|
m_collider.isTrigger = true;
|
||||||
|
m_collider.height = Vector3.Distance(l_hipsPos, new Vector3(0f, l_armPos.y, l_armPos.z));
|
||||||
|
m_collider.radius = new Vector2(l_armPos.x, l_armPos.z).magnitude;
|
||||||
|
m_collider.center = new Vector3(0f, m_collider.height * 0.5f, 0f);
|
||||||
|
m_collider.gameObject.AddComponent<GrabDetector>();
|
||||||
|
|
||||||
|
m_ready = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch(System.Exception e)
|
||||||
|
{
|
||||||
|
MelonLoader.MelonLogger.Error(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnAvatarClear()
|
void OnAvatarClear(CVRAvatar p_avatar)
|
||||||
{
|
{
|
||||||
m_ready = false;
|
try
|
||||||
m_held = false;
|
|
||||||
|
|
||||||
if(m_collider != null)
|
|
||||||
{
|
{
|
||||||
Destroy(m_collider.gameObject);
|
m_ready = false;
|
||||||
m_collider = null;
|
m_held = false;
|
||||||
|
|
||||||
|
if(m_collider != null)
|
||||||
|
{
|
||||||
|
Destroy(m_collider.gameObject);
|
||||||
|
m_collider = null;
|
||||||
|
}
|
||||||
|
m_holderPointA = null;
|
||||||
|
m_holderPointerA = null;
|
||||||
|
m_holderPointB = null;
|
||||||
|
m_holderPointerB = null;
|
||||||
|
}
|
||||||
|
catch(System.Exception e)
|
||||||
|
{
|
||||||
|
MelonLoader.MelonLogger.Error(e);
|
||||||
}
|
}
|
||||||
m_holderPointA = null;
|
|
||||||
m_holderPointerA = null;
|
|
||||||
m_holderPointB = null;
|
|
||||||
m_holderPointerB = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnIKScaling(float p_scale)
|
void OnIKScaling(float p_scale)
|
||||||
|
|
|
@ -32,8 +32,6 @@ namespace ml_prm
|
||||||
public void Invoke(T1 p_obj) => m_action?.Invoke(p_obj);
|
public void Invoke(T1 p_obj) => m_action?.Invoke(p_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly GameEvent OnAvatarSetup = new GameEvent();
|
|
||||||
public static readonly GameEvent OnAvatarClear = new GameEvent();
|
|
||||||
public static readonly GameEvent OnAvatarPreReuse = new GameEvent();
|
public static readonly GameEvent OnAvatarPreReuse = new GameEvent();
|
||||||
public static readonly GameEvent OnAvatarPostReuse = new GameEvent();
|
public static readonly GameEvent OnAvatarPostReuse = new GameEvent();
|
||||||
public static readonly GameEvent<float> OnIKScaling = new GameEvent<float>();
|
public static readonly GameEvent<float> OnIKScaling = new GameEvent<float>();
|
||||||
|
@ -50,18 +48,6 @@ namespace ml_prm
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
p_instance.Patch(
|
|
||||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.ClearAvatar), BindingFlags.Instance | BindingFlags.Public),
|
|
||||||
null,
|
|
||||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnAvatarClear_Postfix), BindingFlags.Static |BindingFlags.NonPublic))
|
|
||||||
);
|
|
||||||
|
|
||||||
p_instance.Patch(
|
|
||||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.SetupAvatar), BindingFlags.Instance | BindingFlags.Public),
|
|
||||||
null,
|
|
||||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnSetupAvatar_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
|
||||||
);
|
|
||||||
|
|
||||||
p_instance.Patch(
|
p_instance.Patch(
|
||||||
typeof(IKSystem).GetMethod(nameof(IKSystem.ReinitializeAvatar), BindingFlags.Instance | BindingFlags.Public),
|
typeof(IKSystem).GetMethod(nameof(IKSystem.ReinitializeAvatar), BindingFlags.Instance | BindingFlags.Public),
|
||||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnAvatarReinitialize_Prefix), BindingFlags.Static | BindingFlags.NonPublic)),
|
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnAvatarReinitialize_Prefix), BindingFlags.Static | BindingFlags.NonPublic)),
|
||||||
|
@ -115,30 +101,6 @@ namespace ml_prm
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OnAvatarClear_Postfix()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
OnAvatarClear.Invoke();
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
MelonLoader.MelonLogger.Error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void OnSetupAvatar_Postfix()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
OnAvatarSetup.Invoke();
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
MelonLoader.MelonLogger.Error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void OnAvatarReinitialize_Prefix()
|
static void OnAvatarReinitialize_Prefix()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using ABI_RC.Core;
|
using ABI_RC.Core;
|
||||||
using ABI_RC.Core.InteractionSystem;
|
using ABI_RC.Core.InteractionSystem;
|
||||||
using ABI_RC.Core.Player;
|
using ABI_RC.Core.Player;
|
||||||
|
using ABI_RC.Systems.GameEventSystem;
|
||||||
using ABI_RC.Systems.IK;
|
using ABI_RC.Systems.IK;
|
||||||
using ABI_RC.Systems.IK.SubSystems;
|
using ABI_RC.Systems.IK.SubSystems;
|
||||||
using ABI_RC.Systems.InputManagement;
|
using ABI_RC.Systems.InputManagement;
|
||||||
|
@ -99,8 +100,8 @@ namespace ml_prm
|
||||||
Settings.OnFallDamageChanged.AddListener(this.OnFallDamageChanged);
|
Settings.OnFallDamageChanged.AddListener(this.OnFallDamageChanged);
|
||||||
Settings.OnGestureGrabChanged.AddListener(this.OnGestureGrabChanged);
|
Settings.OnGestureGrabChanged.AddListener(this.OnGestureGrabChanged);
|
||||||
|
|
||||||
GameEvents.OnAvatarClear.AddListener(this.OnAvatarClear);
|
CVRGameEventSystem.Avatar.OnLocalAvatarClear.AddListener(this.OnAvatarClear);
|
||||||
GameEvents.OnAvatarSetup.AddListener(this.OnAvatarSetup);
|
CVRGameEventSystem.Avatar.OnLocalAvatarLoad.AddListener(this.OnAvatarSetup);
|
||||||
GameEvents.OnAvatarPreReuse.AddListener(this.OnAvatarPreReuse);
|
GameEvents.OnAvatarPreReuse.AddListener(this.OnAvatarPreReuse);
|
||||||
GameEvents.OnAvatarPostReuse.AddListener(this.OnAvatarPostReuse);
|
GameEvents.OnAvatarPostReuse.AddListener(this.OnAvatarPostReuse);
|
||||||
GameEvents.OnIKScaling.AddListener(this.OnAvatarScaling);
|
GameEvents.OnIKScaling.AddListener(this.OnAvatarScaling);
|
||||||
|
@ -148,8 +149,8 @@ namespace ml_prm
|
||||||
Settings.OnFallDamageChanged.RemoveListener(this.OnFallDamageChanged);
|
Settings.OnFallDamageChanged.RemoveListener(this.OnFallDamageChanged);
|
||||||
Settings.OnGestureGrabChanged.RemoveListener(this.OnGestureGrabChanged);
|
Settings.OnGestureGrabChanged.RemoveListener(this.OnGestureGrabChanged);
|
||||||
|
|
||||||
GameEvents.OnAvatarClear.RemoveListener(this.OnAvatarClear);
|
CVRGameEventSystem.Avatar.OnLocalAvatarClear.RemoveListener(this.OnAvatarClear);
|
||||||
GameEvents.OnAvatarSetup.RemoveListener(this.OnAvatarSetup);
|
CVRGameEventSystem.Avatar.OnLocalAvatarLoad.RemoveListener(this.OnAvatarSetup);
|
||||||
GameEvents.OnAvatarPreReuse.RemoveListener(this.OnAvatarPreReuse);
|
GameEvents.OnAvatarPreReuse.RemoveListener(this.OnAvatarPreReuse);
|
||||||
GameEvents.OnAvatarPostReuse.RemoveListener(this.OnAvatarPostReuse);
|
GameEvents.OnAvatarPostReuse.RemoveListener(this.OnAvatarPostReuse);
|
||||||
GameEvents.OnIKScaling.RemoveListener(this.OnAvatarScaling);
|
GameEvents.OnIKScaling.RemoveListener(this.OnAvatarScaling);
|
||||||
|
@ -252,129 +253,143 @@ namespace ml_prm
|
||||||
}
|
}
|
||||||
|
|
||||||
// Game events
|
// Game events
|
||||||
void OnAvatarClear()
|
void OnAvatarClear(CVRAvatar p_avatar)
|
||||||
{
|
{
|
||||||
if(m_initTask != null)
|
try
|
||||||
{
|
{
|
||||||
StopCoroutine(m_initTask);
|
if(m_initTask != null)
|
||||||
m_initTask = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(m_ragdolled)
|
|
||||||
{
|
|
||||||
TryRestoreMovement();
|
|
||||||
BodySystem.TrackingPositionWeight = 1f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(m_puppetRoot != null)
|
|
||||||
Object.Destroy(m_puppetRoot.gameObject);
|
|
||||||
m_puppetRoot = null;
|
|
||||||
|
|
||||||
m_avatarTransform = null;
|
|
||||||
m_hips = null;
|
|
||||||
m_vrIK = null;
|
|
||||||
m_applyHipsPosition = false;
|
|
||||||
m_ragdolled = false;
|
|
||||||
m_avatarReady = false;
|
|
||||||
m_avatarRagdollToggle = null;
|
|
||||||
m_ragdolledParameter = null;
|
|
||||||
m_puppetReferences = new BipedRagdollReferences();
|
|
||||||
m_ragdollBodyHandlers.Clear();
|
|
||||||
m_boneLinks.Clear();
|
|
||||||
m_jointAnchors.Clear();
|
|
||||||
m_reachedGround = true;
|
|
||||||
m_groundedTime = 0f;
|
|
||||||
m_downTime = float.MinValue;
|
|
||||||
m_puppet.localScale = Vector3.one;
|
|
||||||
m_inAir = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnAvatarSetup()
|
|
||||||
{
|
|
||||||
if(PlayerSetup.Instance.Animator.isHuman)
|
|
||||||
{
|
|
||||||
m_avatarTransform = PlayerSetup.Instance.AvatarTransform;
|
|
||||||
m_hips = PlayerSetup.Instance.Animator.GetBoneTransform(HumanBodyBones.Hips);
|
|
||||||
Utils.SetAvatarTPose();
|
|
||||||
|
|
||||||
BipedRagdollReferences l_avatarReferences = BipedRagdollReferences.FromAvatar(PlayerSetup.Instance.Animator);
|
|
||||||
|
|
||||||
m_puppetRoot = new GameObject("Root").transform;
|
|
||||||
m_puppetRoot.gameObject.layer = CVRLayers.PlayerClone;
|
|
||||||
m_puppetRoot.parent = m_puppet;
|
|
||||||
m_puppetRoot.position = m_avatarTransform.position;
|
|
||||||
m_puppetRoot.rotation = m_avatarTransform.rotation;
|
|
||||||
|
|
||||||
m_puppetReferences.root = m_puppetRoot;
|
|
||||||
m_puppetReferences.hips = CloneTransform(l_avatarReferences.hips, m_puppetReferences.root, "Hips");
|
|
||||||
m_puppetReferences.spine = CloneTransform(l_avatarReferences.spine, m_puppetReferences.hips, "Spine");
|
|
||||||
|
|
||||||
if(l_avatarReferences.chest != null)
|
|
||||||
m_puppetReferences.chest = CloneTransform(l_avatarReferences.chest, m_puppetReferences.spine, "Chest");
|
|
||||||
|
|
||||||
m_puppetReferences.head = CloneTransform(l_avatarReferences.head, (m_puppetReferences.chest != null) ? m_puppetReferences.chest : m_puppetReferences.spine, "Head");
|
|
||||||
|
|
||||||
m_puppetReferences.leftUpperArm = CloneTransform(l_avatarReferences.leftUpperArm, (m_puppetReferences.chest != null) ? m_puppetReferences.chest : m_puppetReferences.spine, "LeftUpperArm");
|
|
||||||
m_puppetReferences.leftLowerArm = CloneTransform(l_avatarReferences.leftLowerArm, m_puppetReferences.leftUpperArm, "LeftLowerArm");
|
|
||||||
m_puppetReferences.leftHand = CloneTransform(l_avatarReferences.leftHand, m_puppetReferences.leftLowerArm, "LeftHand");
|
|
||||||
|
|
||||||
m_puppetReferences.rightUpperArm = CloneTransform(l_avatarReferences.rightUpperArm, (m_puppetReferences.chest != null) ? m_puppetReferences.chest : m_puppetReferences.spine, "RightUpperArm");
|
|
||||||
m_puppetReferences.rightLowerArm = CloneTransform(l_avatarReferences.rightLowerArm, m_puppetReferences.rightUpperArm, "RightLowerArm");
|
|
||||||
m_puppetReferences.rightHand = CloneTransform(l_avatarReferences.rightHand, m_puppetReferences.rightLowerArm, "RightHand");
|
|
||||||
|
|
||||||
m_puppetReferences.leftUpperLeg = CloneTransform(l_avatarReferences.leftUpperLeg, m_puppetReferences.hips, "LeftUpperLeg");
|
|
||||||
m_puppetReferences.leftLowerLeg = CloneTransform(l_avatarReferences.leftLowerLeg, m_puppetReferences.leftUpperLeg, "LeftLowerLeg");
|
|
||||||
m_puppetReferences.leftFoot = CloneTransform(l_avatarReferences.leftFoot, m_puppetReferences.leftLowerLeg, "LeftFoot");
|
|
||||||
|
|
||||||
m_puppetReferences.rightUpperLeg = CloneTransform(l_avatarReferences.rightUpperLeg, m_puppetReferences.hips, "RightUpperLeg");
|
|
||||||
m_puppetReferences.rightLowerLeg = CloneTransform(l_avatarReferences.rightLowerLeg, m_puppetReferences.rightUpperLeg, "RightLowerLeg");
|
|
||||||
m_puppetReferences.rightFoot = CloneTransform(l_avatarReferences.rightFoot, m_puppetReferences.rightLowerLeg, "RightFoot");
|
|
||||||
|
|
||||||
// Move to world origin to overcome possible issues
|
|
||||||
m_puppetRoot.position = Vector3.zero;
|
|
||||||
m_puppetRoot.rotation = Quaternion.identity;
|
|
||||||
|
|
||||||
BipedRagdollCreator.Options l_options = BipedRagdollCreator.AutodetectOptions(m_puppetReferences);
|
|
||||||
l_options.joints = RagdollCreator.JointType.Character;
|
|
||||||
BipedRagdollCreator.Create(m_puppetReferences, l_options);
|
|
||||||
|
|
||||||
Transform[] l_puppetTransforms = m_puppetReferences.GetRagdollTransforms();
|
|
||||||
Transform[] l_avatarTransforms = l_avatarReferences.GetRagdollTransforms();
|
|
||||||
Transform[] l_influencedTransforms = new Transform[] { m_puppetReferences.hips, m_puppetReferences.spine, m_puppetReferences.chest };
|
|
||||||
for(int i = 0; i < l_puppetTransforms.Length; i++)
|
|
||||||
{
|
{
|
||||||
if(l_puppetTransforms[i] != null)
|
StopCoroutine(m_initTask);
|
||||||
{
|
m_initTask = null;
|
||||||
CharacterJoint l_joint = l_puppetTransforms[i].GetComponent<CharacterJoint>();
|
|
||||||
if(l_joint != null)
|
|
||||||
{
|
|
||||||
l_joint.enablePreprocessing = false;
|
|
||||||
l_joint.enableProjection = true;
|
|
||||||
m_jointAnchors.Add(System.Tuple.Create(l_joint, l_joint.connectedAnchor));
|
|
||||||
}
|
|
||||||
|
|
||||||
Rigidbody l_body = l_puppetTransforms[i].GetComponent<Rigidbody>();
|
|
||||||
Collider l_collider = l_puppetTransforms[i].GetComponent<Collider>();
|
|
||||||
if((l_body != null) && (l_collider != null))
|
|
||||||
{
|
|
||||||
RagdollBodypartHandler l_handler = l_puppetTransforms[i].gameObject.AddComponent<RagdollBodypartHandler>();
|
|
||||||
l_handler.SetInfuencerUsage(Utils.IsInEnumeration(l_puppetTransforms[i], l_influencedTransforms));
|
|
||||||
m_ragdollBodyHandlers.Add(l_handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(l_avatarTransforms[i] != null)
|
|
||||||
m_boneLinks.Add(System.Tuple.Create(l_puppetTransforms[i], l_avatarTransforms[i]));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_vrIK = PlayerSetup.Instance.AvatarObject.GetComponent<VRIK>();
|
if(m_ragdolled)
|
||||||
if(m_vrIK != null)
|
{
|
||||||
m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostSolverUpdate);
|
TryRestoreMovement();
|
||||||
|
BodySystem.TrackingPositionWeight = 1f;
|
||||||
|
}
|
||||||
|
|
||||||
m_avatarRagdollToggle = PlayerSetup.Instance.AvatarObject.GetComponentInChildren<RagdollToggle>(true);
|
if(m_puppetRoot != null)
|
||||||
m_ragdolledParameter = new AvatarParameter("Ragdolled", PlayerSetup.Instance.AnimatorManager);
|
Object.Destroy(m_puppetRoot.gameObject);
|
||||||
|
m_puppetRoot = null;
|
||||||
|
|
||||||
m_initTask = StartCoroutine(WaitForBodyHandlers());
|
m_avatarTransform = null;
|
||||||
|
m_hips = null;
|
||||||
|
m_vrIK = null;
|
||||||
|
m_applyHipsPosition = false;
|
||||||
|
m_ragdolled = false;
|
||||||
|
m_avatarReady = false;
|
||||||
|
m_avatarRagdollToggle = null;
|
||||||
|
m_ragdolledParameter = null;
|
||||||
|
m_puppetReferences = new BipedRagdollReferences();
|
||||||
|
m_ragdollBodyHandlers.Clear();
|
||||||
|
m_boneLinks.Clear();
|
||||||
|
m_jointAnchors.Clear();
|
||||||
|
m_reachedGround = true;
|
||||||
|
m_groundedTime = 0f;
|
||||||
|
m_downTime = float.MinValue;
|
||||||
|
m_puppet.localScale = Vector3.one;
|
||||||
|
m_inAir = false;
|
||||||
|
}
|
||||||
|
catch(System.Exception e)
|
||||||
|
{
|
||||||
|
MelonLoader.MelonLogger.Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnAvatarSetup(CVRAvatar p_avatar)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if(PlayerSetup.Instance.Animator.isHuman)
|
||||||
|
{
|
||||||
|
m_avatarTransform = PlayerSetup.Instance.AvatarTransform;
|
||||||
|
m_hips = PlayerSetup.Instance.Animator.GetBoneTransform(HumanBodyBones.Hips);
|
||||||
|
Utils.SetAvatarTPose();
|
||||||
|
|
||||||
|
BipedRagdollReferences l_avatarReferences = BipedRagdollReferences.FromAvatar(PlayerSetup.Instance.Animator);
|
||||||
|
|
||||||
|
m_puppetRoot = new GameObject("Root").transform;
|
||||||
|
m_puppetRoot.gameObject.layer = CVRLayers.PlayerClone;
|
||||||
|
m_puppetRoot.parent = m_puppet;
|
||||||
|
m_puppetRoot.position = m_avatarTransform.position;
|
||||||
|
m_puppetRoot.rotation = m_avatarTransform.rotation;
|
||||||
|
|
||||||
|
m_puppetReferences.root = m_puppetRoot;
|
||||||
|
m_puppetReferences.hips = CloneTransform(l_avatarReferences.hips, m_puppetReferences.root, "Hips");
|
||||||
|
m_puppetReferences.spine = CloneTransform(l_avatarReferences.spine, m_puppetReferences.hips, "Spine");
|
||||||
|
|
||||||
|
if(l_avatarReferences.chest != null)
|
||||||
|
m_puppetReferences.chest = CloneTransform(l_avatarReferences.chest, m_puppetReferences.spine, "Chest");
|
||||||
|
|
||||||
|
m_puppetReferences.head = CloneTransform(l_avatarReferences.head, (m_puppetReferences.chest != null) ? m_puppetReferences.chest : m_puppetReferences.spine, "Head");
|
||||||
|
|
||||||
|
m_puppetReferences.leftUpperArm = CloneTransform(l_avatarReferences.leftUpperArm, (m_puppetReferences.chest != null) ? m_puppetReferences.chest : m_puppetReferences.spine, "LeftUpperArm");
|
||||||
|
m_puppetReferences.leftLowerArm = CloneTransform(l_avatarReferences.leftLowerArm, m_puppetReferences.leftUpperArm, "LeftLowerArm");
|
||||||
|
m_puppetReferences.leftHand = CloneTransform(l_avatarReferences.leftHand, m_puppetReferences.leftLowerArm, "LeftHand");
|
||||||
|
|
||||||
|
m_puppetReferences.rightUpperArm = CloneTransform(l_avatarReferences.rightUpperArm, (m_puppetReferences.chest != null) ? m_puppetReferences.chest : m_puppetReferences.spine, "RightUpperArm");
|
||||||
|
m_puppetReferences.rightLowerArm = CloneTransform(l_avatarReferences.rightLowerArm, m_puppetReferences.rightUpperArm, "RightLowerArm");
|
||||||
|
m_puppetReferences.rightHand = CloneTransform(l_avatarReferences.rightHand, m_puppetReferences.rightLowerArm, "RightHand");
|
||||||
|
|
||||||
|
m_puppetReferences.leftUpperLeg = CloneTransform(l_avatarReferences.leftUpperLeg, m_puppetReferences.hips, "LeftUpperLeg");
|
||||||
|
m_puppetReferences.leftLowerLeg = CloneTransform(l_avatarReferences.leftLowerLeg, m_puppetReferences.leftUpperLeg, "LeftLowerLeg");
|
||||||
|
m_puppetReferences.leftFoot = CloneTransform(l_avatarReferences.leftFoot, m_puppetReferences.leftLowerLeg, "LeftFoot");
|
||||||
|
|
||||||
|
m_puppetReferences.rightUpperLeg = CloneTransform(l_avatarReferences.rightUpperLeg, m_puppetReferences.hips, "RightUpperLeg");
|
||||||
|
m_puppetReferences.rightLowerLeg = CloneTransform(l_avatarReferences.rightLowerLeg, m_puppetReferences.rightUpperLeg, "RightLowerLeg");
|
||||||
|
m_puppetReferences.rightFoot = CloneTransform(l_avatarReferences.rightFoot, m_puppetReferences.rightLowerLeg, "RightFoot");
|
||||||
|
|
||||||
|
// Move to world origin to overcome possible issues
|
||||||
|
m_puppetRoot.position = Vector3.zero;
|
||||||
|
m_puppetRoot.rotation = Quaternion.identity;
|
||||||
|
|
||||||
|
BipedRagdollCreator.Options l_options = BipedRagdollCreator.AutodetectOptions(m_puppetReferences);
|
||||||
|
l_options.joints = RagdollCreator.JointType.Character;
|
||||||
|
BipedRagdollCreator.Create(m_puppetReferences, l_options);
|
||||||
|
|
||||||
|
Transform[] l_puppetTransforms = m_puppetReferences.GetRagdollTransforms();
|
||||||
|
Transform[] l_avatarTransforms = l_avatarReferences.GetRagdollTransforms();
|
||||||
|
Transform[] l_influencedTransforms = new Transform[] { m_puppetReferences.hips, m_puppetReferences.spine, m_puppetReferences.chest };
|
||||||
|
for(int i = 0; i < l_puppetTransforms.Length; i++)
|
||||||
|
{
|
||||||
|
if(l_puppetTransforms[i] != null)
|
||||||
|
{
|
||||||
|
CharacterJoint l_joint = l_puppetTransforms[i].GetComponent<CharacterJoint>();
|
||||||
|
if(l_joint != null)
|
||||||
|
{
|
||||||
|
l_joint.enablePreprocessing = false;
|
||||||
|
l_joint.enableProjection = true;
|
||||||
|
m_jointAnchors.Add(System.Tuple.Create(l_joint, l_joint.connectedAnchor));
|
||||||
|
}
|
||||||
|
|
||||||
|
Rigidbody l_body = l_puppetTransforms[i].GetComponent<Rigidbody>();
|
||||||
|
Collider l_collider = l_puppetTransforms[i].GetComponent<Collider>();
|
||||||
|
if((l_body != null) && (l_collider != null))
|
||||||
|
{
|
||||||
|
RagdollBodypartHandler l_handler = l_puppetTransforms[i].gameObject.AddComponent<RagdollBodypartHandler>();
|
||||||
|
l_handler.SetInfuencerUsage(Utils.IsInEnumeration(l_puppetTransforms[i], l_influencedTransforms));
|
||||||
|
m_ragdollBodyHandlers.Add(l_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(l_avatarTransforms[i] != null)
|
||||||
|
m_boneLinks.Add(System.Tuple.Create(l_puppetTransforms[i], l_avatarTransforms[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_vrIK = PlayerSetup.Instance.AvatarObject.GetComponent<VRIK>();
|
||||||
|
if(m_vrIK != null)
|
||||||
|
m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostSolverUpdate);
|
||||||
|
|
||||||
|
m_avatarRagdollToggle = PlayerSetup.Instance.AvatarObject.GetComponentInChildren<RagdollToggle>(true);
|
||||||
|
m_ragdolledParameter = new AvatarParameter("Ragdolled", PlayerSetup.Instance.AnimatorManager);
|
||||||
|
|
||||||
|
m_initTask = StartCoroutine(WaitForBodyHandlers());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(System.Exception e)
|
||||||
|
{
|
||||||
|
MelonLoader.MelonLogger.Error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue