diff --git a/ml_amt/AvatarParameter.cs b/ml_amt/AvatarParameter.cs index 3349104..7bec1d3 100644 --- a/ml_amt/AvatarParameter.cs +++ b/ml_amt/AvatarParameter.cs @@ -1,4 +1,6 @@ -using ABI_RC.Core.Player; +using ABI_RC.Core; +using System.Text.RegularExpressions; +using UnityEngine; namespace ml_amt { @@ -11,24 +13,30 @@ namespace ml_amt Moving } - public enum ParameterSyncType - { - Synced, - Local - } + readonly ParameterType m_type; + readonly string m_name; + readonly int m_hash = 0; + readonly bool m_sync; + readonly AnimatorControllerParameterType m_innerType; + readonly CVRAnimatorManager m_manager = null; - public readonly ParameterType m_type; - public readonly ParameterSyncType m_sync; - public readonly string m_name; - public readonly int m_hash; // For local only - - - public AvatarParameter(ParameterType p_type, string p_name, ParameterSyncType p_sync = ParameterSyncType.Synced, int p_hash = 0) + public AvatarParameter(ParameterType p_type, CVRAnimatorManager p_manager) { m_type = p_type; - m_sync = p_sync; - m_name = p_name; - m_hash = p_hash; + m_name = p_type.ToString(); + m_manager = p_manager; + + Regex l_regex = new Regex("^#?" + m_name + '$'); + foreach(var l_param in m_manager.animator.parameters) + { + if(l_regex.IsMatch(l_param.name)) + { + m_hash = l_param.nameHash; + m_sync = (l_param.name[0] != '#'); + m_innerType = l_param.type; + break; + } + } } public void Update(MotionTweaker p_tweaker) @@ -49,29 +57,28 @@ namespace ml_amt } } + public bool IsValid() => (m_hash != 0); + public ParameterType GetParameterType() => m_type; + void SetFloat(float p_value) { - switch(m_sync) + if(m_innerType == AnimatorControllerParameterType.Float) { - case ParameterSyncType.Local: - PlayerSetup.Instance._animator.SetFloat(m_hash, p_value); - break; - case ParameterSyncType.Synced: - PlayerSetup.Instance.animatorManager.SetAnimatorParameterFloat(m_name, p_value); - break; + if(m_sync) + m_manager.SetAnimatorParameterFloat(m_name, p_value); + else + m_manager.animator.SetFloat(m_hash, p_value); } } void SetBoolean(bool p_value) { - switch(m_sync) + if(m_innerType == AnimatorControllerParameterType.Bool) { - case ParameterSyncType.Local: - PlayerSetup.Instance._animator.SetBool(m_hash, p_value); - break; - case ParameterSyncType.Synced: - PlayerSetup.Instance.animatorManager.SetAnimatorParameterBool(m_name, p_value); - break; + if(m_sync) + m_manager.SetAnimatorParameterBool(m_name, p_value); + else + m_manager.animator.SetBool(m_hash, p_value); } } } diff --git a/ml_amt/MotionTweaker.cs b/ml_amt/MotionTweaker.cs index ec6e487..11e9ffb 100644 --- a/ml_amt/MotionTweaker.cs +++ b/ml_amt/MotionTweaker.cs @@ -208,28 +208,12 @@ namespace ml_amt m_viewPointHeight = PlayerSetup.Instance._avatar.GetComponent().viewPosition.y; // Parse animator parameters - AnimatorControllerParameter[] l_params = PlayerSetup.Instance._animator.parameters; - foreach(var l_param in l_params) - { - foreach(AvatarParameter.ParameterType l_enumParam in System.Enum.GetValues(typeof(AvatarParameter.ParameterType))) - { - if(l_param.name.Contains(l_enumParam.ToString()) && (m_parameters.FindIndex(p => p.m_type == l_enumParam) == -1)) - { - bool l_local = (l_param.name[0] == '#'); + m_parameters.Add(new AvatarParameter(AvatarParameter.ParameterType.Upright, PlayerSetup.Instance.animatorManager)); + m_parameters.Add(new AvatarParameter(AvatarParameter.ParameterType.GroundedRaw, PlayerSetup.Instance.animatorManager)); + m_parameters.Add(new AvatarParameter(AvatarParameter.ParameterType.Moving, PlayerSetup.Instance.animatorManager)); + m_parameters.RemoveAll(p => !p.IsValid()); - m_parameters.Add(new AvatarParameter( - l_enumParam, - l_param.name, - (l_local ? AvatarParameter.ParameterSyncType.Local : AvatarParameter.ParameterSyncType.Synced), - (l_local ? l_param.nameHash : 0) - )); - - break; - } - } - } - - m_compatibleAvatar = m_parameters.Exists(p => p.m_type == AvatarParameter.ParameterType.Upright); + m_compatibleAvatar = m_parameters.Exists(p => (p.GetParameterType() == AvatarParameter.ParameterType.Upright)); m_avatarScale = Mathf.Abs(PlayerSetup.Instance._avatar.transform.localScale.y); Transform l_customTransform = PlayerSetup.Instance._avatar.transform.Find("CrouchLimit"); diff --git a/ml_amt/README.md b/ml_amt/README.md index b717c77..86c02a4 100644 --- a/ml_amt/README.md +++ b/ml_amt/README.md @@ -38,9 +38,9 @@ Available additional parameters for AAS animator: * Note: Can be set as local-only (not synced) if starts with `#` character. * Note: Defining this parameter in AAS animator will consider avatar as compatible with mod. * Note: Can't be used for transitions between poses in desktop mode. In desktop mode its value is driven by avatar animations. Use `CVR Parameter Stream` for detecting desktop/VR modes and change AAS animator transitions accordingly. -* **`GroundedRaw`:** defines instant grounding state of player instead of delayed default parameter `Grounded`. +* **`GroundedRaw`:** defines instant grounding state of player instead of delayed default parameter `Grounded`; boolean. * Note: Can be set as local-only (not synced) if starts with `#` character. -* **`Moving`:** defines movement state of player +* **`Moving`:** defines movement state of player; boolean. * Note: Can be set as local-only (not synced) if starts with `#` character. Additional mod's behaviour: diff --git a/ml_prm/AvatarBoolParameter.cs b/ml_prm/AvatarBoolParameter.cs new file mode 100644 index 0000000..b7a9535 --- /dev/null +++ b/ml_prm/AvatarBoolParameter.cs @@ -0,0 +1,43 @@ +using ABI_RC.Core; +using System.Text.RegularExpressions; +using UnityEngine; + +namespace ml_prm +{ + class AvatarBoolParameter + { + public readonly string m_name; + public readonly int m_hash = 0; + public readonly bool m_sync; + readonly CVRAnimatorManager m_manager = null; + + public AvatarBoolParameter(string p_name, CVRAnimatorManager p_manager) + { + m_name = p_name; + m_manager = p_manager; + + Regex l_regex = new Regex("^#?" + p_name + '$'); + foreach(var l_param in m_manager.animator.parameters) + { + if(l_regex.IsMatch(l_param.name) && (l_param.type == AnimatorControllerParameterType.Bool)) + { + m_name = l_param.name; + m_hash = l_param.nameHash; + m_sync = (l_param.name[0] != '#'); + break; + } + } + } + + public void SetValue(bool p_value) + { + if(m_hash != 0) + { + if(m_sync) + m_manager.SetAnimatorParameterBool(m_name, p_value); + else + m_manager.animator.SetBool(m_hash, p_value); + } + } + } +} diff --git a/ml_prm/README.md b/ml_prm/README.md index fb8142a..d0773bf 100644 --- a/ml_prm/README.md +++ b/ml_prm/README.md @@ -24,6 +24,10 @@ Optional mod's settings with [BTKUILib](https://github.com/BTK-Development/BTKUI * **Angular movement drag:** angular movement resistance; `2.0` by default. * **Reset settings:** resets mod settings to default. +Available additional parameters for AAS animator: +* **`Ragdolled`:** defines current ragdoll state; boolean. + * Note: Can be set as local-only (not synced) if starts with `#` character. + # Unity Editor Script You can also trigger the ragdoll via animations on your avatar. To do this you need: * Download and import the `ml_prm_editor_script.unitypackage` into your unity project diff --git a/ml_prm/RagdollController.cs b/ml_prm/RagdollController.cs index c66e8bd..e4e2d87 100644 --- a/ml_prm/RagdollController.cs +++ b/ml_prm/RagdollController.cs @@ -33,6 +33,7 @@ namespace ml_prm RagdollToggle m_avatarRagdollToggle = null; RagdollTrigger m_customTrigger = null; + AvatarBoolParameter m_ragdolledParameter = null; bool m_reachedGround = true; @@ -129,6 +130,7 @@ namespace ml_prm m_enabled = false; m_avatarReady = false; m_avatarRagdollToggle = null; + m_ragdolledParameter = null; m_rigidBodies.Clear(); m_colliders.Clear(); m_puppetReferences = new BipedRagdollReferences(); @@ -231,6 +233,7 @@ namespace ml_prm } m_avatarRagdollToggle = PlayerSetup.Instance._avatar.GetComponentInChildren(true); + m_ragdolledParameter = new AvatarBoolParameter("Ragdolled", PlayerSetup.Instance.animatorManager); m_avatarReady = true; } @@ -336,6 +339,7 @@ namespace ml_prm MovementSystem.Instance.SetImmobilized(true); PlayerSetup.Instance.animatorManager.SetAnimatorParameterTrigger("CancelEmote"); + m_ragdolledParameter.SetValue(true); if(BodySystem.isCalibratedAsFullBody) BodySystem.TrackingPositionWeight = 0f; @@ -368,6 +372,7 @@ namespace ml_prm if(IsSafeToUnragdoll()) { MovementSystem.Instance.SetImmobilized(false); + m_ragdolledParameter.SetValue(false); if(BodySystem.isCalibratedAsFullBody) BodySystem.TrackingPositionWeight = 1f; diff --git a/ml_prm/ml_prm.csproj b/ml_prm/ml_prm.csproj index 4a041d1..33450f6 100644 --- a/ml_prm/ml_prm.csproj +++ b/ml_prm/ml_prm.csproj @@ -86,6 +86,7 @@ +