using UnityEngine; // Sci-Fi Ship Controller. Copyright (c) 2018-2023 SCSM Pty Ltd. All rights reserved. namespace SciFiShipController { /// /// This will nudge a the ship away from a collider (like a wall) if it is /// constant contact with it for a specified duration. Attach this component /// to a ShipControlModule. /// [RequireComponent(typeof(Rigidbody))] public class PreventWallStick : MonoBehaviour { #region Public variables public float maxStickTime = 0.25f; public float wallPushVelocity = 5f; #endregion #region Private variables private float wallStickTimer = 0f; private int totalTouchingColliders = 0; private Rigidbody rBody; #endregion #region Initialisation Methods void Awake() { rBody = GetComponent(); } #endregion #region Event Methods private void OnCollisionStay(Collision collision) { // If we are touching other colliders for too long, push us away from them wallStickTimer += Time.deltaTime; if (wallStickTimer > maxStickTime && rBody != null) { #if UNITY_2018_3_OR_NEWER rBody.AddForce(collision.GetContact(0).normal * wallPushVelocity, ForceMode.VelocityChange); #else ContactPoint[] contacts = collision.contacts; int numContactPoints = contacts == null ? 0 : contacts.Length; if (numContactPoints > 0) { rBody.AddForce(contacts[0].normal * wallPushVelocity, ForceMode.VelocityChange); } #endif } } private void OnCollisionEnter(Collision collision) { // Every time a collider enters, increment the number of colliders we are touching totalTouchingColliders++; } private void OnCollisionExit(Collision collision) { // Every time a collider exits, decrement the number of colliders we are touching totalTouchingColliders--; if (totalTouchingColliders < 1) { if (totalTouchingColliders < 0) { totalTouchingColliders = 0; #if UNITY_EDITOR Debug.Log("[DEBUG] Colliders < 0"); #endif } wallStickTimer = 0f; } } #endregion } }