mirror of
https://github.com/hanetzer/sdraw_mods_cvr.git
synced 2025-09-03 18:39:23 +00:00
Instance set changes
Additional animator parameters Reworked rigidbodies Update to latest LeapC and LeapCSharp
This commit is contained in:
parent
1f0b518761
commit
075ff67304
38 changed files with 8310 additions and 8646 deletions
|
@ -1,253 +1,253 @@
|
|||
using ABI.CCK.Components;
|
||||
using ABI_RC.Core;
|
||||
using ABI_RC.Core.InteractionSystem;
|
||||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Systems.IK;
|
||||
using ABI_RC.Systems.IK.SubSystems;
|
||||
using ABI_RC.Systems.Movement;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ml_prm
|
||||
{
|
||||
static class GameEvents
|
||||
{
|
||||
internal class EventResult
|
||||
{
|
||||
public bool m_result = false;
|
||||
}
|
||||
internal class GameEvent
|
||||
{
|
||||
event Action m_action;
|
||||
public void AddHandler(Action p_listener) => m_action += p_listener;
|
||||
public void RemoveHandler(Action p_listener) => m_action -= p_listener;
|
||||
public void Invoke() => m_action?.Invoke();
|
||||
}
|
||||
internal class GameEvent<T1>
|
||||
{
|
||||
event Action<T1> m_action;
|
||||
public void AddHandler(Action<T1> p_listener) => m_action += p_listener;
|
||||
public void RemoveHandler(Action<T1> p_listener) => m_action -= p_listener;
|
||||
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 OnAvatarPostReuse = new GameEvent();
|
||||
public static readonly GameEvent<float> OnIKScaling = new GameEvent<float>();
|
||||
public static readonly GameEvent<CVRSeat> OnSeatPreSit = new GameEvent<CVRSeat>();
|
||||
public static readonly GameEvent OnCalibrationStart = new GameEvent();
|
||||
public static readonly GameEvent OnWorldPreSpawn = new GameEvent();
|
||||
public static readonly GameEvent OnCombatPreDown = new GameEvent();
|
||||
public static readonly GameEvent OnFlightChange = new GameEvent();
|
||||
public static readonly GameEvent<EventResult> OnIKOffsetUpdate = new GameEvent<EventResult>();
|
||||
|
||||
static readonly EventResult ms_result = new EventResult();
|
||||
|
||||
internal static void Init(HarmonyLib.Harmony p_instance)
|
||||
{
|
||||
try
|
||||
{
|
||||
p_instance.Patch(
|
||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.ClearAvatar)),
|
||||
null,
|
||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnAvatarClear_Postfix), BindingFlags.NonPublic | BindingFlags.Static))
|
||||
);
|
||||
|
||||
p_instance.Patch(
|
||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.SetupAvatar)),
|
||||
null,
|
||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnSetupAvatar_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
||||
);
|
||||
|
||||
p_instance.Patch(
|
||||
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_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
||||
);
|
||||
|
||||
p_instance.Patch(
|
||||
typeof(PlayerSetup).GetMethod("SetupIKScaling", BindingFlags.NonPublic | BindingFlags.Instance),
|
||||
null,
|
||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnSetupIKScaling_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
||||
);
|
||||
|
||||
p_instance.Patch(
|
||||
typeof(CVRSeat).GetMethod(nameof(CVRSeat.SitDown)),
|
||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnCVRSeatSitDown_Prefix), BindingFlags.Static | BindingFlags.NonPublic)),
|
||||
null
|
||||
);
|
||||
|
||||
p_instance.Patch(
|
||||
typeof(BodySystem).GetMethod(nameof(BodySystem.StartCalibration)),
|
||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnStartCalibration_Prefix), BindingFlags.Static | BindingFlags.NonPublic)),
|
||||
null
|
||||
);
|
||||
|
||||
p_instance.Patch(
|
||||
typeof(RootLogic).GetMethod(nameof(RootLogic.SpawnOnWorldInstance)),
|
||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnWorldSpawn_Prefix), BindingFlags.Static | BindingFlags.NonPublic)),
|
||||
null
|
||||
);
|
||||
|
||||
p_instance.Patch(
|
||||
typeof(CombatSystem).GetMethods().First(m => (!m.IsGenericMethod && m.Name == nameof(CombatSystem.Down))),
|
||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnCombatDown_Prefix), BindingFlags.Static | BindingFlags.NonPublic)),
|
||||
null
|
||||
);
|
||||
|
||||
p_instance.Patch(
|
||||
typeof(BetterBetterCharacterController).GetMethod(nameof(BetterBetterCharacterController.ChangeFlight)),
|
||||
null,
|
||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnChangeFlight_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
||||
);
|
||||
|
||||
p_instance.Patch(
|
||||
typeof(IKSystem).GetMethod("OnPreSolverUpdateActiveOffset", BindingFlags.Instance | BindingFlags.NonPublic),
|
||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnOffsetUpdate_Prefix), BindingFlags.Static | BindingFlags.NonPublic))
|
||||
);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
try
|
||||
{
|
||||
OnAvatarPreReuse.Invoke();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnAvatarReinitialize_Postfix()
|
||||
{
|
||||
try
|
||||
{
|
||||
OnAvatarPostReuse.Invoke();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnSetupIKScaling_Postfix(ref UnityEngine.Vector3 ___scaleDifference)
|
||||
{
|
||||
try
|
||||
{
|
||||
OnIKScaling.Invoke(1f + ___scaleDifference.y);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnCVRSeatSitDown_Prefix(ref CVRSeat __instance)
|
||||
{
|
||||
try
|
||||
{
|
||||
OnSeatPreSit.Invoke(__instance);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnStartCalibration_Prefix()
|
||||
{
|
||||
try
|
||||
{
|
||||
OnCalibrationStart.Invoke();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnWorldSpawn_Prefix()
|
||||
{
|
||||
try
|
||||
{
|
||||
OnWorldPreSpawn.Invoke();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnCombatDown_Prefix()
|
||||
{
|
||||
try
|
||||
{
|
||||
OnCombatPreDown.Invoke();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnChangeFlight_Postfix()
|
||||
{
|
||||
try
|
||||
{
|
||||
OnFlightChange.Invoke();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
static bool OnOffsetUpdate_Prefix()
|
||||
{
|
||||
try
|
||||
{
|
||||
ms_result.m_result = false;
|
||||
OnIKOffsetUpdate.Invoke(ms_result);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
return !ms_result.m_result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using ABI.CCK.Components;
|
||||
using ABI_RC.Core;
|
||||
using ABI_RC.Core.InteractionSystem;
|
||||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Systems.IK;
|
||||
using ABI_RC.Systems.IK.SubSystems;
|
||||
using ABI_RC.Systems.Movement;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ml_prm
|
||||
{
|
||||
static class GameEvents
|
||||
{
|
||||
internal class EventResult
|
||||
{
|
||||
public bool m_result = false;
|
||||
}
|
||||
internal class GameEvent
|
||||
{
|
||||
event Action m_action;
|
||||
public void AddHandler(Action p_listener) => m_action += p_listener;
|
||||
public void RemoveHandler(Action p_listener) => m_action -= p_listener;
|
||||
public void Invoke() => m_action?.Invoke();
|
||||
}
|
||||
internal class GameEvent<T1>
|
||||
{
|
||||
event Action<T1> m_action;
|
||||
public void AddHandler(Action<T1> p_listener) => m_action += p_listener;
|
||||
public void RemoveHandler(Action<T1> p_listener) => m_action -= p_listener;
|
||||
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 OnAvatarPostReuse = new GameEvent();
|
||||
public static readonly GameEvent<float> OnIKScaling = new GameEvent<float>();
|
||||
public static readonly GameEvent<CVRSeat> OnSeatPreSit = new GameEvent<CVRSeat>();
|
||||
public static readonly GameEvent OnCalibrationStart = new GameEvent();
|
||||
public static readonly GameEvent OnWorldPreSpawn = new GameEvent();
|
||||
public static readonly GameEvent OnCombatPreDown = new GameEvent();
|
||||
public static readonly GameEvent OnFlightChange = new GameEvent();
|
||||
public static readonly GameEvent<EventResult> OnIKOffsetUpdate = new GameEvent<EventResult>();
|
||||
|
||||
static readonly EventResult ms_result = new EventResult();
|
||||
|
||||
internal static void Init(HarmonyLib.Harmony p_instance)
|
||||
{
|
||||
try
|
||||
{
|
||||
p_instance.Patch(
|
||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.ClearAvatar)),
|
||||
null,
|
||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnAvatarClear_Postfix), BindingFlags.NonPublic | BindingFlags.Static))
|
||||
);
|
||||
|
||||
p_instance.Patch(
|
||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.SetupAvatar)),
|
||||
null,
|
||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnSetupAvatar_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
||||
);
|
||||
|
||||
p_instance.Patch(
|
||||
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_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
||||
);
|
||||
|
||||
p_instance.Patch(
|
||||
typeof(PlayerSetup).GetMethod("SetupIKScaling", BindingFlags.NonPublic | BindingFlags.Instance),
|
||||
null,
|
||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnSetupIKScaling_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
||||
);
|
||||
|
||||
p_instance.Patch(
|
||||
typeof(CVRSeat).GetMethod(nameof(CVRSeat.SitDown)),
|
||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnCVRSeatSitDown_Prefix), BindingFlags.Static | BindingFlags.NonPublic)),
|
||||
null
|
||||
);
|
||||
|
||||
p_instance.Patch(
|
||||
typeof(BodySystem).GetMethod(nameof(BodySystem.StartCalibration)),
|
||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnStartCalibration_Prefix), BindingFlags.Static | BindingFlags.NonPublic)),
|
||||
null
|
||||
);
|
||||
|
||||
p_instance.Patch(
|
||||
typeof(RootLogic).GetMethod(nameof(RootLogic.SpawnOnWorldInstance)),
|
||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnWorldSpawn_Prefix), BindingFlags.Static | BindingFlags.NonPublic)),
|
||||
null
|
||||
);
|
||||
|
||||
p_instance.Patch(
|
||||
typeof(CombatSystem).GetMethods().First(m => (!m.IsGenericMethod && m.Name == nameof(CombatSystem.Down))),
|
||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnCombatDown_Prefix), BindingFlags.Static | BindingFlags.NonPublic)),
|
||||
null
|
||||
);
|
||||
|
||||
p_instance.Patch(
|
||||
typeof(BetterBetterCharacterController).GetMethod(nameof(BetterBetterCharacterController.ChangeFlight)),
|
||||
null,
|
||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnChangeFlight_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
||||
);
|
||||
|
||||
p_instance.Patch(
|
||||
typeof(IKSystem).GetMethod("OnPreSolverUpdateActiveOffset", BindingFlags.Instance | BindingFlags.NonPublic),
|
||||
new HarmonyLib.HarmonyMethod(typeof(GameEvents).GetMethod(nameof(OnOffsetUpdate_Prefix), BindingFlags.Static | BindingFlags.NonPublic))
|
||||
);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
try
|
||||
{
|
||||
OnAvatarPreReuse.Invoke();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnAvatarReinitialize_Postfix()
|
||||
{
|
||||
try
|
||||
{
|
||||
OnAvatarPostReuse.Invoke();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnSetupIKScaling_Postfix(ref UnityEngine.Vector3 ___scaleDifference)
|
||||
{
|
||||
try
|
||||
{
|
||||
OnIKScaling.Invoke(1f + ___scaleDifference.y);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnCVRSeatSitDown_Prefix(ref CVRSeat __instance)
|
||||
{
|
||||
try
|
||||
{
|
||||
OnSeatPreSit.Invoke(__instance);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnStartCalibration_Prefix()
|
||||
{
|
||||
try
|
||||
{
|
||||
OnCalibrationStart.Invoke();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnWorldSpawn_Prefix()
|
||||
{
|
||||
try
|
||||
{
|
||||
OnWorldPreSpawn.Invoke();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnCombatDown_Prefix()
|
||||
{
|
||||
try
|
||||
{
|
||||
OnCombatPreDown.Invoke();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnChangeFlight_Postfix()
|
||||
{
|
||||
try
|
||||
{
|
||||
OnFlightChange.Invoke();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
static bool OnOffsetUpdate_Prefix()
|
||||
{
|
||||
try
|
||||
{
|
||||
ms_result.m_result = false;
|
||||
OnIKOffsetUpdate.Invoke(ms_result);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
return !ms_result.m_result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
using ABI.CCK.Components;
|
||||
using ABI_RC.Systems.Movement;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ml_prm
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
class GravityInfluencer : MonoBehaviour
|
||||
{
|
||||
Rigidbody m_rigidBody = null;
|
||||
PhysicsInfluencer m_physicsInfluencer = null;
|
||||
bool m_activeGravity = true;
|
||||
|
||||
void Start()
|
||||
{
|
||||
m_rigidBody = this.GetComponent<Rigidbody>();
|
||||
m_physicsInfluencer = this.GetComponent<PhysicsInfluencer>();
|
||||
}
|
||||
|
||||
void FixedUpdate()
|
||||
{
|
||||
m_rigidBody.useGravity = false;
|
||||
if(m_activeGravity && ((m_physicsInfluencer == null) || !m_physicsInfluencer.enableInfluence || !m_physicsInfluencer.GetSubmerged()))
|
||||
m_rigidBody.AddForce(BetterBetterCharacterController.Instance.GravityResult.AppliedGravity * m_rigidBody.mass);
|
||||
}
|
||||
|
||||
public void SetActiveGravity(bool p_state) => m_activeGravity = p_state;
|
||||
}
|
||||
}
|
219
ml_prm/ModUi.cs
219
ml_prm/ModUi.cs
|
@ -1,8 +1,8 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using BTKUILib.UIObjects;
|
||||
using BTKUILib.UIObjects.Components;
|
||||
|
||||
namespace ml_prm
|
||||
{
|
||||
|
@ -37,83 +37,103 @@ namespace ml_prm
|
|||
FallLimit
|
||||
}
|
||||
|
||||
const string c_ragdollKeyTooltip = "Switch ragdoll mode with '{0}' key";
|
||||
const string c_fallLimitTooltip = "Fall limit based on impact velocity<p>Current value corresponds to drop from {0} units with default gravity</p>";
|
||||
|
||||
internal static readonly UiEvent OnSwitchChanged = new UiEvent();
|
||||
|
||||
static List<object> ms_uiElements = null;
|
||||
static Page ms_page = null;
|
||||
static Category ms_category = null;
|
||||
|
||||
static Button ms_ragdollButton = null;
|
||||
static ToggleButton ms_hotkeyToggle = null;
|
||||
static ToggleButton ms_gravityToggle = null;
|
||||
static ToggleButton ms_pointersToggle = null;
|
||||
static ToggleButton ms_ignoreLocalToggle = null;
|
||||
static ToggleButton ms_combatToggle = null;
|
||||
static ToggleButton ms_recoveryToggle = null;
|
||||
static ToggleButton ms_slipperinessToggle = null;
|
||||
static ToggleButton ms_bouncinessToggle = null;
|
||||
static ToggleButton ms_viewDirectionToggle = null;
|
||||
static ToggleButton ms_jumpRecoverToggle = null;
|
||||
static ToggleButton ms_buoyancyToggle = null;
|
||||
static ToggleButton ms_fallDamageToggle = null;
|
||||
static SliderFloat ms_velocityMultiplierSlider = null;
|
||||
static SliderFloat ms_movementDragSlider = null;
|
||||
static SliderFloat ms_angularMovementDragSlider = null;
|
||||
static SliderFloat ms_recoverDelaySlider = null;
|
||||
static SliderFloat ms_fallLimitSlider = null;
|
||||
static Button ms_resetButton = null;
|
||||
|
||||
internal static void Init()
|
||||
{
|
||||
ms_uiElements = new List<object>();
|
||||
|
||||
if(MelonLoader.MelonMod.RegisteredMelons.FirstOrDefault(m => m.Info.Name == "BTKUILib") != null)
|
||||
CreateUi();
|
||||
}
|
||||
|
||||
// Separated method, otherwise exception is thrown, funny CSharp and optional references, smh
|
||||
static void CreateUi()
|
||||
{
|
||||
BTKUILib.QuickMenuAPI.PrepareIcon("PlayerRagdollMod", "PRM-Person", GetIconStream("person.png"));
|
||||
|
||||
var l_modRoot = new BTKUILib.UIObjects.Page("PlayerRagdollMod", "MainPage", true, "PRM-Person");
|
||||
l_modRoot.MenuTitle = "Player Ragdoll Mod";
|
||||
l_modRoot.MenuSubtitle = "Become a ragdoll and change various settings for people amusement";
|
||||
ms_page = new Page("PlayerRagdollMod", "MainPage", true, "PRM-Person");
|
||||
ms_page.MenuTitle = "Player Ragdoll Mod";
|
||||
ms_page.MenuSubtitle = "Become a ragdoll and change various settings for people amusement";
|
||||
|
||||
var l_modCategory = l_modRoot.AddCategory("Settings");
|
||||
ms_category = ms_page.AddCategory("Settings");
|
||||
|
||||
l_modCategory.AddButton("Switch ragdoll", "PRM-Person", "Switch between normal and ragdoll state.").OnPress += OnSwitch;
|
||||
ms_ragdollButton = ms_category.AddButton("Switch ragdoll", "PRM-Person", "Switch between normal and ragdoll state");
|
||||
ms_ragdollButton.OnPress += OnSwitch;
|
||||
|
||||
ms_hotkeyToggle = ms_category.AddToggle("Use hotkey", "Switch ragdoll mode with 'R' key", Settings.Hotkey);
|
||||
ms_hotkeyToggle.ToggleTooltip = string.Format(c_ragdollKeyTooltip, Settings.HotkeyKey);
|
||||
ms_hotkeyToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.Hotkey, state);
|
||||
Settings.OnHotkeyKeyChanged.AddHandler(OnHotkeyKeyChanged);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddToggle("Use hotkey", "Switch ragdoll mode with 'R' key", Settings.Hotkey));
|
||||
(ms_uiElements[(int)UiIndex.Hotkey] as BTKUILib.UIObjects.Components.ToggleButton).OnValueUpdated += (state) => OnToggleUpdate(UiIndex.Hotkey, state);
|
||||
ms_gravityToggle = ms_category.AddToggle("Use gravity", "Apply gravity to ragdoll", Settings.Gravity);
|
||||
ms_gravityToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.Gravity, state);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddToggle("Use gravity", "Apply gravity to ragdoll", Settings.Gravity));
|
||||
(ms_uiElements[(int)UiIndex.Gravity] as BTKUILib.UIObjects.Components.ToggleButton).OnValueUpdated += (state) => OnToggleUpdate(UiIndex.Gravity, state);
|
||||
ms_pointersToggle = ms_category.AddToggle("Pointers reaction", "React to trigger colliders with CVRPointer component of 'ragdoll' type", Settings.PointersReaction);
|
||||
ms_pointersToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.PointersReaction, state);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddToggle("Pointers reaction", "React to trigger colliders with CVRPointer component of 'ragdoll' type", Settings.PointersReaction));
|
||||
(ms_uiElements[(int)UiIndex.PointersReaction] as BTKUILib.UIObjects.Components.ToggleButton).OnValueUpdated += (state) => OnToggleUpdate(UiIndex.PointersReaction, state);
|
||||
ms_ignoreLocalToggle = ms_category.AddToggle("Ignore local pointers", "Ignore local avatar's CVRPointer components of 'ragdoll' type", Settings.IgnoreLocal);
|
||||
ms_ignoreLocalToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.IgnoreLocal, state);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddToggle("Ignore local pointers", "Ignore local avatar's CVRPointer components of 'ragdoll' type", Settings.IgnoreLocal));
|
||||
(ms_uiElements[(int)UiIndex.IgnoreLocal] as BTKUILib.UIObjects.Components.ToggleButton).OnValueUpdated += (state) => OnToggleUpdate(UiIndex.IgnoreLocal, state);
|
||||
ms_combatToggle = ms_category.AddToggle("Combat reaction", "Ragdoll upon combat system death", Settings.CombatReaction);
|
||||
ms_combatToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.CombatReaction, state);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddToggle("Combat reaction", "Ragdoll upon combat system death", Settings.CombatReaction));
|
||||
(ms_uiElements[(int)UiIndex.CombatReaction] as BTKUILib.UIObjects.Components.ToggleButton).OnValueUpdated += (state) => OnToggleUpdate(UiIndex.CombatReaction, state);
|
||||
ms_recoveryToggle = ms_category.AddToggle("Auto recover", "Automatically unragdoll after set recover delay", Settings.AutoRecover);
|
||||
ms_recoveryToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.AutoRecover, state);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddToggle("Auto recover", "Automatically unragdoll after set recover delay", Settings.AutoRecover));
|
||||
(ms_uiElements[(int)UiIndex.AutoRecover] as BTKUILib.UIObjects.Components.ToggleButton).OnValueUpdated += (state) => OnToggleUpdate(UiIndex.AutoRecover, state);
|
||||
ms_slipperinessToggle = ms_category.AddToggle("Slipperiness", "Enables/disables friction of ragdoll", Settings.Slipperiness);
|
||||
ms_slipperinessToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.Slipperiness, state);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddToggle("Slipperiness", "Enables/disables friction of ragdoll", Settings.Slipperiness));
|
||||
(ms_uiElements[(int)UiIndex.Slipperiness] as BTKUILib.UIObjects.Components.ToggleButton).OnValueUpdated += (state) => OnToggleUpdate(UiIndex.Slipperiness, state);
|
||||
ms_bouncinessToggle = ms_category.AddToggle("Bounciness", "Enables/disables bounciness of ragdoll", Settings.Bounciness);
|
||||
ms_bouncinessToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.Bounciness, state);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddToggle("Bounciness", "Enables/disables bounciness of ragdoll", Settings.Bounciness));
|
||||
(ms_uiElements[(int)UiIndex.Bounciness] as BTKUILib.UIObjects.Components.ToggleButton).OnValueUpdated += (state) => OnToggleUpdate(UiIndex.Bounciness, state);
|
||||
ms_viewDirectionToggle = ms_category.AddToggle("View direction velocity", "Apply velocity to camera view direction", Settings.ViewVelocity);
|
||||
ms_viewDirectionToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.ViewVelocity, state);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddToggle("View direction velocity", "Apply velocity to camera view direction", Settings.ViewVelocity));
|
||||
(ms_uiElements[(int)UiIndex.ViewVelocity] as BTKUILib.UIObjects.Components.ToggleButton).OnValueUpdated += (state) => OnToggleUpdate(UiIndex.ViewVelocity, state);
|
||||
ms_jumpRecoverToggle = ms_category.AddToggle("Jump recover", "Recover from ragdoll state by jumping", Settings.JumpRecover);
|
||||
ms_jumpRecoverToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.JumpRecover, state);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddToggle("Jump recover", "Recover from ragdoll state by jumping", Settings.JumpRecover));
|
||||
(ms_uiElements[(int)UiIndex.JumpRecover] as BTKUILib.UIObjects.Components.ToggleButton).OnValueUpdated += (state) => OnToggleUpdate(UiIndex.JumpRecover, state);
|
||||
ms_buoyancyToggle = ms_category.AddToggle("Buoyancy", "Enable buoyancy in fluid volumes<p>Warning: constantly changes movement and air drag of hips, spine and chest</p>", Settings.Buoyancy);
|
||||
ms_buoyancyToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.Buoyancy, state);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddToggle("Buoyancy", "Enable buoyancy in fluid volumes. Warning: constantly changes movement and air drag of hips, spine and chest.", Settings.Buoyancy));
|
||||
(ms_uiElements[(int)UiIndex.Buoyancy] as BTKUILib.UIObjects.Components.ToggleButton).OnValueUpdated += (state) => OnToggleUpdate(UiIndex.Buoyancy, state);
|
||||
ms_fallDamageToggle = ms_category.AddToggle("Fall damage", "Enable ragdoll when falling from height", Settings.FallDamage);
|
||||
ms_fallDamageToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.FallDamage, state);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddToggle("Fall damage", "Enable ragdoll when falling from height", Settings.FallDamage));
|
||||
(ms_uiElements[(int)UiIndex.FallDamage] as BTKUILib.UIObjects.Components.ToggleButton).OnValueUpdated += (state) => OnToggleUpdate(UiIndex.FallDamage, state);
|
||||
ms_velocityMultiplierSlider = ms_category.AddSlider("Velocity multiplier", "Velocity multiplier upon entering ragdoll state", Settings.VelocityMultiplier, 1f, 50f);
|
||||
ms_velocityMultiplierSlider.OnValueUpdated += (value) => OnSliderUpdate(UiIndex.VelocityMultiplier, value);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddSlider("Velocity multiplier", "Velocity multiplier upon entering ragdoll state", Settings.VelocityMultiplier, 1f, 50f));
|
||||
(ms_uiElements[(int)UiIndex.VelocityMultiplier] as BTKUILib.UIObjects.Components.SliderFloat).OnValueUpdated += (value) => OnSliderUpdate(UiIndex.VelocityMultiplier, value);
|
||||
ms_movementDragSlider = ms_category.AddSlider("Movement drag", "Movement resistance", Settings.MovementDrag, 0f, 50f);
|
||||
ms_movementDragSlider.OnValueUpdated += (value) => OnSliderUpdate(UiIndex.MovementDrag, value);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddSlider("Movement drag", "Movement resistance", Settings.MovementDrag, 0f, 50f));
|
||||
(ms_uiElements[(int)UiIndex.MovementDrag] as BTKUILib.UIObjects.Components.SliderFloat).OnValueUpdated += (value) => OnSliderUpdate(UiIndex.MovementDrag, value);
|
||||
ms_angularMovementDragSlider = ms_category.AddSlider("Angular movement drag", "Rotation movement resistance", Settings.AngularDrag, 0f, 50f);
|
||||
ms_angularMovementDragSlider.OnValueUpdated += (value) => OnSliderUpdate(UiIndex.AngularDrag, value);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddSlider("Angular movement drag", "Rotation movement resistance", Settings.AngularDrag, 0f, 50f));
|
||||
(ms_uiElements[(int)UiIndex.AngularDrag] as BTKUILib.UIObjects.Components.SliderFloat).OnValueUpdated += (value) => OnSliderUpdate(UiIndex.AngularDrag, value);
|
||||
ms_recoverDelaySlider = ms_category.AddSlider("Recover delay (seconds)", "Recover delay for automatic recover", Settings.RecoverDelay, 1f, 10f);
|
||||
ms_recoverDelaySlider.OnValueUpdated += (value) => OnSliderUpdate(UiIndex.RecoverDelay, value);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddSlider("Recover delay (seconds)", "Recover delay for automatic recover", Settings.RecoverDelay, 1f, 10f));
|
||||
(ms_uiElements[(int)UiIndex.RecoverDelay] as BTKUILib.UIObjects.Components.SliderFloat).OnValueUpdated += (value) => OnSliderUpdate(UiIndex.RecoverDelay, value);
|
||||
ms_fallLimitSlider = ms_category.AddSlider("Fall limit", "", Settings.FallLimit, 4.5f, 44.5f);
|
||||
ms_fallLimitSlider.SliderTooltip = string.Format(c_fallLimitTooltip, GetDropHeight(Settings.FallLimit));
|
||||
ms_fallLimitSlider.OnValueUpdated += (value) => OnSliderUpdate(UiIndex.FallLimit, value);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddSlider("Fall limit", "Height limit for fall damage", Settings.FallLimit, 0f, 100f));
|
||||
(ms_uiElements[(int)UiIndex.FallLimit] as BTKUILib.UIObjects.Components.SliderFloat).OnValueUpdated += (value) => OnSliderUpdate(UiIndex.FallLimit, value);
|
||||
|
||||
l_modCategory.AddButton("Reset settings", "", "Reset mod settings to default").OnPress += Reset;
|
||||
ms_resetButton = ms_category.AddButton("Reset settings", "", "Reset mod settings to default");
|
||||
ms_resetButton.OnPress += Reset;
|
||||
}
|
||||
|
||||
static void OnSwitch()
|
||||
|
@ -128,7 +148,7 @@ namespace ml_prm
|
|||
}
|
||||
}
|
||||
|
||||
static void OnToggleUpdate(UiIndex p_index, bool p_state, bool p_force = false)
|
||||
static void OnToggleUpdate(UiIndex p_index, bool p_state)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -182,9 +202,6 @@ namespace ml_prm
|
|||
Settings.SetSetting(Settings.ModSetting.FallDamage, p_state);
|
||||
break;
|
||||
}
|
||||
|
||||
if(p_force)
|
||||
(ms_uiElements[(int)p_index] as BTKUILib.UIObjects.Components.ToggleButton).ToggleValue = p_state;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
|
@ -192,7 +209,7 @@ namespace ml_prm
|
|||
}
|
||||
}
|
||||
|
||||
static void OnSliderUpdate(UiIndex p_index, float p_value, bool p_force = false)
|
||||
static void OnSliderUpdate(UiIndex p_index, float p_value)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -215,12 +232,12 @@ namespace ml_prm
|
|||
break;
|
||||
|
||||
case UiIndex.FallLimit:
|
||||
{
|
||||
Settings.SetSetting(Settings.ModSetting.FallLimit, p_value);
|
||||
break;
|
||||
ms_fallLimitSlider.SliderTooltip = string.Format(c_fallLimitTooltip, GetDropHeight(p_value));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(p_force)
|
||||
(ms_uiElements[(int)p_index] as BTKUILib.UIObjects.Components.SliderFloat).SetSliderValue(p_value);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
|
@ -230,23 +247,62 @@ namespace ml_prm
|
|||
|
||||
static void Reset()
|
||||
{
|
||||
OnToggleUpdate(UiIndex.Hotkey, true, true);
|
||||
OnToggleUpdate(UiIndex.Gravity, true, true);
|
||||
OnToggleUpdate(UiIndex.PointersReaction, true, true);
|
||||
OnToggleUpdate(UiIndex.IgnoreLocal, true, true);
|
||||
OnToggleUpdate(UiIndex.CombatReaction, true, true);
|
||||
OnToggleUpdate(UiIndex.AutoRecover, false, true);
|
||||
OnToggleUpdate(UiIndex.Slipperiness, false, true);
|
||||
OnToggleUpdate(UiIndex.Bounciness, false, true);
|
||||
OnToggleUpdate(UiIndex.ViewVelocity, false, true);
|
||||
OnToggleUpdate(UiIndex.JumpRecover, false, true);
|
||||
OnToggleUpdate(UiIndex.Buoyancy, true, true);
|
||||
OnToggleUpdate(UiIndex.FallDamage, true, true);
|
||||
OnSliderUpdate(UiIndex.VelocityMultiplier, 2f, true);
|
||||
OnSliderUpdate(UiIndex.MovementDrag, 1f, true);
|
||||
OnSliderUpdate(UiIndex.AngularDrag, 1f, true);
|
||||
OnSliderUpdate(UiIndex.RecoverDelay, 3f, true);
|
||||
OnSliderUpdate(UiIndex.FallLimit, 5f, true);
|
||||
OnToggleUpdate(UiIndex.Hotkey, true);
|
||||
ms_hotkeyToggle.ToggleValue = true;
|
||||
|
||||
OnToggleUpdate(UiIndex.Gravity, true);
|
||||
ms_gravityToggle.ToggleValue = true;
|
||||
|
||||
OnToggleUpdate(UiIndex.PointersReaction, true);
|
||||
ms_pointersToggle.ToggleValue = true;
|
||||
|
||||
OnToggleUpdate(UiIndex.IgnoreLocal, true);
|
||||
ms_ignoreLocalToggle.ToggleValue = true;
|
||||
|
||||
OnToggleUpdate(UiIndex.CombatReaction, true);
|
||||
ms_combatToggle.ToggleValue = true;
|
||||
|
||||
OnToggleUpdate(UiIndex.AutoRecover, false);
|
||||
ms_recoveryToggle.ToggleValue = false;
|
||||
|
||||
OnToggleUpdate(UiIndex.Slipperiness, false);
|
||||
ms_slipperinessToggle.ToggleValue = false;
|
||||
|
||||
OnToggleUpdate(UiIndex.Bounciness, false);
|
||||
ms_bouncinessToggle.ToggleValue = false;
|
||||
|
||||
OnToggleUpdate(UiIndex.ViewVelocity, false);
|
||||
ms_viewDirectionToggle.ToggleValue = false;
|
||||
|
||||
OnToggleUpdate(UiIndex.JumpRecover, false);
|
||||
ms_jumpRecoverToggle.ToggleValue = false;
|
||||
|
||||
OnToggleUpdate(UiIndex.Buoyancy, true);
|
||||
ms_buoyancyToggle.ToggleValue = true;
|
||||
|
||||
OnToggleUpdate(UiIndex.FallDamage, true);
|
||||
ms_fallDamageToggle.ToggleValue = true;
|
||||
|
||||
OnSliderUpdate(UiIndex.VelocityMultiplier, 2f);
|
||||
ms_velocityMultiplierSlider.SetSliderValue(2f);
|
||||
|
||||
OnSliderUpdate(UiIndex.MovementDrag, 1f);
|
||||
ms_movementDragSlider.SetSliderValue(1f);
|
||||
|
||||
OnSliderUpdate(UiIndex.AngularDrag, 1f);
|
||||
ms_angularMovementDragSlider.SetSliderValue(1f);
|
||||
|
||||
OnSliderUpdate(UiIndex.RecoverDelay, 3f);
|
||||
ms_recoverDelaySlider.SetSliderValue(3f);
|
||||
|
||||
OnSliderUpdate(UiIndex.FallLimit, 9.899494f);
|
||||
ms_fallLimitSlider.SetSliderValue(9.899494f);
|
||||
}
|
||||
|
||||
static void OnHotkeyKeyChanged(UnityEngine.KeyCode p_keyCode)
|
||||
{
|
||||
if(ms_ragdollButton != null)
|
||||
ms_hotkeyToggle.ToggleTooltip = string.Format(c_ragdollKeyTooltip, p_keyCode);
|
||||
}
|
||||
|
||||
static Stream GetIconStream(string p_name)
|
||||
|
@ -255,5 +311,10 @@ namespace ml_prm
|
|||
string l_assemblyName = l_assembly.GetName().Name;
|
||||
return l_assembly.GetManifestResourceStream(l_assemblyName + ".resources." + p_name);
|
||||
}
|
||||
|
||||
static float GetDropHeight(float p_speed, float p_gravity = 9.8f)
|
||||
{
|
||||
return MathF.Pow(p_speed, 2f) / (p_gravity * 2f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[assembly: MelonLoader.MelonInfo(typeof(ml_prm.PlayerRagdollMod), "PlayerRagdollMod", "1.1.7", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
||||
[assembly: MelonLoader.MelonInfo(typeof(ml_prm.PlayerRagdollMod), "PlayerRagdollMod", "1.1.8", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
||||
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
||||
[assembly: MelonLoader.MelonPriority(2)]
|
||||
[assembly: MelonLoader.MelonOptionalDependencies("BTKUILib")]
|
||||
[assembly: MelonLoader.MelonAdditionalDependencies("BTKUILib")]
|
||||
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||
[assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||
[assembly: MelonLoader.MelonAdditionalCredits("kafeijao, NotAKidOnSteam")]
|
||||
|
|
192
ml_prm/RagdollBodypartHandler.cs
Normal file
192
ml_prm/RagdollBodypartHandler.cs
Normal file
|
@ -0,0 +1,192 @@
|
|||
using ABI.CCK.Components;
|
||||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Core.Savior;
|
||||
using ABI_RC.Systems.Movement;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ml_prm
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
class RagdollBodypartHandler : MonoBehaviour, CVRTriggerVolume
|
||||
{
|
||||
const string c_ragdollPointerType = "ragdoll";
|
||||
|
||||
Rigidbody m_rigidBody = null;
|
||||
public Collider collider { get; set; } = null;
|
||||
PhysicsInfluencer m_physicsInfluencer = null;
|
||||
|
||||
bool m_shouldHaveInfluencer = false;
|
||||
bool m_activeGravity = true;
|
||||
|
||||
// Unity events
|
||||
void Awake()
|
||||
{
|
||||
this.gameObject.layer = LayerMask.NameToLayer("PlayerLocal");
|
||||
|
||||
collider = this.GetComponent<Collider>();
|
||||
m_rigidBody = this.GetComponent<Rigidbody>();
|
||||
|
||||
if(m_rigidBody != null)
|
||||
{
|
||||
m_rigidBody.isKinematic = false;
|
||||
m_rigidBody.detectCollisions = true;
|
||||
m_rigidBody.useGravity = false;
|
||||
m_rigidBody.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic;
|
||||
}
|
||||
|
||||
if(collider != null)
|
||||
{
|
||||
Physics.IgnoreCollision(collider, BetterBetterCharacterController.Instance.Collider, true);
|
||||
Physics.IgnoreCollision(collider, BetterBetterCharacterController.Instance.KinematicTriggerProxy.Collider, true);
|
||||
Physics.IgnoreCollision(collider, BetterBetterCharacterController.Instance.NonKinematicProxy.Collider, true);
|
||||
Physics.IgnoreCollision(collider, BetterBetterCharacterController.Instance.SphereProxy.Collider, true);
|
||||
BetterBetterCharacterController.Instance.IgnoreCollision(collider, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
if(m_shouldHaveInfluencer && (m_rigidBody != null) && (collider != null))
|
||||
{
|
||||
m_physicsInfluencer = this.gameObject.AddComponent<PhysicsInfluencer>();
|
||||
m_physicsInfluencer.fluidDrag = 3f;
|
||||
m_physicsInfluencer.fluidAngularDrag = 1f;
|
||||
m_physicsInfluencer.enableBuoyancy = true;
|
||||
m_physicsInfluencer.enableInfluence = false;
|
||||
m_physicsInfluencer.forceAlignUpright = false;
|
||||
float mass = m_rigidBody.mass;
|
||||
m_physicsInfluencer.UpdateDensity();
|
||||
m_rigidBody.mass = mass;
|
||||
m_physicsInfluencer.volume = mass * 0.005f;
|
||||
m_physicsInfluencer.enableLocalGravity = true;
|
||||
}
|
||||
|
||||
if(collider != null)
|
||||
{
|
||||
CVRParticlePointerManager.volumes.Add(this);
|
||||
CVRParticlePointerManager.UpdateParticleSystems();
|
||||
}
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
if(collider != null)
|
||||
CVRParticlePointerManager.RemoveTrigger(collider);
|
||||
}
|
||||
|
||||
void FixedUpdate()
|
||||
{
|
||||
if(m_rigidBody != null)
|
||||
{
|
||||
m_rigidBody.useGravity = false;
|
||||
|
||||
if(m_activeGravity && ((m_physicsInfluencer == null) || !m_physicsInfluencer.enableInfluence || !m_physicsInfluencer.GetSubmerged()))
|
||||
m_rigidBody.AddForce(BetterBetterCharacterController.Instance.GravityResult.AppliedGravity * m_rigidBody.mass);
|
||||
}
|
||||
}
|
||||
|
||||
void OnTriggerEnter(Collider p_col)
|
||||
{
|
||||
if(Settings.PointersReaction && (RagdollController.Instance != null))
|
||||
{
|
||||
CVRPointer l_pointer = p_col.GetComponent<CVRPointer>();
|
||||
if((l_pointer != null) && (l_pointer.type == c_ragdollPointerType) && !IsIgnored(l_pointer.transform) && !RagdollController.Instance.IsRagdolled())
|
||||
RagdollController.Instance.SwitchRagdoll();
|
||||
}
|
||||
}
|
||||
|
||||
// Arbitrary
|
||||
public bool IsReady() => ((m_rigidBody != null) && (collider != null) && (!m_shouldHaveInfluencer || ((m_physicsInfluencer != null) && m_physicsInfluencer.IsReady())));
|
||||
public void SetInfuencerUsage(bool p_state) => m_shouldHaveInfluencer = p_state;
|
||||
|
||||
public void SetColliderMaterial(PhysicMaterial p_material)
|
||||
{
|
||||
if(collider != null)
|
||||
{
|
||||
collider.sharedMaterial = p_material;
|
||||
collider.material = p_material;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetAsKinematic(bool p_state)
|
||||
{
|
||||
if(collider != null)
|
||||
collider.isTrigger = p_state;
|
||||
if(m_rigidBody != null)
|
||||
{
|
||||
m_rigidBody.isKinematic = p_state;
|
||||
m_rigidBody.collisionDetectionMode = (p_state ? CollisionDetectionMode.Discrete : CollisionDetectionMode.ContinuousDynamic);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetVelocity(Vector3 p_vec)
|
||||
{
|
||||
if(m_rigidBody != null)
|
||||
m_rigidBody.velocity = p_vec;
|
||||
}
|
||||
|
||||
public void SetAngularVelocity(Vector3 p_vec)
|
||||
{
|
||||
if(m_rigidBody != null)
|
||||
m_rigidBody.angularVelocity = p_vec;
|
||||
}
|
||||
|
||||
public void SetActiveGravity(bool p_state)
|
||||
{
|
||||
m_activeGravity = p_state;
|
||||
|
||||
if(m_physicsInfluencer != null)
|
||||
m_physicsInfluencer.enabled = m_activeGravity;
|
||||
}
|
||||
|
||||
public void SetDrag(float p_value)
|
||||
{
|
||||
if(m_rigidBody != null)
|
||||
{
|
||||
m_rigidBody.drag = p_value;
|
||||
m_rigidBody.WakeUp();
|
||||
}
|
||||
if(m_physicsInfluencer != null)
|
||||
m_physicsInfluencer.airDrag = p_value;
|
||||
}
|
||||
|
||||
public void SetAngularDrag(float p_value)
|
||||
{
|
||||
if(m_rigidBody != null)
|
||||
{
|
||||
m_rigidBody.angularDrag = p_value;
|
||||
m_rigidBody.WakeUp();
|
||||
}
|
||||
if(m_physicsInfluencer != null)
|
||||
m_physicsInfluencer.airAngularDrag = p_value;
|
||||
}
|
||||
|
||||
public void SetBuoyancy(bool p_state)
|
||||
{
|
||||
if(m_physicsInfluencer != null)
|
||||
m_physicsInfluencer.enableInfluence = p_state;
|
||||
}
|
||||
|
||||
public void ClearFluidVolumes()
|
||||
{
|
||||
if(m_physicsInfluencer != null)
|
||||
m_physicsInfluencer.ClearFluidVolumes();
|
||||
}
|
||||
|
||||
static bool IsIgnored(Transform p_transform)
|
||||
{
|
||||
return (Settings.IgnoreLocal && (p_transform.root == PlayerSetup.Instance.transform));
|
||||
}
|
||||
|
||||
// CVRTriggerVolume
|
||||
public void TriggerEnter(CVRPointer pointer)
|
||||
{
|
||||
if(Settings.PointersReaction && (RagdollController.Instance != null))
|
||||
{
|
||||
if((pointer != null) && (pointer.type == c_ragdollPointerType) && !IsIgnored(pointer.transform) && !RagdollController.Instance.IsRagdolled())
|
||||
RagdollController.Instance.SwitchRagdoll();
|
||||
}
|
||||
}
|
||||
public void TriggerExit(CVRPointer pointer) { }
|
||||
}
|
||||
}
|
|
@ -27,15 +27,12 @@ namespace ml_prm
|
|||
bool m_enabled = false;
|
||||
bool m_forcedSwitch = false;
|
||||
|
||||
readonly List<Rigidbody> m_rigidBodies = null;
|
||||
readonly List<Collider> m_colliders = null;
|
||||
Transform m_puppetRoot = null;
|
||||
Transform m_puppet = null;
|
||||
BipedRagdollReferences m_puppetReferences;
|
||||
readonly List<RagdollBodypartHandler> m_ragdollBodyHandlers = null;
|
||||
readonly List<System.Tuple<Transform, Transform>> m_boneLinks = null;
|
||||
readonly List<System.Tuple<CharacterJoint, Vector3>> m_jointAnchors = null;
|
||||
readonly List<PhysicsInfluencer> m_physicsInfluencers = null;
|
||||
readonly List<GravityInfluencer> m_gravityInfluencers = null;
|
||||
|
||||
bool m_avatarReady = false;
|
||||
Coroutine m_initCoroutine = null;
|
||||
|
@ -44,8 +41,7 @@ namespace ml_prm
|
|||
Vector3 m_ragdollLastPos = Vector3.zero;
|
||||
bool m_wasSwimming = false;
|
||||
|
||||
RagdollToggle m_avatarRagdollToggle = null;
|
||||
RagdollTrigger m_ragdollTrigger = null;
|
||||
RagdollToggle m_avatarRagdollToggle = null; // Custom component available for editor
|
||||
AvatarBoolParameter m_ragdolledParameter = null;
|
||||
PhysicMaterial m_physicsMaterial = null;
|
||||
|
||||
|
@ -54,24 +50,25 @@ namespace ml_prm
|
|||
float m_downTime = float.MinValue;
|
||||
|
||||
bool m_inAir = false;
|
||||
float m_inAirDistance = 0f;
|
||||
|
||||
internal RagdollController()
|
||||
{
|
||||
m_rigidBodies = new List<Rigidbody>();
|
||||
m_colliders = new List<Collider>();
|
||||
m_ragdollBodyHandlers = new List<RagdollBodypartHandler>();
|
||||
m_boneLinks = new List<System.Tuple<Transform, Transform>>();
|
||||
m_jointAnchors = new List<System.Tuple<CharacterJoint, Vector3>>();
|
||||
m_physicsInfluencers = new List<PhysicsInfluencer>();
|
||||
m_gravityInfluencers = new List<GravityInfluencer>();
|
||||
}
|
||||
|
||||
// Unity events
|
||||
void Awake()
|
||||
{
|
||||
if((Instance != null) && (Instance != this))
|
||||
Object.Destroy(this);
|
||||
else
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
if(Instance == null)
|
||||
Instance = this;
|
||||
|
||||
m_physicsMaterial = new PhysicMaterial("Ragdoll");
|
||||
m_physicsMaterial.dynamicFriction = c_defaultFriction;
|
||||
m_physicsMaterial.staticFriction = c_defaultFriction;
|
||||
|
@ -84,9 +81,6 @@ namespace ml_prm
|
|||
m_puppetRoot.localPosition = Vector3.zero;
|
||||
m_puppetRoot.localRotation = Quaternion.identity;
|
||||
|
||||
m_ragdollTrigger = BetterBetterCharacterController.Instance.NonKinematicProxy.gameObject.AddComponent<RagdollTrigger>();
|
||||
m_ragdollTrigger.enabled = false;
|
||||
|
||||
Settings.OnMovementDragChanged.AddHandler(this.OnMovementDragChanged);
|
||||
Settings.OnAngularDragChanged.AddHandler(this.OnAngularDragChanged);
|
||||
Settings.OnGravityChanged.AddHandler(this.OnGravityChanged);
|
||||
|
@ -125,17 +119,11 @@ namespace ml_prm
|
|||
m_puppetRoot = null;
|
||||
|
||||
m_puppet = null;
|
||||
m_rigidBodies.Clear();
|
||||
m_colliders.Clear();
|
||||
m_ragdollBodyHandlers.Clear();
|
||||
m_boneLinks.Clear();
|
||||
m_jointAnchors.Clear();
|
||||
m_physicsInfluencers.Clear();
|
||||
m_avatarRagdollToggle = null;
|
||||
|
||||
if(m_ragdollTrigger != null)
|
||||
Object.Destroy(m_ragdollTrigger);
|
||||
m_ragdollTrigger = null;
|
||||
|
||||
if(m_physicsMaterial != null)
|
||||
Object.Destroy(m_physicsMaterial);
|
||||
m_physicsMaterial = null;
|
||||
|
@ -170,33 +158,23 @@ namespace ml_prm
|
|||
{
|
||||
bool l_grounded = BetterBetterCharacterController.Instance.IsGrounded();
|
||||
bool l_inWater = BetterBetterCharacterController.Instance.IsInWater();
|
||||
if(m_inAir && l_grounded && !l_inWater && (m_inAirDistance > Settings.FallLimit))
|
||||
{
|
||||
m_inAirDistance = 0f;
|
||||
if(m_inAir && l_grounded && !l_inWater && (m_velocity.magnitude >= Settings.FallLimit))
|
||||
SwitchRagdoll();
|
||||
}
|
||||
|
||||
m_inAir = !(l_grounded || l_inWater);
|
||||
if(!m_inAir)
|
||||
m_inAirDistance = 0f;
|
||||
}
|
||||
|
||||
if(m_avatarReady && m_enabled)
|
||||
{
|
||||
m_inAirDistance = 0f;
|
||||
BodySystem.TrackingPositionWeight = 0f;
|
||||
BetterBetterCharacterController.Instance.PauseGroundConstraint();
|
||||
BetterBetterCharacterController.Instance.ResetAllForces();
|
||||
}
|
||||
|
||||
if(m_avatarReady && !m_enabled)
|
||||
{
|
||||
Vector3 l_pos = PlayerSetup.Instance.transform.position;
|
||||
m_velocity = (m_velocity + (l_pos - m_lastPosition) / Time.deltaTime) * 0.5f;
|
||||
if(m_inAir)
|
||||
{
|
||||
m_inAirDistance += (Quaternion.Inverse(PlayerSetup.Instance.transform.rotation) * (m_lastPosition - l_pos)).y;
|
||||
m_inAirDistance = Mathf.Clamp(m_inAirDistance, 0f, float.MaxValue);
|
||||
}
|
||||
|
||||
m_lastPosition = l_pos;
|
||||
|
||||
if(!m_reachedGround && BetterBetterCharacterController.Instance.IsOnGround())
|
||||
|
@ -220,9 +198,6 @@ namespace ml_prm
|
|||
if((m_avatarRagdollToggle != null) && m_avatarRagdollToggle.isActiveAndEnabled && m_avatarRagdollToggle.shouldOverride && (m_enabled != m_avatarRagdollToggle.isOn))
|
||||
SwitchRagdoll();
|
||||
|
||||
if((m_ragdollTrigger != null) && m_ragdollTrigger.GetStateWithReset() && m_avatarReady && !m_enabled && Settings.PointersReaction)
|
||||
SwitchRagdoll();
|
||||
|
||||
if(Settings.Hotkey && Input.GetKeyDown(Settings.HotkeyKey) && !ViewManager.Instance.IsAnyMenuOpen)
|
||||
SwitchRagdoll();
|
||||
|
||||
|
@ -277,31 +252,21 @@ namespace ml_prm
|
|||
Object.Destroy(m_puppet.gameObject);
|
||||
m_puppet = null;
|
||||
|
||||
if(m_ragdollTrigger != null)
|
||||
{
|
||||
m_ragdollTrigger.GetStateWithReset();
|
||||
m_ragdollTrigger.enabled = false;
|
||||
}
|
||||
|
||||
m_vrIK = null;
|
||||
m_applyHipsPosition = false;
|
||||
m_enabled = false;
|
||||
m_avatarReady = false;
|
||||
m_avatarRagdollToggle = null;
|
||||
m_ragdolledParameter = null;
|
||||
m_rigidBodies.Clear();
|
||||
m_colliders.Clear();
|
||||
m_puppetReferences = new BipedRagdollReferences();
|
||||
m_ragdollBodyHandlers.Clear();
|
||||
m_boneLinks.Clear();
|
||||
m_jointAnchors.Clear();
|
||||
m_physicsInfluencers.Clear();
|
||||
m_gravityInfluencers.Clear();
|
||||
m_reachedGround = true;
|
||||
m_groundedTime = 0f;
|
||||
m_downTime = float.MinValue;
|
||||
m_puppetRoot.localScale = Vector3.one;
|
||||
m_inAir = false;
|
||||
m_inAirDistance = 0f;
|
||||
m_wasSwimming = false;
|
||||
}
|
||||
|
||||
|
@ -353,26 +318,11 @@ namespace ml_prm
|
|||
|
||||
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)
|
||||
{
|
||||
Rigidbody l_body = l_puppetTransforms[i].GetComponent<Rigidbody>();
|
||||
if(l_body != null)
|
||||
{
|
||||
m_rigidBodies.Add(l_body);
|
||||
l_body.isKinematic = true;
|
||||
l_body.angularDrag = Settings.AngularDrag;
|
||||
l_body.drag = (WorldHandler.IsSafeWorld() ? Settings.MovementDrag : 1f);
|
||||
l_body.useGravity = false;
|
||||
l_body.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic;
|
||||
l_body.gameObject.layer = LayerMask.NameToLayer("PlayerLocal");
|
||||
|
||||
GravityInfluencer l_gravInfluencer = l_body.gameObject.AddComponent<GravityInfluencer>();
|
||||
l_gravInfluencer.SetActiveGravity((!WorldHandler.IsSafeWorld() || Settings.Gravity));
|
||||
m_gravityInfluencers.Add(l_gravInfluencer);
|
||||
}
|
||||
|
||||
CharacterJoint l_joint = l_puppetTransforms[i].GetComponent<CharacterJoint>();
|
||||
if(l_joint != null)
|
||||
{
|
||||
|
@ -381,37 +331,13 @@ namespace ml_prm
|
|||
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_collider != null)
|
||||
if((l_body != null) && (l_collider != null))
|
||||
{
|
||||
Physics.IgnoreCollision(l_collider, BetterBetterCharacterController.Instance.Collider, true);
|
||||
Physics.IgnoreCollision(l_collider, BetterBetterCharacterController.Instance.KinematicTriggerProxy.Collider, true);
|
||||
Physics.IgnoreCollision(l_collider, BetterBetterCharacterController.Instance.NonKinematicProxy.Collider, true);
|
||||
Physics.IgnoreCollision(l_collider, BetterBetterCharacterController.Instance.SphereProxy.Collider, true);
|
||||
BetterBetterCharacterController.Instance.IgnoreCollision(l_collider, true);
|
||||
|
||||
l_collider.sharedMaterial = m_physicsMaterial;
|
||||
l_collider.material = m_physicsMaterial;
|
||||
m_colliders.Add(l_collider);
|
||||
}
|
||||
|
||||
if((l_body != null) && (l_collider != null) && (l_puppetTransforms[i] == m_puppetReferences.hips || l_puppetTransforms[i] == m_puppetReferences.spine || l_puppetTransforms[i] == m_puppetReferences.chest))
|
||||
{
|
||||
PhysicsInfluencer l_physicsInfluencer = l_puppetTransforms[i].gameObject.AddComponent<PhysicsInfluencer>();
|
||||
l_physicsInfluencer.airDrag = (WorldHandler.IsSafeWorld() ? Settings.MovementDrag : 1f);
|
||||
l_physicsInfluencer.airAngularDrag = Settings.AngularDrag;
|
||||
l_physicsInfluencer.fluidDrag = 3f;
|
||||
l_physicsInfluencer.fluidAngularDrag = 1f;
|
||||
l_physicsInfluencer.enableBuoyancy = true;
|
||||
l_physicsInfluencer.enableInfluence = false;
|
||||
l_physicsInfluencer.forceAlignUpright = false;
|
||||
float mass = l_body.mass;
|
||||
l_physicsInfluencer.UpdateDensity();
|
||||
l_body.mass = mass;
|
||||
l_physicsInfluencer.volume = mass * 0.005f;
|
||||
l_physicsInfluencer.enableLocalGravity = true;
|
||||
|
||||
m_physicsInfluencers.Add(l_physicsInfluencer);
|
||||
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)
|
||||
|
@ -422,7 +348,6 @@ namespace ml_prm
|
|||
// And return back
|
||||
m_puppetRoot.localPosition = Vector3.zero;
|
||||
m_puppetRoot.localRotation = Quaternion.identity;
|
||||
m_puppetRoot.gameObject.SetActive(true);
|
||||
|
||||
m_vrIK = PlayerSetup.Instance._avatar.GetComponent<VRIK>();
|
||||
if(m_vrIK != null)
|
||||
|
@ -431,25 +356,28 @@ namespace ml_prm
|
|||
m_avatarRagdollToggle = PlayerSetup.Instance._avatar.GetComponentInChildren<RagdollToggle>(true);
|
||||
m_ragdolledParameter = new AvatarBoolParameter("Ragdolled", PlayerSetup.Instance.animatorManager);
|
||||
|
||||
m_initCoroutine = StartCoroutine(WaitForPhysicsInfluencers());
|
||||
m_initCoroutine = StartCoroutine(WaitForBodyHandlers());
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator WaitForPhysicsInfluencers()
|
||||
IEnumerator WaitForBodyHandlers()
|
||||
{
|
||||
while(!m_physicsInfluencers.TrueForAll(p => p.IsReady()))
|
||||
while(!m_ragdollBodyHandlers.TrueForAll(p => p.IsReady()))
|
||||
yield return null;
|
||||
|
||||
m_puppetRoot.gameObject.SetActive(false);
|
||||
foreach(RagdollBodypartHandler l_handler in m_ragdollBodyHandlers)
|
||||
{
|
||||
l_handler.SetAsKinematic(true);
|
||||
l_handler.SetColliderMaterial(m_physicsMaterial);
|
||||
}
|
||||
|
||||
m_ragdollTrigger.enabled = true;
|
||||
m_avatarReady = true;
|
||||
m_initCoroutine = null;
|
||||
|
||||
OnGravityChanged(Settings.Gravity);
|
||||
OnBuoyancyChanged(Settings.Buoyancy);
|
||||
OnMovementDragChanged(Settings.MovementDrag);
|
||||
OnAngularDragChanged(Settings.AngularDrag);
|
||||
OnGravityChanged(Settings.Gravity);
|
||||
OnBuoyancyChanged(Settings.Buoyancy);
|
||||
}
|
||||
|
||||
void OnAvatarPreReuse()
|
||||
|
@ -573,28 +501,16 @@ namespace ml_prm
|
|||
if(m_avatarReady)
|
||||
{
|
||||
float l_drag = (WorldHandler.IsSafeWorld() ? p_value : 1f);
|
||||
foreach(Rigidbody l_body in m_rigidBodies)
|
||||
{
|
||||
l_body.drag = l_drag;
|
||||
if(m_enabled)
|
||||
l_body.WakeUp();
|
||||
}
|
||||
foreach(PhysicsInfluencer l_influencer in m_physicsInfluencers)
|
||||
l_influencer.airDrag = l_drag;
|
||||
foreach(RagdollBodypartHandler l_handler in m_ragdollBodyHandlers)
|
||||
l_handler.SetDrag(l_drag);
|
||||
}
|
||||
}
|
||||
void OnAngularDragChanged(float p_value)
|
||||
{
|
||||
if(m_avatarReady)
|
||||
{
|
||||
foreach(Rigidbody l_body in m_rigidBodies)
|
||||
{
|
||||
l_body.angularDrag = p_value;
|
||||
if(m_enabled)
|
||||
l_body.WakeUp();
|
||||
}
|
||||
foreach(PhysicsInfluencer l_influencer in m_physicsInfluencers)
|
||||
l_influencer.airAngularDrag = p_value;
|
||||
foreach(RagdollBodypartHandler l_handler in m_ragdollBodyHandlers)
|
||||
l_handler.SetAngularDrag(p_value);
|
||||
}
|
||||
}
|
||||
void OnGravityChanged(bool p_state)
|
||||
|
@ -602,10 +518,8 @@ namespace ml_prm
|
|||
if(m_avatarReady)
|
||||
{
|
||||
bool l_gravity = (!WorldHandler.IsSafeWorld() || p_state);
|
||||
foreach(PhysicsInfluencer l_influencer in m_physicsInfluencers)
|
||||
l_influencer.enabled = l_gravity;
|
||||
foreach(GravityInfluencer l_influencer in m_gravityInfluencers)
|
||||
l_influencer.SetActiveGravity(l_gravity);
|
||||
foreach(RagdollBodypartHandler l_handler in m_ragdollBodyHandlers)
|
||||
l_handler.SetActiveGravity(l_gravity);
|
||||
|
||||
if(!l_gravity)
|
||||
{
|
||||
|
@ -632,8 +546,8 @@ namespace ml_prm
|
|||
if(m_avatarReady)
|
||||
{
|
||||
bool l_buoyancy = (!WorldHandler.IsSafeWorld() || p_state);
|
||||
foreach(PhysicsInfluencer l_influencer in m_physicsInfluencers)
|
||||
l_influencer.enableInfluence = l_buoyancy;
|
||||
foreach(RagdollBodypartHandler l_handler in m_ragdollBodyHandlers)
|
||||
l_handler.SetBuoyancy(l_buoyancy);
|
||||
|
||||
if(!l_buoyancy)
|
||||
{
|
||||
|
@ -645,7 +559,6 @@ namespace ml_prm
|
|||
void OnFallDamageChanged(bool p_state)
|
||||
{
|
||||
m_inAir = false;
|
||||
m_inAirDistance = 0f;
|
||||
}
|
||||
|
||||
// Arbitrary
|
||||
|
@ -663,6 +576,8 @@ namespace ml_prm
|
|||
BetterBetterCharacterController.Instance.ChangeFlight(false, true);
|
||||
BetterBetterCharacterController.Instance.SetImmobilized(true);
|
||||
BetterBetterCharacterController.Instance.ClearFluidVolumes();
|
||||
BetterBetterCharacterController.Instance.ResetAllForces();
|
||||
BetterBetterCharacterController.Instance.PauseGroundConstraint();
|
||||
BodySystem.TrackingPositionWeight = 0f;
|
||||
m_applyHipsPosition = IKSystem.Instance.applyOriginalHipPosition;
|
||||
IKSystem.Instance.applyOriginalHipPosition = true;
|
||||
|
@ -678,10 +593,11 @@ namespace ml_prm
|
|||
m_groundedTime = 0f;
|
||||
}
|
||||
|
||||
m_puppetRoot.gameObject.SetActive(true);
|
||||
foreach(RagdollBodypartHandler l_handler in m_ragdollBodyHandlers)
|
||||
l_handler.SetAsKinematic(false);
|
||||
|
||||
foreach(Rigidbody l_body in m_rigidBodies)
|
||||
l_body.isKinematic = false;
|
||||
m_puppetRoot.gameObject.SetActive(false); //
|
||||
m_puppetRoot.gameObject.SetActive(true); // Resets rigidbodies and joints inner physics states
|
||||
|
||||
Vector3 l_velocity = Vector3.ClampMagnitude(m_velocity * (WorldHandler.IsSafeWorld() ? Settings.VelocityMultiplier : 1f), WorldHandler.GetMovementLimit());
|
||||
if(Settings.ViewVelocity && WorldHandler.IsSafeWorld())
|
||||
|
@ -690,10 +606,10 @@ namespace ml_prm
|
|||
l_velocity = PlayerSetup.Instance.GetActiveCamera().transform.forward * l_mag;
|
||||
}
|
||||
|
||||
foreach(Rigidbody l_body in m_rigidBodies)
|
||||
foreach(RagdollBodypartHandler l_handler in m_ragdollBodyHandlers)
|
||||
{
|
||||
l_body.velocity = l_velocity;
|
||||
l_body.angularVelocity = Vector3.zero;
|
||||
l_handler.SetVelocity(l_velocity);
|
||||
l_handler.SetAngularVelocity(Vector3.zero);
|
||||
}
|
||||
|
||||
m_ragdollLastPos = m_puppetReferences.hips.position;
|
||||
|
@ -723,15 +639,14 @@ namespace ml_prm
|
|||
|
||||
m_ragdolledParameter.SetValue(false);
|
||||
|
||||
m_puppetRoot.gameObject.SetActive(false);
|
||||
m_puppetRoot.localPosition = Vector3.zero;
|
||||
m_puppetRoot.localRotation = Quaternion.identity;
|
||||
|
||||
foreach(Rigidbody l_body in m_rigidBodies)
|
||||
l_body.isKinematic = true;
|
||||
|
||||
foreach(PhysicsInfluencer l_physicsInfluencer in m_physicsInfluencers)
|
||||
l_physicsInfluencer.ClearFluidVolumes();
|
||||
foreach(RagdollBodypartHandler l_handler in m_ragdollBodyHandlers)
|
||||
{
|
||||
l_handler.SetAsKinematic(true);
|
||||
l_handler.ClearFluidVolumes();
|
||||
}
|
||||
|
||||
m_lastPosition = PlayerSetup.Instance.transform.position;
|
||||
m_velocity = Vector3.zero;
|
||||
|
@ -762,7 +677,6 @@ namespace ml_prm
|
|||
}
|
||||
|
||||
m_inAir = false;
|
||||
m_inAirDistance = 0f;
|
||||
}
|
||||
|
||||
static Transform CloneTransform(Transform p_source, Transform p_parent, string p_name)
|
||||
|
|
|
@ -1,108 +0,0 @@
|
|||
using ABI.CCK.Components;
|
||||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Core.Savior;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ml_prm
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
class RagdollTrigger : MonoBehaviour
|
||||
{
|
||||
const string c_ragdollPointerType = "ragdoll";
|
||||
|
||||
Collider m_collider = null;
|
||||
Collider m_lastColliderTrigger = null;
|
||||
ParticleSystem m_lastParticleSystemTrigger = null;
|
||||
bool m_triggered = false;
|
||||
|
||||
void Start()
|
||||
{
|
||||
m_collider = this.GetComponent<Collider>();
|
||||
|
||||
CVRParticlePointerManager.volumes.Add(new RagdollTriggerVolume(m_collider, this));
|
||||
CVRParticlePointerManager.UpdateParticleSystems();
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
if(m_collider != null)
|
||||
CVRParticlePointerManager.RemoveTrigger(m_collider);
|
||||
m_collider = null;
|
||||
|
||||
m_lastColliderTrigger = null;
|
||||
m_lastParticleSystemTrigger = null;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if(!ReferenceEquals(m_lastColliderTrigger, null))
|
||||
{
|
||||
if(m_lastColliderTrigger != null)
|
||||
{
|
||||
if(!m_collider.bounds.Intersects(m_lastColliderTrigger.bounds))
|
||||
m_lastColliderTrigger = null;
|
||||
}
|
||||
else
|
||||
m_lastColliderTrigger = null;
|
||||
}
|
||||
if(!ReferenceEquals(m_lastParticleSystemTrigger, null))
|
||||
{
|
||||
if(m_lastParticleSystemTrigger != null)
|
||||
{
|
||||
if(m_lastParticleSystemTrigger.particleCount == 0)
|
||||
m_lastParticleSystemTrigger = null;
|
||||
}
|
||||
else
|
||||
m_lastParticleSystemTrigger = null;
|
||||
}
|
||||
}
|
||||
|
||||
void OnTriggerEnter(Collider p_other)
|
||||
{
|
||||
CVRPointer l_pointer = p_other.GetComponent<CVRPointer>();
|
||||
if((l_pointer != null) && (l_pointer.type == c_ragdollPointerType) && !IsIgnored(l_pointer.transform) && (m_lastColliderTrigger != p_other))
|
||||
{
|
||||
m_lastColliderTrigger = p_other;
|
||||
m_triggered = true;
|
||||
}
|
||||
}
|
||||
|
||||
void OnTriggerExit(Collider p_other)
|
||||
{
|
||||
if(m_lastColliderTrigger == p_other)
|
||||
m_lastColliderTrigger = null;
|
||||
}
|
||||
|
||||
public void OnPointerParticleEnter(CVRPointer p_pointer)
|
||||
{
|
||||
if(!this.gameObject.activeInHierarchy)
|
||||
return;
|
||||
|
||||
if((p_pointer.type == c_ragdollPointerType) && !IsIgnored(p_pointer.transform) && (m_lastParticleSystemTrigger != p_pointer.particleSystem))
|
||||
{
|
||||
m_lastParticleSystemTrigger = p_pointer.particleSystem;
|
||||
m_triggered = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPointerParticleExit(CVRPointer p_pointer)
|
||||
{
|
||||
// This seems to be very unreliable, and it's causing weird behavior
|
||||
// if (!gameObject.activeInHierarchy) return;
|
||||
// if(m_lastParticleSystemTrigger == p_pointer.particleSystem)
|
||||
// m_lastParticleSystemTrigger = null;
|
||||
}
|
||||
|
||||
public bool GetStateWithReset()
|
||||
{
|
||||
bool l_state = m_triggered;
|
||||
m_triggered = false;
|
||||
return l_state;
|
||||
}
|
||||
|
||||
static bool IsIgnored(Transform p_transform)
|
||||
{
|
||||
return (Settings.IgnoreLocal && (p_transform.root == PlayerSetup.Instance.transform));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
using ABI_RC.Core.Savior;
|
||||
using ABI.CCK.Components;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ml_prm
|
||||
{
|
||||
class RagdollTriggerVolume : CVRTriggerVolume
|
||||
{
|
||||
readonly RagdollTrigger m_trigger = null;
|
||||
|
||||
public Collider collider { get; set; }
|
||||
|
||||
internal RagdollTriggerVolume(Collider p_collider, RagdollTrigger p_trigger)
|
||||
{
|
||||
collider = p_collider;
|
||||
m_trigger = p_trigger;
|
||||
}
|
||||
|
||||
public void TriggerEnter(CVRPointer pointer) => m_trigger.OnPointerParticleEnter(pointer);
|
||||
public void TriggerExit(CVRPointer pointer) => m_trigger.OnPointerParticleExit(pointer);
|
||||
}
|
||||
}
|
|
@ -53,7 +53,7 @@ namespace ml_prm
|
|||
public static bool JumpRecover { get; private set; } = false;
|
||||
public static bool Buoyancy { get; private set; } = true;
|
||||
public static bool FallDamage { get; private set; } = true;
|
||||
public static float FallLimit { get; private set; } = 5f;
|
||||
public static float FallLimit { get; private set; } = 9.899494f;
|
||||
|
||||
public static readonly SettingEvent<bool> OnHotkeyChanged = new SettingEvent<bool>();
|
||||
public static readonly SettingEvent<KeyCode> OnHotkeyKeyChanged = new SettingEvent<KeyCode>();
|
||||
|
@ -122,7 +122,7 @@ namespace ml_prm
|
|||
JumpRecover = (bool)ms_entries[(int)ModSetting.JumpRecover].BoxedValue;
|
||||
Buoyancy = (bool)ms_entries[(int)ModSetting.Buoyancy].BoxedValue;
|
||||
FallDamage = (bool)ms_entries[(int)ModSetting.FallDamage].BoxedValue;
|
||||
FallLimit = Mathf.Clamp((float)ms_entries[(int)ModSetting.FallLimit].BoxedValue, 0f, 100f);
|
||||
FallLimit = Mathf.Clamp((float)ms_entries[(int)ModSetting.FallLimit].BoxedValue, 4.5f, 44.5f);
|
||||
}
|
||||
|
||||
static void OnMelonSettingSave_HotkeyKey(object p_oldValue, object p_newValue)
|
||||
|
|
|
@ -6,6 +6,7 @@ using ABI_RC.Systems.Movement;
|
|||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using System.Linq;
|
||||
|
||||
namespace ml_prm
|
||||
{
|
||||
|
@ -40,5 +41,7 @@ namespace ml_prm
|
|||
PlayerSetup.Instance._avatar.transform.localPosition = Vector3.zero;
|
||||
PlayerSetup.Instance._avatar.transform.localRotation = Quaternion.identity;
|
||||
}
|
||||
|
||||
public static bool IsInEnumeration(object p_obj, object[] p_enumeration) => p_enumeration.Contains(p_obj);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<Platforms>x64</Platforms>
|
||||
<PackageId>PlayerRagdollMod</PackageId>
|
||||
<Version>1.1.7</Version>
|
||||
<Version>1.1.8</Version>
|
||||
<Authors>SDraw</Authors>
|
||||
<Company>None</Company>
|
||||
<Product>PlayerRagdollMod</Product>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue