diff --git a/ml_prm/Main.cs b/ml_prm/Main.cs index 06479de..75852e7 100644 --- a/ml_prm/Main.cs +++ b/ml_prm/Main.cs @@ -3,7 +3,9 @@ using ABI_RC.Core.InteractionSystem; using ABI_RC.Core.Player; using ABI_RC.Systems.IK.SubSystems; using System; +using System.Collections.Generic; using System.Reflection; +using ABI_RC.Core.Util.AssetFiltering; namespace ml_prm { @@ -46,6 +48,10 @@ namespace ml_prm null ); + // Whitelist the toggle script + var l_localComponentWhitelist = typeof(SharedFilter).GetField("_localComponentWhitelist", BindingFlags.NonPublic | BindingFlags.Static)!.GetValue(null) as HashSet; + l_localComponentWhitelist!.Add(typeof(RagdollToggle)); + MelonLoader.MelonCoroutines.Start(WaitForLocalPlayer()); } diff --git a/ml_prm/README.md b/ml_prm/README.md index 0adf8e9..c7a45f0 100644 --- a/ml_prm/README.md +++ b/ml_prm/README.md @@ -24,3 +24,15 @@ Optional mod's settings with [BTKUILib](https://github.com/BTK-Development/BTKUI * Not suggested to activate fly mode with enabled ragdoll state. * Can't be activated in worlds that don't allow flying and spawnables. * If ragdoll state is enabled in during emote, remote players see whole emote playing while local player sees ragdolling. It's tied to how game handles remote players, currently can be prevented with renaming avatar emote animations to not have default name or containing `Emote` substring. + +# Unity Editor Script +You can also trigger the ragdoll via animations on your avatar. To do this you need to download and import the +`ml_prm_editor_script.unitypackage` into your unity project. Then add the component `Ragdoll Toggle` anywhere inside of +your avatar's hierarchy. Now you can animate both parameters available: + +- **Should Override:** Whether the animation should override the toggled state of the ragdoll. +- **Is On:** Whether the ragdoll state is On or Off (only works if `Should Override` is also On). + +![](resources/ragdoll_toggle_editor_script.png) + +**Note:** In order to work the game object needs to be active and the component enabled. diff --git a/ml_prm/RagdollController.cs b/ml_prm/RagdollController.cs index 6c7d2ab..ecd7fdc 100644 --- a/ml_prm/RagdollController.cs +++ b/ml_prm/RagdollController.cs @@ -30,6 +30,8 @@ namespace ml_prm Vector3 m_lastPosition = Vector3.zero; Vector3 m_velocity = Vector3.zero; + RagdollToggle m_avatarRagdollToggle = null; + internal RagdollController() { m_rigidBodies = new List(); @@ -67,6 +69,11 @@ namespace ml_prm if(Settings.Hotkey && Input.GetKeyDown(KeyCode.R) && !ViewManager.Instance.isGameMenuOpen()) SwitchRagdoll(); + + if (m_avatarRagdollToggle != null && m_avatarRagdollToggle.isActiveAndEnabled && m_avatarRagdollToggle.shouldOverride) { + if (m_enabled != m_avatarRagdollToggle.isOn) + SwitchRagdoll(); + } } void LateUpdate() @@ -182,6 +189,8 @@ namespace ml_prm m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate); } + m_avatarRagdollToggle = PlayerSetup.Instance._avatar.GetComponentInChildren(true); + m_avatarReady = true; } } diff --git a/ml_prm/RagdollToggle.cs b/ml_prm/RagdollToggle.cs new file mode 100644 index 0000000..63343a2 --- /dev/null +++ b/ml_prm/RagdollToggle.cs @@ -0,0 +1,12 @@ +using UnityEngine; + +namespace ml_prm +{ + public class RagdollToggle : MonoBehaviour + { + [Tooltip("Whether or not is should use the isOn property to override the current Ragdoll State of the Avatar.")] + [SerializeField] public bool shouldOverride; + [Tooltip("Whether Ragdoll State is active or not on the Avatar. Requires shouldOverride to be true to work.")] + [SerializeField] public bool isOn; + } +} diff --git a/ml_prm/ml_prm_editor_script.unitypackage b/ml_prm/ml_prm_editor_script.unitypackage new file mode 100644 index 0000000..7efa884 Binary files /dev/null and b/ml_prm/ml_prm_editor_script.unitypackage differ diff --git a/ml_prm/resources/ragdoll_toggle_editor_script.png b/ml_prm/resources/ragdoll_toggle_editor_script.png new file mode 100644 index 0000000..0bc9e5d Binary files /dev/null and b/ml_prm/resources/ragdoll_toggle_editor_script.png differ