MoverSimulationManager.cs (5711B)
1 using System; 2 using Boo.Lang; 3 using Slimecing.Characters; 4 using Slimecing.Environment.Moving; 5 using UnityEngine; 6 7 namespace Slimecing.Environment 8 { 9 public enum SimulationInterpolationMethod 10 { 11 None, 12 Unity 13 } 14 15 [DefaultExecutionOrder(-100)] 16 public class MoverSimulationManager : MonoBehaviour 17 { 18 private static MoverSimulationManager _instance; 19 20 private static readonly List<CharacterMovementController> s_CharacterMovers = new List<CharacterMovementController>(); 21 private static readonly List<RigidbodyMover> s_RigidbodyMovers = new List<RigidbodyMover>(); 22 23 private static SimulationInterpolationMethod _internalInterpolationMethod = SimulationInterpolationMethod.None; 24 25 public static SimulationInterpolationMethod interpolationMethod 26 { 27 get => _internalInterpolationMethod; 28 set 29 { 30 _internalInterpolationMethod = value; 31 32 MoveBodiesInstantly(); 33 34 RigidbodyInterpolation interpolation = (_internalInterpolationMethod == SimulationInterpolationMethod.Unity) ? RigidbodyInterpolation.Interpolate : RigidbodyInterpolation.None; 35 foreach (var charMover in s_CharacterMovers) 36 { 37 charMover.playerRigidbody.interpolation = interpolation; 38 } 39 40 foreach (var mover in s_RigidbodyMovers) 41 { 42 mover.moverRigidbody.interpolation = interpolation; 43 } 44 } 45 } 46 47 public static void CheckAlive() 48 { 49 if (_instance != null) return; 50 51 GameObject holdingGameObject = new GameObject("MoverSimManager"); 52 _instance = holdingGameObject.AddComponent<MoverSimulationManager>(); 53 54 holdingGameObject.hideFlags = HideFlags.NotEditable; 55 _instance.hideFlags = HideFlags.NotEditable; 56 } 57 private void Awake() 58 { 59 _instance = this; 60 } 61 62 private void OnDisable() 63 { 64 Destroy(gameObject); 65 } 66 67 public static void RegisterCharMover(CharacterMovementController charMover) 68 { 69 s_CharacterMovers.Add(charMover); 70 71 RigidbodyInterpolation interpolate = _internalInterpolationMethod == SimulationInterpolationMethod.Unity ? RigidbodyInterpolation.Interpolate : RigidbodyInterpolation.None; 72 charMover.playerRigidbody.interpolation = interpolate; 73 } 74 75 public static void UnregisterCharMover(CharacterMovementController charMover) 76 { 77 s_CharacterMovers.Remove(charMover); 78 } 79 80 public static void RegisterMover(RigidbodyMover mover) 81 { 82 s_RigidbodyMovers.Add(mover); 83 84 RigidbodyInterpolation interpolate = _internalInterpolationMethod == SimulationInterpolationMethod.Unity ? RigidbodyInterpolation.Interpolate : RigidbodyInterpolation.None; 85 mover.moverRigidbody.interpolation = interpolate; 86 } 87 88 public static void UnregisterMover(RigidbodyMover mover) 89 { 90 s_RigidbodyMovers.Remove(mover); 91 } 92 93 private void FixedUpdate() 94 { 95 float deltaTime = Time.deltaTime; 96 PreSimulationTick(); 97 SimulateTick(deltaTime); 98 PostSimulationTick(); 99 } 100 101 private void PreSimulationTick() 102 { 103 foreach (var mover in s_RigidbodyMovers) 104 { 105 var moverTransform = mover.transform; 106 mover.beginningTickPosition = moverTransform.position; 107 mover.beginningTickRotation = moverTransform.rotation; 108 } 109 } 110 111 private void SimulateTick(float deltaTime) 112 { 113 foreach (var mover in s_RigidbodyMovers) 114 { 115 mover.UpdateMoverVelocity(deltaTime); 116 117 mover.transform.SetPositionAndRotation(mover.currentPosition, mover.currentRotation); 118 mover.moverRigidbody.position = mover.currentPosition; 119 mover.moverRigidbody.rotation = mover.currentRotation; 120 } 121 122 foreach (var charMover in s_CharacterMovers) 123 { 124 charMover.TickCharacter(deltaTime); 125 } 126 } 127 128 private void PostSimulationTick() 129 { 130 Physics.SyncTransforms(); 131 132 foreach (var mover in s_RigidbodyMovers) 133 { 134 mover.moverRigidbody.position = mover.beginningTickPosition; 135 mover.moverRigidbody.rotation = mover.beginningTickRotation; 136 mover.moverRigidbody.MovePosition(mover.currentPosition); 137 mover.moverRigidbody.MoveRotation(mover.currentRotation); 138 } 139 } 140 141 private static void MoveBodiesInstantly() 142 { 143 foreach (var charMover in s_CharacterMovers) 144 { 145 charMover.transform.SetPositionAndRotation(charMover.internalTransformPosition, 146 charMover.transform.rotation); 147 charMover.playerRigidbody.position = charMover.internalTransformPosition; 148 charMover.playerRigidbody.rotation = charMover.transform.rotation; 149 } 150 151 foreach (var mover in s_RigidbodyMovers) 152 { 153 mover.transform.SetPositionAndRotation(mover.currentPosition, mover.currentRotation); 154 mover.moverRigidbody.position = mover.currentPosition; 155 mover.moverRigidbody.rotation = mover.currentRotation; 156 } 157 } 158 } 159 }