Files
Convention-Unity-Demo/Assets/Scenes/SafeArea/Scripts/Movable.cs
2025-09-25 19:04:05 +08:00

115 lines
3.5 KiB
C#

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();
}
}
}
}
}
}