mirror of
https://github.com/NotAKidoS/NAK_CVR_Mods.git
synced 2025-09-04 23:39:22 +00:00
[RelativeSync] Fixed execution order of RelativeSyncController & PuppetMaster.ProcessAvatarVisibility, so moving at high speeds with passengers does not disrupt voice or avatar distance hider
This commit is contained in:
parent
063669e8a6
commit
ea5a9eef97
5 changed files with 52 additions and 35 deletions
|
@ -18,9 +18,6 @@ public class RelativeSyncMod : MelonMod
|
||||||
// Experimental sync hack
|
// Experimental sync hack
|
||||||
ApplyPatches(typeof(CVRSpawnablePatches));
|
ApplyPatches(typeof(CVRSpawnablePatches));
|
||||||
|
|
||||||
// Experimental no interpolation on Better Better Character Controller
|
|
||||||
ApplyPatches(typeof(BetterBetterCharacterControllerPatches));
|
|
||||||
|
|
||||||
// Send relative sync update after network root data update
|
// Send relative sync update after network root data update
|
||||||
ApplyPatches(typeof(NetworkRootDataUpdatePatches));
|
ApplyPatches(typeof(NetworkRootDataUpdatePatches));
|
||||||
|
|
||||||
|
@ -31,6 +28,9 @@ public class RelativeSyncMod : MelonMod
|
||||||
// Add components if missing (for relative sync markers)
|
// Add components if missing (for relative sync markers)
|
||||||
ApplyPatches(typeof(CVRSeatPatches));
|
ApplyPatches(typeof(CVRSeatPatches));
|
||||||
ApplyPatches(typeof(CVRMovementParentPatches));
|
ApplyPatches(typeof(CVRMovementParentPatches));
|
||||||
|
|
||||||
|
// So we run after the client moves the remote player
|
||||||
|
ApplyPatches(typeof(NetIKController_Patches));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApplyPatches(Type type)
|
private void ApplyPatches(Type type)
|
||||||
|
|
|
@ -24,10 +24,6 @@ internal static class ModSettings
|
||||||
Category.CreateEntry("ExpSyncedObjectHack", true,
|
Category.CreateEntry("ExpSyncedObjectHack", true,
|
||||||
"Exp Spawnable Sync Fix", description: "Forces CVRSpawnable to update position in FixedUpdate. May help reduce local jitter on synced movement parents.");
|
"Exp Spawnable Sync Fix", description: "Forces CVRSpawnable to update position in FixedUpdate. May help reduce local jitter on synced movement parents.");
|
||||||
|
|
||||||
private static readonly MelonPreferences_Entry<bool> ExpNoInterpolationOnBBCC =
|
|
||||||
Category.CreateEntry("ExpNoInterpolationOnBBCC", true,
|
|
||||||
"Exp Disable Interpolation on BBCC", description: "Disable interpolation on Better Better Character Controller. May help reduce local jitter on synced movement parents.");
|
|
||||||
|
|
||||||
#endregion Melon Preferences
|
#endregion Melon Preferences
|
||||||
|
|
||||||
internal static void Initialize()
|
internal static void Initialize()
|
||||||
|
@ -43,6 +39,5 @@ internal static class ModSettings
|
||||||
ModNetwork.Debug_NetworkInbound = DebugLogInbound.Value;
|
ModNetwork.Debug_NetworkInbound = DebugLogInbound.Value;
|
||||||
ModNetwork.Debug_NetworkOutbound = DebugLogOutbound.Value;
|
ModNetwork.Debug_NetworkOutbound = DebugLogOutbound.Value;
|
||||||
Patches.CVRSpawnablePatches.UseHack = ExpSyncedObjectHack.Value;
|
Patches.CVRSpawnablePatches.UseHack = ExpSyncedObjectHack.Value;
|
||||||
Patches.BetterBetterCharacterControllerPatches.NoInterpolation = ExpNoInterpolationOnBBCC.Value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,12 +2,10 @@
|
||||||
using ABI_RC.Core.InteractionSystem;
|
using ABI_RC.Core.InteractionSystem;
|
||||||
using ABI_RC.Core.Networking.Jobs;
|
using ABI_RC.Core.Networking.Jobs;
|
||||||
using ABI_RC.Core.Player;
|
using ABI_RC.Core.Player;
|
||||||
using ABI_RC.Systems.Movement;
|
|
||||||
using ABI.CCK.Components;
|
using ABI.CCK.Components;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using NAK.RelativeSync.Components;
|
using NAK.RelativeSync.Components;
|
||||||
using NAK.RelativeSync.Networking;
|
using NAK.RelativeSync.Networking;
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace NAK.RelativeSync.Patches;
|
namespace NAK.RelativeSync.Patches;
|
||||||
|
|
||||||
|
@ -19,7 +17,6 @@ internal static class PlayerSetupPatches
|
||||||
{
|
{
|
||||||
__instance.AddComponentIfMissing<RelativeSyncMonitor>();
|
__instance.AddComponentIfMissing<RelativeSyncMonitor>();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static class PuppetMasterPatches
|
internal static class PuppetMasterPatches
|
||||||
|
@ -30,6 +27,20 @@ internal static class PuppetMasterPatches
|
||||||
{
|
{
|
||||||
__instance.AddComponentIfMissing<RelativeSyncController>();
|
__instance.AddComponentIfMissing<RelativeSyncController>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool ShouldProcessAvatarVisibility { get; set; }
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(PuppetMaster), nameof(PuppetMaster.ProcessAvatarVisibility))]
|
||||||
|
private static bool Prefix_PuppetMaster_ProcessAvatarVisibility()
|
||||||
|
=> ShouldProcessAvatarVisibility;
|
||||||
|
|
||||||
|
public static void ForceProcessAvatarVisibility(PuppetMaster puppetMaster)
|
||||||
|
{
|
||||||
|
ShouldProcessAvatarVisibility = true;
|
||||||
|
puppetMaster.ProcessAvatarVisibility();
|
||||||
|
ShouldProcessAvatarVisibility = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static class CVRSeatPatches
|
internal static class CVRSeatPatches
|
||||||
|
@ -85,29 +96,24 @@ internal static class CVRSpawnablePatches
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static class BetterBetterCharacterControllerPatches
|
internal static class NetIKController_Patches
|
||||||
{
|
{
|
||||||
private static bool _noInterpolation;
|
|
||||||
internal static bool NoInterpolation
|
|
||||||
{
|
|
||||||
get => _noInterpolation;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_noInterpolation = value;
|
|
||||||
if (_rigidbody == null) return;
|
|
||||||
_rigidbody.interpolation = value ? RigidbodyInterpolation.None : _initialInterpolation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Rigidbody _rigidbody;
|
|
||||||
private static RigidbodyInterpolation _initialInterpolation;
|
|
||||||
|
|
||||||
[HarmonyPostfix]
|
[HarmonyPostfix]
|
||||||
[HarmonyPatch(typeof(BetterBetterCharacterController), nameof(BetterBetterCharacterController.Start))]
|
[HarmonyPatch(typeof(NetIKController), nameof(NetIKController.LateUpdate))]
|
||||||
private static void Postfix_BetterBetterCharacterController_Update(ref BetterBetterCharacterController __instance)
|
private static void Postfix_NetIKController_LateUpdate(ref NetIKController __instance)
|
||||||
{
|
{
|
||||||
_rigidbody = __instance.GetComponent<Rigidbody>();
|
if (!RelativeSyncManager.NetIkControllersToRelativeSyncControllers.TryGetValue(__instance,
|
||||||
_initialInterpolation = _rigidbody.interpolation;
|
out RelativeSyncController syncController))
|
||||||
NoInterpolation = _noInterpolation; // get initial value as patch runs later than settings init
|
{
|
||||||
|
// Process visibility only after applying network IK
|
||||||
|
PuppetMasterPatches.ForceProcessAvatarVisibility(__instance._puppetMaster);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply relative sync after the network IK has been applied
|
||||||
|
syncController.OnPostNetIkControllerLateUpdate();
|
||||||
|
|
||||||
|
// Process visibility after we have moved the remote player
|
||||||
|
PuppetMasterPatches.ForceProcessAvatarVisibility(__instance._puppetMaster);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -26,14 +26,29 @@ public class RelativeSyncController : MonoBehaviour
|
||||||
|
|
||||||
_userId = puppetMaster._playerDescriptor.ownerId;
|
_userId = puppetMaster._playerDescriptor.ownerId;
|
||||||
RelativeSyncManager.RelativeSyncControllers.Add(_userId, this);
|
RelativeSyncManager.RelativeSyncControllers.Add(_userId, this);
|
||||||
|
RelativeSyncManager.NetIkControllersToRelativeSyncControllers.Add(puppetMaster.netIkController, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDestroy()
|
private void OnDestroy()
|
||||||
{
|
{
|
||||||
RelativeSyncManager.RelativeSyncControllers.Remove(_userId);
|
RelativeSyncManager.RelativeSyncControllers.Remove(_userId);
|
||||||
|
|
||||||
|
if (puppetMaster == null
|
||||||
|
|| puppetMaster.netIkController == null)
|
||||||
|
{
|
||||||
|
// remove by value ?
|
||||||
|
foreach (var kvp in RelativeSyncManager.NetIkControllersToRelativeSyncControllers)
|
||||||
|
{
|
||||||
|
if (kvp.Value != this) continue;
|
||||||
|
RelativeSyncManager.NetIkControllersToRelativeSyncControllers.Remove(kvp.Key);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RelativeSyncManager.NetIkControllersToRelativeSyncControllers.Remove(puppetMaster.netIkController);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LateUpdate()
|
internal void OnPostNetIkControllerLateUpdate()
|
||||||
{
|
{
|
||||||
// if (puppetMaster._isHidden)
|
// if (puppetMaster._isHidden)
|
||||||
// return;
|
// return;
|
||||||
|
|
|
@ -11,6 +11,7 @@ public static class RelativeSyncManager
|
||||||
|
|
||||||
public static readonly Dictionary<int, RelativeSyncMarker> RelativeSyncTransforms = new();
|
public static readonly Dictionary<int, RelativeSyncMarker> RelativeSyncTransforms = new();
|
||||||
public static readonly Dictionary<string, RelativeSyncController> RelativeSyncControllers = new();
|
public static readonly Dictionary<string, RelativeSyncController> RelativeSyncControllers = new();
|
||||||
|
public static readonly Dictionary<NetIKController, RelativeSyncController> NetIkControllersToRelativeSyncControllers = new();
|
||||||
|
|
||||||
public static void ApplyRelativeSync(string userId, int target, Vector3 position, Vector3 rotation)
|
public static void ApplyRelativeSync(string userId, int target, Vector3 position, Vector3 rotation)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue