mirror of
https://github.com/hanetzer/sdraw_mods_cvr.git
synced 2025-09-03 10:29:22 +00:00
Emotes custom detection
VRIK component checks for desktop mode Disable head rotation when emote is active
This commit is contained in:
parent
71c0068652
commit
4dafd9dcd7
9 changed files with 93 additions and 26 deletions
|
@ -4,8 +4,8 @@ Merged set of MelonLoader mods for ChilloutVR.
|
|||
| Full name | Short name | Latest version | Available in [CVRMA](https://github.com/knah/CVRMelonAssistant) | Current Status | Notes |
|
||||
|-----------|------------|----------------|-----------------------------------------------------------------|----------------|-------|
|
||||
| Avatar Change Info | ml_aci | 1.0.2 | Yes | Working |
|
||||
| Avatar Motion Tweaker | ml_amt | 1.1.1 | On review | Working |
|
||||
| Desktop Head Tracking | ml_dht | 1.0.4 | On review | Working |
|
||||
| Avatar Motion Tweaker | ml_amt | 1.1.2 | On review | Working |
|
||||
| Desktop Head Tracking | ml_dht | 1.0.5 | On review | Working |
|
||||
| Desktop Reticle Switch | ml_drs | 1.0.0 | Yes | Working |
|
||||
| Four Point Tracking | ml_fpt | 1.0.7 | On review | Working |
|
||||
| Leap Motion Extension | ml_lme | 1.2.0 | On review | Working |
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace ml_amt
|
|||
Settings.PoseTransitionsChange += this.OnPoseTransitonsChange;
|
||||
Settings.AdjustedMovementChange += this.OnAdjustedMovementChange;
|
||||
Settings.IKOverrideFlyChange += this.OnIKOverrideFlyChange;
|
||||
Settings.DetectEmotesChange += this.OnDetectEmotesChange;
|
||||
|
||||
HarmonyInstance.Patch(
|
||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.ClearAvatar)),
|
||||
|
@ -49,6 +50,7 @@ namespace ml_amt
|
|||
m_localTweaker.SetPoseTransitions(Settings.PoseTransitions);
|
||||
m_localTweaker.SetAdjustedMovement(Settings.AdjustedMovement);
|
||||
m_localTweaker.SetIKOverrideFly(Settings.IKOverrideFly);
|
||||
m_localTweaker.SetDetectEmotes(Settings.DetectEmotes);
|
||||
}
|
||||
|
||||
void OnIKOverrideCrouchChange(bool p_state)
|
||||
|
@ -86,6 +88,11 @@ namespace ml_amt
|
|||
if(m_localTweaker != null)
|
||||
m_localTweaker.SetIKOverrideFly(p_state);
|
||||
}
|
||||
void OnDetectEmotesChange(bool p_state)
|
||||
{
|
||||
if(m_localTweaker != null)
|
||||
m_localTweaker.SetDetectEmotes(p_state);
|
||||
}
|
||||
|
||||
static void OnAvatarClear_Postfix() => ms_instance?.OnAvatarClear();
|
||||
void OnAvatarClear()
|
||||
|
|
|
@ -2,14 +2,17 @@
|
|||
using ABI_RC.Systems.MovementSystem;
|
||||
using RootMotion.FinalIK;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ml_amt
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
class MotionTweaker : MonoBehaviour
|
||||
{
|
||||
static System.Reflection.FieldInfo ms_rootVelocity = typeof(IKSolverVR).GetField("rootVelocity", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
static System.Reflection.FieldInfo ms_groundedRaw = typeof(MovementSystem).GetField("_isGroundedRaw", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
static readonly FieldInfo ms_rootVelocity = typeof(IKSolverVR).GetField("rootVelocity", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
static readonly FieldInfo ms_groundedRaw = typeof(MovementSystem).GetField("_isGroundedRaw", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
static readonly int ms_emoteHash = Animator.StringToHash("Emote");
|
||||
|
||||
enum ParameterType
|
||||
{
|
||||
|
@ -41,6 +44,8 @@ namespace ml_amt
|
|||
static readonly Vector4 ms_pointVector = new Vector4(0f, 0f, 0f, 1f);
|
||||
|
||||
VRIK m_vrIk = null;
|
||||
int m_locomotionLayer = 0;
|
||||
float m_ikWeight = 1f; // Original weight
|
||||
float m_locomotionWeight = 1f; // Original weight
|
||||
float m_avatarScale = 1f; // Instantiated scale
|
||||
|
||||
|
@ -64,6 +69,9 @@ namespace ml_amt
|
|||
bool m_customLocomotionOffset = false;
|
||||
Vector3 m_locomotionOffset = Vector3.zero;
|
||||
|
||||
bool m_detectEmotes = true;
|
||||
bool m_emoteActive = false;
|
||||
|
||||
readonly List<AdditionalParameterInfo> m_parameters = null;
|
||||
|
||||
public MotionTweaker()
|
||||
|
@ -83,7 +91,7 @@ namespace ml_amt
|
|||
m_upright = Mathf.Clamp(((l_avatarViewHeight > 0f) ? (l_currentHeight / l_avatarViewHeight) : 0f), 0f, 1f);
|
||||
PoseState l_poseState = (m_upright <= m_proneLimit) ? PoseState.Proning : ((m_upright <= m_crouchLimit) ? PoseState.Crouching : PoseState.Standing);
|
||||
|
||||
if((m_vrIk != null) && m_vrIk.enabled)
|
||||
if(PlayerSetup.Instance._inVr && (m_vrIk != null) && m_vrIk.enabled)
|
||||
{
|
||||
if(m_poseState != l_poseState)
|
||||
{
|
||||
|
@ -115,6 +123,14 @@ namespace ml_amt
|
|||
|
||||
m_poseState = l_poseState;
|
||||
|
||||
if(m_detectEmotes && (m_locomotionLayer >= 0))
|
||||
{
|
||||
AnimatorStateInfo l_animState = PlayerSetup.Instance._animator.GetCurrentAnimatorStateInfo(m_locomotionLayer);
|
||||
m_emoteActive = (l_animState.tagHash == ms_emoteHash);
|
||||
}
|
||||
else
|
||||
m_emoteActive = false;
|
||||
|
||||
if(m_parameters.Count > 0)
|
||||
{
|
||||
foreach(AdditionalParameterInfo l_param in m_parameters)
|
||||
|
@ -129,7 +145,7 @@ namespace ml_amt
|
|||
PlayerSetup.Instance._animator.SetFloat(l_param.m_hash, m_upright);
|
||||
break;
|
||||
case ParameterSyncType.Synced:
|
||||
PlayerSetup.Instance.changeAnimatorParam(l_param.m_name, m_upright);
|
||||
PlayerSetup.Instance.animatorManager.SetAnimatorParameterFloat(l_param.m_name, m_upright);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -143,7 +159,7 @@ namespace ml_amt
|
|||
PlayerSetup.Instance._animator.SetBool(l_param.m_hash, (bool)ms_groundedRaw.GetValue(MovementSystem.Instance));
|
||||
break;
|
||||
case ParameterSyncType.Synced:
|
||||
PlayerSetup.Instance.changeAnimatorParam(l_param.m_name, (bool)ms_groundedRaw.GetValue(MovementSystem.Instance) ? 1f : 0f);
|
||||
PlayerSetup.Instance.animatorManager.SetAnimatorParameterBool(l_param.m_name, (bool)ms_groundedRaw.GetValue(MovementSystem.Instance));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -157,6 +173,7 @@ namespace ml_amt
|
|||
public void OnAvatarClear()
|
||||
{
|
||||
m_vrIk = null;
|
||||
m_locomotionLayer = -1;
|
||||
m_avatarReady = false;
|
||||
m_compatibleAvatar = false;
|
||||
m_poseState = PoseState.Standing;
|
||||
|
@ -165,12 +182,14 @@ namespace ml_amt
|
|||
m_customLocomotionOffset = false;
|
||||
m_locomotionOffset = Vector3.zero;
|
||||
m_avatarScale = 1f;
|
||||
m_emoteActive = false;
|
||||
m_parameters.Clear();
|
||||
}
|
||||
|
||||
public void OnCalibrateAvatar()
|
||||
{
|
||||
m_vrIk = PlayerSetup.Instance._avatar.GetComponent<VRIK>();
|
||||
m_locomotionLayer = PlayerSetup.Instance._animator.GetLayerIndex("Locomotion/Emotes");
|
||||
|
||||
// Parse animator parameters
|
||||
AnimatorControllerParameter[] l_params = PlayerSetup.Instance._animator.parameters;
|
||||
|
@ -227,16 +246,24 @@ namespace ml_amt
|
|||
|
||||
void OnIKPreUpdate()
|
||||
{
|
||||
m_ikWeight = m_vrIk.solver.IKPositionWeight;
|
||||
m_locomotionWeight = m_vrIk.solver.locomotion.weight;
|
||||
|
||||
if((m_ikOverrideCrouch && (m_poseState != PoseState.Standing)) || (m_ikOverrideProne && (m_poseState == PoseState.Proning)))
|
||||
m_vrIk.solver.locomotion.weight = 0f;
|
||||
if(m_ikOverrideFly && MovementSystem.Instance.flying)
|
||||
m_vrIk.solver.locomotion.weight = 0f;
|
||||
if(m_detectEmotes && m_emoteActive)
|
||||
m_vrIk.solver.IKPositionWeight = 0f;
|
||||
|
||||
if(PlayerSetup.Instance._inVr)
|
||||
{
|
||||
if((m_ikOverrideCrouch && (m_poseState != PoseState.Standing)) || (m_ikOverrideProne && (m_poseState == PoseState.Proning)))
|
||||
m_vrIk.solver.locomotion.weight = 0f;
|
||||
if(m_ikOverrideFly && MovementSystem.Instance.flying)
|
||||
m_vrIk.solver.locomotion.weight = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
void OnIKPostUpdate()
|
||||
{
|
||||
m_vrIk.solver.IKPositionWeight = m_ikWeight;
|
||||
m_vrIk.solver.locomotion.weight = m_locomotionWeight;
|
||||
}
|
||||
|
||||
|
@ -282,5 +309,9 @@ namespace ml_amt
|
|||
{
|
||||
m_ikOverrideFly = p_state;
|
||||
}
|
||||
public void SetDetectEmotes(bool p_state)
|
||||
{
|
||||
m_detectEmotes = p_state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyTitle("AvatarMotionTweaker")]
|
||||
[assembly: AssemblyVersion("1.1.1")]
|
||||
[assembly: AssemblyFileVersion("1.1.1")]
|
||||
[assembly: AssemblyVersion("1.1.2")]
|
||||
[assembly: AssemblyFileVersion("1.1.2")]
|
||||
|
||||
[assembly: MelonLoader.MelonInfo(typeof(ml_amt.AvatarMotionTweaker), "AvatarMotionTweaker", "1.1.1", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
||||
[assembly: MelonLoader.MelonInfo(typeof(ml_amt.AvatarMotionTweaker), "AvatarMotionTweaker", "1.1.2", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
||||
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
||||
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||
[assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
|
@ -15,7 +15,8 @@ namespace ml_amt
|
|||
ProneLimit,
|
||||
PoseTransitions,
|
||||
AdjustedMovement,
|
||||
IKOverrideFly
|
||||
IKOverrideFly,
|
||||
DetectEmotes
|
||||
};
|
||||
|
||||
static bool ms_ikOverrideCrouch = true;
|
||||
|
@ -25,6 +26,7 @@ namespace ml_amt
|
|||
static bool ms_poseTransitions = true;
|
||||
static bool ms_adjustedMovement = true;
|
||||
static bool ms_ikOverrideFly = true;
|
||||
static bool ms_detectEmotes = true;
|
||||
|
||||
static MelonLoader.MelonPreferences_Category ms_category = null;
|
||||
static List<MelonLoader.MelonPreferences_Entry> ms_entries = null;
|
||||
|
@ -36,6 +38,7 @@ namespace ml_amt
|
|||
static public event Action<bool> PoseTransitionsChange;
|
||||
static public event Action<bool> AdjustedMovementChange;
|
||||
static public event Action<bool> IKOverrideFlyChange;
|
||||
static public event Action<bool> DetectEmotesChange;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
|
@ -49,6 +52,7 @@ namespace ml_amt
|
|||
ms_entries.Add(ms_category.CreateEntry(ModSetting.PoseTransitions.ToString(), true));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.AdjustedMovement.ToString(), true));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.IKOverrideFly.ToString(), true));
|
||||
ms_entries.Add(ms_category.CreateEntry(ModSetting.DetectEmotes.ToString(), true));
|
||||
|
||||
Load();
|
||||
|
||||
|
@ -86,6 +90,7 @@ namespace ml_amt
|
|||
ms_poseTransitions = (bool)ms_entries[(int)ModSetting.PoseTransitions].BoxedValue;
|
||||
ms_adjustedMovement = (bool)ms_entries[(int)ModSetting.AdjustedMovement].BoxedValue;
|
||||
ms_ikOverrideFly = (bool)ms_entries[(int)ModSetting.IKOverrideFly].BoxedValue;
|
||||
ms_detectEmotes = (bool)ms_entries[(int)ModSetting.DetectEmotes].BoxedValue;
|
||||
}
|
||||
|
||||
static void OnSliderUpdate(string p_name, string p_value)
|
||||
|
@ -152,6 +157,13 @@ namespace ml_amt
|
|||
ms_ikOverrideFly = bool.Parse(p_value);
|
||||
IKOverrideFlyChange?.Invoke(ms_ikOverrideFly);
|
||||
} break;
|
||||
|
||||
case ModSetting.DetectEmotes:
|
||||
{
|
||||
ms_detectEmotes = bool.Parse(p_value);
|
||||
DetectEmotesChange?.Invoke(ms_detectEmotes);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ms_entries[(int)l_setting].BoxedValue = bool.Parse(p_value);
|
||||
|
@ -186,5 +198,9 @@ namespace ml_amt
|
|||
{
|
||||
get => ms_ikOverrideFly;
|
||||
}
|
||||
public static bool DetectEmotes
|
||||
{
|
||||
get => ms_detectEmotes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -228,6 +228,13 @@ function inp_toggle_mod_amt(_obj, _callbackName) {
|
|||
<div id="AdjustedMovement" class ="inp_toggle no-scroll" data-current="true"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class ="row-wrapper">
|
||||
<div class ="option-caption">Detect animations emote tag: </div>
|
||||
<div class ="option-input">
|
||||
<div id="DetectEmotes" class ="inp_toggle no-scroll" data-current="true"></div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
document.getElementById('settings-implementation').appendChild(l_block);
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using ABI.CCK.Components;
|
||||
using ABI_RC.Core.Player;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ml_dht
|
||||
|
@ -7,6 +8,8 @@ namespace ml_dht
|
|||
[DisallowMultipleComponent]
|
||||
class HeadTracked : MonoBehaviour
|
||||
{
|
||||
static FieldInfo ms_emotePlaying = typeof(PlayerSetup).GetField("_emotePlaying", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
bool m_enabled = false;
|
||||
float m_smoothing = 0.5f;
|
||||
bool m_mirrored = false;
|
||||
|
@ -47,7 +50,9 @@ namespace ml_dht
|
|||
if(m_enabled && (m_headBone != null))
|
||||
{
|
||||
m_lastHeadRotation = Quaternion.Slerp(m_lastHeadRotation, m_avatarDescriptor.transform.rotation * (m_headRotation * m_bindRotation), m_smoothing);
|
||||
m_headBone.rotation = m_lastHeadRotation;
|
||||
|
||||
if(!(bool)ms_emotePlaying.GetValue(PlayerSetup.Instance))
|
||||
m_headBone.rotation = m_lastHeadRotation;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,7 +76,7 @@ namespace ml_dht
|
|||
{
|
||||
if(m_avatarDescriptor != null)
|
||||
m_avatarDescriptor.useVisemeLipsync = false;
|
||||
|
||||
|
||||
float l_weight = Mathf.Clamp(Mathf.InverseLerp(0.25f, 1f, Mathf.Abs(m_mouthShapes.y)), 0f, 1f) * 100f;
|
||||
|
||||
p_component.BlendShapeValues[(int)ViveSR.anipal.Lip.LipShape_v2.Jaw_Open] = m_mouthShapes.x * 100f;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using ABI.CCK.Components;
|
||||
using ABI_RC.Core.Player;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ml_dht
|
||||
{
|
||||
|
@ -33,22 +34,22 @@ namespace ml_dht
|
|||
HarmonyInstance.Patch(
|
||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.ClearAvatar)),
|
||||
null,
|
||||
new HarmonyLib.HarmonyMethod(typeof(DesktopHeadTracking).GetMethod(nameof(OnAvatarClear_Postfix), System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic))
|
||||
new HarmonyLib.HarmonyMethod(typeof(DesktopHeadTracking).GetMethod(nameof(OnAvatarClear_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
||||
);
|
||||
HarmonyInstance.Patch(
|
||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.CalibrateAvatar)),
|
||||
null,
|
||||
new HarmonyLib.HarmonyMethod(typeof(DesktopHeadTracking).GetMethod(nameof(OnCalibrateAvatar_Postfix), System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic))
|
||||
new HarmonyLib.HarmonyMethod(typeof(DesktopHeadTracking).GetMethod(nameof(OnCalibrateAvatar_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
||||
);
|
||||
HarmonyInstance.Patch(
|
||||
typeof(CVREyeController).GetMethod("Update", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic),
|
||||
typeof(CVREyeController).GetMethod("Update", BindingFlags.Instance | BindingFlags.NonPublic),
|
||||
null,
|
||||
new HarmonyLib.HarmonyMethod(typeof(DesktopHeadTracking).GetMethod(nameof(OnEyeControllerUpdate_Postfix), System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic))
|
||||
new HarmonyLib.HarmonyMethod(typeof(DesktopHeadTracking).GetMethod(nameof(OnEyeControllerUpdate_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
||||
);
|
||||
HarmonyInstance.Patch(
|
||||
typeof(CVRFaceTracking).GetMethod("Update", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic),
|
||||
typeof(CVRFaceTracking).GetMethod("Update", BindingFlags.Instance | BindingFlags.NonPublic),
|
||||
null,
|
||||
new HarmonyLib.HarmonyMethod(typeof(DesktopHeadTracking).GetMethod(nameof(OnFaceTrackingUpdate_Postfix), System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic))
|
||||
new HarmonyLib.HarmonyMethod(typeof(DesktopHeadTracking).GetMethod(nameof(OnFaceTrackingUpdate_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
||||
);
|
||||
|
||||
MelonLoader.MelonCoroutines.Start(WaitForPlayer());
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyTitle("DesktopHeadTracking")]
|
||||
[assembly: AssemblyVersion("1.0.4")]
|
||||
[assembly: AssemblyFileVersion("1.0.4")]
|
||||
[assembly: AssemblyVersion("1.0.5")]
|
||||
[assembly: AssemblyFileVersion("1.0.5")]
|
||||
|
||||
[assembly: MelonLoader.MelonInfo(typeof(ml_dht.DesktopHeadTracking), "DesktopHeadTracking", "1.0.4", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
||||
[assembly: MelonLoader.MelonInfo(typeof(ml_dht.DesktopHeadTracking), "DesktopHeadTracking", "1.0.5", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
||||
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
||||
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||
[assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
Loading…
Add table
Add a link
Reference in a new issue