diff --git a/Assets/Scenes/Main.unity b/Assets/Scenes/Main.unity index 15df2cc..0e86036 100644 --- a/Assets/Scenes/Main.unity +++ b/Assets/Scenes/Main.unity @@ -211,7 +211,7 @@ MeshCollider: m_Bits: 0 m_LayerOverridePriority: 0 m_IsTrigger: 0 - m_ProvidesContacts: 0 + m_ProvidesContacts: 1 m_Enabled: 1 serializedVersion: 5 m_Convex: 0 @@ -1609,6 +1609,8 @@ MonoBehaviour: mainEngine: {fileID: 1437557825} rb: {fileID: 1172921199} altimeter: {fileID: 894314916} + physicsTransitionAltitude: 1000 + useUnityPhysics: 1 --- !u!54 &1172921199 Rigidbody: m_ObjectHideFlags: 0 @@ -1635,7 +1637,7 @@ Rigidbody: m_IsKinematic: 0 m_Interpolate: 0 m_Constraints: 0 - m_CollisionDetection: 2 + m_CollisionDetection: 0 --- !u!65 &1172921200 BoxCollider: m_ObjectHideFlags: 0 @@ -1652,7 +1654,7 @@ BoxCollider: m_Bits: 0 m_LayerOverridePriority: 0 m_IsTrigger: 0 - m_ProvidesContacts: 0 + m_ProvidesContacts: 1 m_Enabled: 1 serializedVersion: 3 m_Size: {x: 1, y: 1, z: 1} diff --git a/Assets/Scripts/RocketPhysics.cs b/Assets/Scripts/RocketPhysics.cs index 0fe3d4e..47ac535 100644 --- a/Assets/Scripts/RocketPhysics.cs +++ b/Assets/Scripts/RocketPhysics.cs @@ -13,17 +13,86 @@ public class RocketPhysics : MonoBehaviour public DoublePrecisionVector3 velocity; public DoublePrecisionVector3 rotation; - // Start is called once before the first execution of Update after the MonoBehaviour is created + [Header("Physics Mode Settings")] + public float physicsTransitionAltitude = 1000f; // meters - switch to Unity physics below this + public bool useUnityPhysics = true; // current physics mode + + private Vector3 lastPhysicsPosition; + void Start() { position = new DoublePrecisionVector3(rb.position.x, rb.position.y, rb.position.z); velocity = new DoublePrecisionVector3(rb.linearVelocity.x, rb.linearVelocity.y, rb.linearVelocity.z); rotation = new DoublePrecisionVector3(rb.rotation.eulerAngles.x, rb.rotation.eulerAngles.y, rb.rotation.eulerAngles.z); + + rb.useGravity = false; + lastPhysicsPosition = rb.position; } - // Update is called once per frame - void Update() + void FixedUpdate() { + // Determine which physics mode to use + bool shouldUseUnityPhysics = altimeter.altitude < physicsTransitionAltitude; + + // Handle mode transition + if (shouldUseUnityPhysics != useUnityPhysics) + { + TransitionPhysicsMode(shouldUseUnityPhysics); + } + + if (useUnityPhysics) + { + UpdateWithUnityPhysics(); + } + else + { + UpdateWithDoublePrecision(); + } + } + + void TransitionPhysicsMode(bool toUnityPhysics) + { + if (toUnityPhysics) + { + // Transitioning to Unity physics (descending) + rb.isKinematic = false; + rb.position = new Vector3((float)position.x, (float)position.y, (float)position.z); + rb.linearVelocity = new Vector3((float)velocity.x, (float)velocity.y, (float)velocity.z); + lastPhysicsPosition = rb.position; + } + else + { + // Transitioning to double precision (ascending) + rb.isKinematic = true; + position = new DoublePrecisionVector3(rb.position.x, rb.position.y, rb.position.z); + velocity = new DoublePrecisionVector3(rb.linearVelocity.x, rb.linearVelocity.y, rb.linearVelocity.z); + } + + useUnityPhysics = toUnityPhysics; + Debug.Log($"Physics mode switched to: {(useUnityPhysics ? "Unity Physics" : "Double Precision")}"); + } + + void UpdateWithUnityPhysics() + { + // Use Unity's physics engine - allows ground interaction + double gravityAcceleration = altimeter.gh; + Vector3 gravityForce = new Vector3(0, (float)(-gravityAcceleration * rb.mass), 0); + + Vector3 thrustDirection = rb.rotation * Vector3.up; + Vector3 thrustForce = thrustDirection * mainEngine.thrust; + + rb.AddForce(gravityForce, ForceMode.Force); + rb.AddForce(thrustForce, ForceMode.Force); + + // Update double precision tracking from Unity physics + position = new DoublePrecisionVector3(rb.position.x, rb.position.y, rb.position.z); + velocity = new DoublePrecisionVector3(rb.linearVelocity.x, rb.linearVelocity.y, rb.linearVelocity.z); + rotation = new DoublePrecisionVector3(rb.rotation.eulerAngles.x, rb.rotation.eulerAngles.y, rb.rotation.eulerAngles.z); + } + + void UpdateWithDoublePrecision() + { + // Manual double-precision integration - no ground interaction double gravityAcceleration = altimeter.gh; double thrustAcceleration = mainEngine.thrust / rb.mass; @@ -36,11 +105,14 @@ public class RocketPhysics : MonoBehaviour ); DoublePrecisionVector3 totalAcceleration = gravityAccelerationVector + thrustAccelerationVector; - velocity = velocity + totalAcceleration * Time.deltaTime; - position = position + velocity * Time.deltaTime; + velocity = velocity + totalAcceleration * Time.fixedDeltaTime; + position = position + velocity * Time.fixedDeltaTime; - rb.position = new Vector3((float)position.x, (float)position.y, (float)position.z); - rb.linearVelocity = new Vector3((float)velocity.x, (float)velocity.y, (float)velocity.z); + // Update Unity transform (kinematic mode) + Vector3 newPosition = new Vector3((float)position.x, (float)position.y, (float)position.z); + rb.position = newPosition; + // Do not set linearVelocity for kinematic bodies + // rb.linearVelocity = new Vector3((float)velocity.x, (float)velocity.y, (float)velocity.z); rb.rotation = Quaternion.Euler((float)rotation.x, (float)rotation.y, (float)rotation.z); } }