Files
Cielonos/Assets/Scripts/MainGame/AttackArea/Submodules/TraceMoveSubmodule.cs
2025-12-24 16:58:51 -05:00

90 lines
3.5 KiB
C#

using Cielonos.MainGame.Characters;
using UnityEngine;
namespace Cielonos.MainGame
{
public partial class TraceMoveSubmodule : MoveSubmoduleBase
{
public Transform projectile => owner.topParent;
public CharacterBase target;
public float angularSpeed;
public float angularAcceleration;
public float moveSpeed;
public float moveAcceleration;
public bool autoConnect;
public bool autoDisconnect;
public float detectRadius;
private float deltaTime => owner.creator.selfTimeSm.DeltaTime;
private Vector3 step;
public TraceMoveSubmodule(AttackAreaBase attackArea, CharacterBase target,
float moveSpeed, float moveAcceleration, float angularSpeed, float angularAcceleration, Vector3 initialDirection,
bool autoConnect, bool autoDisconnect, float detectRadius, bool stopWhenHit) : base(attackArea, stopWhenHit)
{
this.target = target;
this.angularSpeed = angularSpeed;
this.angularAcceleration = angularAcceleration;
this.moveSpeed = moveSpeed;
this.moveAcceleration = moveAcceleration;
this.autoConnect = autoConnect;
this.autoDisconnect = autoDisconnect;
this.detectRadius = detectRadius;
projectile.forward = initialDirection;
}
public override void Update()
{
if (target == null || target.statusSm.isDead)
{
moveSpeed += moveAcceleration * deltaTime;
moveSpeed = Mathf.Max(moveSpeed, 0f);
unscaledVelocity = projectile.forward * moveSpeed;
scaledVelocity = timeScaleCoefficient * unscaledVelocity;
projectile.position += scaledVelocity * deltaTime;
if (autoConnect)
{
if (owner.creator == MainGameManager.Player)
{
CharacterBase detectEnemy = BattleManager.EnemySm.GetNearestEnemy(detectRadius, owner.transform);
if (detectEnemy != null)
{
target = detectEnemy;
}
}
}
return;
}
angularSpeed += angularAcceleration * deltaTime;
moveSpeed += moveAcceleration * deltaTime;
angularSpeed = Mathf.Max(angularSpeed, 0f);
moveSpeed = Mathf.Max(moveSpeed, 0f);
Vector3 direction = target.flexibleCenterPoint.position - projectile.position;
if (direction != Vector3.zero)
{
Quaternion targetRotation = Quaternion.LookRotation(direction);
// RotateTowards 保证恒定转速,不会因为角度小而变慢
projectile.rotation = Quaternion.RotateTowards(projectile.rotation, targetRotation, angularSpeed * deltaTime);
}
unscaledVelocity = projectile.forward * moveSpeed;
scaledVelocity = unscaledVelocity * timeScaleCoefficient;
projectile.position += scaledVelocity * deltaTime;
if (autoDisconnect)
{
float distanceToTarget = Vector3.Distance(projectile.position, target.flexibleCenterPoint.position);
if (distanceToTarget > detectRadius)
{
target = null;
}
}
}
}
}