using FishNet.CodeGenerating; using FishNet.Serializing; using UnityEngine; using UnityEngine.Scripting; namespace FishNet.Component.Prediction { [UseGlobalCustomSerializer] [Preserve] public struct RigidbodyState { public Vector3 Position; public Quaternion Rotation; public bool IsKinematic; public Vector3 Velocity; public Vector3 AngularVelocity; public RigidbodyState(Rigidbody rb, bool isKinematic) : this(rb) { Position = rb.transform.position; Rotation = rb.transform.rotation; IsKinematic = isKinematic; Velocity = rb.linearVelocity; AngularVelocity = rb.angularVelocity; } public RigidbodyState(Rigidbody rb) { Position = rb.transform.position; Rotation = rb.transform.rotation; IsKinematic = rb.isKinematic; Velocity = rb.linearVelocity; AngularVelocity = rb.angularVelocity; } } [UseGlobalCustomSerializer] [Preserve] public struct Rigidbody2DState { public Vector3 Position; public Quaternion Rotation; public Vector2 Velocity; public float AngularVelocity; public bool Simulated; public bool IsKinematic; public Rigidbody2DState(Rigidbody2D rb, bool simulated) { Position = rb.transform.position; Rotation = rb.transform.rotation; Velocity = rb.linearVelocity; AngularVelocity = rb.angularVelocity; Simulated = simulated; IsKinematic = rb.isKinematic; } public Rigidbody2DState(Rigidbody2D rb) { Position = rb.transform.position; Rotation = rb.transform.rotation; Velocity = rb.linearVelocity; AngularVelocity = rb.angularVelocity; Simulated = rb.simulated; IsKinematic = rb.isKinematic; } } [Preserve] public static class RigidbodyStateSerializers { public static void WriteRigidbodyState(this Writer writer, RigidbodyState value) { writer.WriteVector3(value.Position); writer.WriteQuaternion32(value.Rotation); writer.WriteBoolean(value.IsKinematic); if (!value.IsKinematic) { writer.WriteVector3(value.Velocity); writer.WriteVector3(value.AngularVelocity); } } public static RigidbodyState ReadRigidbodyState(this Reader reader) { RigidbodyState state = new() { Position = reader.ReadVector3(), Rotation = reader.ReadQuaternion32(), IsKinematic = reader.ReadBoolean() }; if (!state.IsKinematic) { state.Velocity = reader.ReadVector3(); state.AngularVelocity = reader.ReadVector3(); } return state; } public static void WriteRigidbody2DState(this Writer writer, Rigidbody2DState value) { writer.WriteVector3(value.Position); writer.WriteQuaternion32(value.Rotation); writer.WriteBoolean(value.Simulated); writer.WriteBoolean(value.IsKinematic); if (value.Simulated) { writer.WriteVector2(value.Velocity); writer.WriteSingle(value.AngularVelocity); } } public static Rigidbody2DState ReadRigidbody2DState(this Reader reader) { Rigidbody2DState state = new() { Position = reader.ReadVector3(), Rotation = reader.ReadQuaternion32(), Simulated = reader.ReadBoolean(), IsKinematic = reader.ReadBoolean() }; if (state.Simulated) { state.Velocity = reader.ReadVector2(); state.AngularVelocity = reader.ReadSingle(); } return state; } } [Preserve] public static class RigidbodyStateExtensions { /// /// Gets a RigidbodyState. /// public static RigidbodyState GetState(this Rigidbody rb) { return new(rb); } /// /// Sets a state to a rigidbody. /// public static void SetState(this Rigidbody rb, RigidbodyState state) { Transform t = rb.transform; t.position = state.Position; t.rotation = state.Rotation; rb.linearVelocity = state.Velocity; rb.angularVelocity = state.AngularVelocity; } /// /// Gets a Rigidbody2DState. /// public static Rigidbody2DState GetState(this Rigidbody2D rb) { return new(rb); } /// /// Sets a state to a rigidbody. /// public static void SetState(this Rigidbody2D rb, Rigidbody2DState state) { Transform t = rb.transform; t.position = state.Position; t.rotation = state.Rotation; rb.linearVelocity = state.Velocity; rb.angularVelocity = state.AngularVelocity; } } }