using System.Collections; using System.Collections.Generic; using UnityEngine; namespace Demo { [System.Serializable] public class MovableException : System.Exception { public MovableException() { } public MovableException(string message) : base(message) { } public MovableException(string message, System.Exception inner) : base(message, inner) { } protected MovableException( System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { } } public abstract class Movable : MonoBehaviour { public Vector3 Position { get => this.transform.localPosition; set => this.transform.localPosition = value; } public abstract float DeltaTime { get; } public bool IsDirty { get; set; } = false; private Vector2 m_EstimatePosition = Vector2.zero; protected virtual bool VerifyEstimatePosition(Vector2 value) => true; public Vector2 EstimatePosition { get => m_EstimatePosition; set { if (VerifyEstimatePosition(value) == false) throw new MovableException($"{this}.{nameof(EstimatePosition)}.set verify fail "); IsDirty = true; m_EstimatePosition = value; } } [SerializeField] private Vector2 m_Speed = Vector2.zero; protected virtual bool VerifySpeed(Vector2 value) => true; public Vector2 Speed { get => m_Speed; set { if (VerifySpeed(value) == false) throw new MovableException($"{this}.{nameof(Speed)}.set verify fail "); IsDirty = true; m_Speed = value; } } [SerializeField] private Vector2 m_Acceleration = Vector2.zero; protected virtual bool VerifyAcceleration(Vector2 value) => true; public Vector2 Acceleration { get => m_Acceleration; set { if (VerifyAcceleration(value) == false) throw new MovableException($"{this}.{nameof(Speed)}.set verify fail "); IsDirty = true; m_Acceleration = value; } } public abstract bool Verify(); public abstract Vector3 FailMovingPosition(); public abstract Vector3 FailMovingSpeed(); [SerializeField] private Rigidbody2D m_Rigidbody = null; protected virtual void Update() { if (Speed.magnitude > 0) { EstimatePosition += Speed * DeltaTime; } Speed += Acceleration * DeltaTime; } protected virtual void LateUpdate() { if (IsDirty) { if (m_Rigidbody) { if (!Verify()) { Speed = FailMovingSpeed(); } m_Rigidbody.velocity = Speed; } else { if (Verify()) { Position = EstimatePosition; } else { Position = FailMovingPosition(); Speed = FailMovingSpeed(); } } } } } }