From f10742586ca680ebed39d4713b8d3a580ad84bbd Mon Sep 17 00:00:00 2001 From: Nympfonic Date: Thu, 4 Jul 2024 11:29:13 +0000 Subject: [PATCH] Fixed BTR twerking on steep slopes (!142) In the end, Kaeno's fix by changing the main client collider's layer to `HighPolyCollider` is the only way I could fix it. Also made changes to avoid unnecessary physics collisions between other BTR colliders; these physics collisions can cause FPS drops especially for lower end PCs so this should provide a slight performance gain for them. I left in the commented-out collision debugger script I made to log collisions in case it's useful for future debugging purposes. Reviewed-on: https://dev.sp-tarkov.com/SPT/Modules/pulls/142 Co-authored-by: Nympfonic Co-committed-by: Nympfonic --- project/SPT.Custom/BTR/BTRManager.cs | 72 +++++++++++++++++++-- project/SPT.Custom/BTR/CollisionDebugger.cs | 35 ++++++++++ project/SPT.Custom/SPT.Custom.csproj | 4 +- 3 files changed, 105 insertions(+), 6 deletions(-) create mode 100644 project/SPT.Custom/BTR/CollisionDebugger.cs diff --git a/project/SPT.Custom/BTR/BTRManager.cs b/project/SPT.Custom/BTR/BTRManager.cs index d8eaea3..2ced1fe 100644 --- a/project/SPT.Custom/BTR/BTRManager.cs +++ b/project/SPT.Custom/BTR/BTRManager.cs @@ -1,11 +1,12 @@ -using SPT.Custom.BTR.Utils; -using SPT.SinglePlayer.Utils.TraderServices; -using Comfort.Common; +using Comfort.Common; using EFT; using EFT.InventoryLogic; using EFT.UI; using EFT.Vehicle; +using GPUInstancer; using HarmonyLib; +using SPT.Custom.BTR.Utils; +using SPT.SinglePlayer.Utils.TraderServices; using System.Collections; using System.Collections.Generic; using System.Linq; @@ -229,6 +230,7 @@ namespace SPT.Custom.BTR private void InitBtrBotService() { btrBotShooter = btrController.BotShooterBtr; + btrBotShooter.GetPlayer.GetComponent().detectCollisions = false; // disable rigidbody collisions with BTR bot firearmController = btrBotShooter.GetComponent(); var weaponPrefab = (WeaponPrefab)AccessTools.Field(firearmController.GetType(), "weaponPrefab_0").GetValue(firearmController); weaponSoundPlayer = weaponPrefab.GetComponent(); @@ -380,14 +382,74 @@ namespace SPT.Custom.BTR // Initially we assumed there was a reason for this so it was left as is. // Turns out disabling the server collider in favour of the client collider fixes the "BTR doing a wheelie" bug, // while preventing the player from walking through the BTR. + // We also need to change the client collider's layer to HighPolyCollider due to unknown collisions that occur + // when going down a steep slope. + + // Add collision debugger component to log collisions in the EFT Console + var clientColliders = btrClientSide.GetComponentsInChildren(true); + //foreach (var collider in clientColliders) + //{ + // collider.gameObject.AddComponent(); + //} + + var serverColliders = btrServerSide.GetComponentsInChildren(true); + //foreach (var collider in serverColliders) + //{ + // collider.gameObject.AddComponent(); + //} + + var clientRootCollider = clientColliders.First(x => x.gameObject.name == "Root"); + + // Retrieve all TerrainColliders + var terrainColliders = new List(); + + foreach (GPUInstancerManager manager in GPUInstancerManager.activeManagerList) + { + if (manager.GetType() != typeof(GPUInstancerDetailManager)) + { + continue; + } + + var detailManager = (GPUInstancerDetailManager)manager; + if (detailManager.terrain == null) + { + continue; + } + + terrainColliders.Add(detailManager.terrain.GetComponent()); + } + + // Make the Root collider ignore collisions with TerrainColliders + foreach (var collider in terrainColliders) + { + Physics.IgnoreCollision(clientRootCollider, collider); + } + + // Retrieve all wheel colliders on the serverside BTR + const string wheelColliderParentName = "BTR_82_wheel"; + const string wheelColliderName = "Cylinder"; + + var serverWheelColliders = serverColliders + .Where(x => x.transform.parent.name.StartsWith(wheelColliderParentName) && x.gameObject.name.StartsWith(wheelColliderName)) + .ToArray(); + + // Make the Root collider ignore collisions with the serverside BTR wheels + foreach (var collider in serverWheelColliders) + { + Physics.IgnoreCollision(clientRootCollider, collider); + } + + // Enable clientside BTR collider and disable serverside BTR collider const string exteriorColliderName = "BTR_82_exterior_COLLIDER"; - var serverExteriorCollider = btrServerSide.GetComponentsInChildren(true) + + var serverExteriorCollider = serverColliders .First(x => x.gameObject.name == exteriorColliderName); - var clientExteriorCollider = btrClientSide.GetComponentsInChildren(true) + var clientExteriorCollider = clientColliders .First(x => x.gameObject.name == exteriorColliderName); serverExteriorCollider.gameObject.SetActive(false); clientExteriorCollider.gameObject.SetActive(true); + clientExteriorCollider.gameObject.layer = LayerMask.NameToLayer("HighPolyCollider"); } private void UpdateTarget() diff --git a/project/SPT.Custom/BTR/CollisionDebugger.cs b/project/SPT.Custom/BTR/CollisionDebugger.cs new file mode 100644 index 0000000..3324a82 --- /dev/null +++ b/project/SPT.Custom/BTR/CollisionDebugger.cs @@ -0,0 +1,35 @@ +using EFT.UI; +using UnityEngine; + +namespace SPT.Custom.BTR +{ + public class CollisionDebugger : MonoBehaviour + { + private int _resetFrame = 10; + private int _frame = 0; + + private void Update() + { + _frame = (_frame + 1) % _resetFrame; + } + + private void OnCollisionEnter(Collision collision) + { + foreach (var contact in collision.contacts) + { + ConsoleScreen.LogWarning($"Collision between {gameObject.name} and {contact.otherCollider.gameObject.name}"); + } + } + + private void OnCollisionStay(Collision collision) + { + if (_frame == 0) + { + foreach (var contact in collision.contacts) + { + ConsoleScreen.LogWarning($"Collision between {gameObject.name} and {contact.otherCollider.gameObject.name}"); + } + } + } + } +} diff --git a/project/SPT.Custom/SPT.Custom.csproj b/project/SPT.Custom/SPT.Custom.csproj index 8ee72ff..6bbbfd6 100644 --- a/project/SPT.Custom/SPT.Custom.csproj +++ b/project/SPT.Custom/SPT.Custom.csproj @@ -25,8 +25,10 @@ - + + +