using UnityEngine; public class ForceToAcessibleVolume : MonoBehaviour { public float ForceMultiplier; public float MaxForce; public float DistanceExponent; public int AccesibleVolumeLayer; private Vector3 _LastContactNormal; private Vector3 _LastContanctPosition; private Vector3 _PreviousPosition; private bool _OutsideVolume; private Rigidbody _Rigidbody; private void Start() { _Rigidbody = GetComponent(); _LastContanctPosition = base.transform.position; _PreviousPosition = base.transform.position; } private void OnTriggerStay(Collider other) { if (_OutsideVolume && other.gameObject.layer == AccesibleVolumeLayer) { _LastContanctPosition = base.transform.position; _OutsideVolume = false; } } private void OnTriggerExit(Collider other) { if (other.gameObject.layer == AccesibleVolumeLayer) { _OutsideVolume = true; _LastContactNormal = (base.transform.position - _PreviousPosition).normalized; } } private void FixedUpdate() { if (_OutsideVolume) { Vector3 vector = base.transform.position - _LastContanctPosition; float magnitude = vector.magnitude; RaycastHit hitInfo; if (Physics.Raycast(base.transform.position, -_LastContactNormal, out hitInfo, magnitude, 1 << AccesibleVolumeLayer)) { _LastContanctPosition = hitInfo.point; _LastContactNormal = hitInfo.normal; vector = base.transform.position - _LastContanctPosition; magnitude = vector.magnitude; } Vector3 vector2 = -vector.normalized; float num = Mathf.Clamp(Mathf.Pow(magnitude, DistanceExponent), 0f, MaxForce); _Rigidbody.AddForce(num * vector2); } _PreviousPosition = base.transform.position; } }