Files
2026-03-02 19:22:44 +07:00

90 lines
3.2 KiB
C#

using UnityEngine;
namespace BrewMonster
{
/// <summary>
/// Homing missile movement with rotation toward target.
/// Mirrors C++ CGfxMissileMove exactly (A3DSkillGfxEvent2.cpp:94-142).
/// 追踪导弹移动(向目标旋转),完全镜像C++ CGfxMissileMove。
/// </summary>
public class CGfxMissileMove : CGfxMoveBase
{
protected Vector3 m_vOrgPos;
protected float m_fCurVel;
private const float _missile_acc = 20.0f; // acceleration, same as C++
private const float _missile_vel = 5.0f; // initial velocity, same as C++
private const float _missile_rot = Mathf.PI * 1.5f; // rotation speed (radians per second), same as C++
private float _angle_limit = Mathf.Cos(15.0f * Mathf.Deg2Rad); // 15 degree limit, same as C++
public CGfxMissileMove(GfxMoveMode mode) : base(mode) { }
/// <summary>
/// Initialize missile movement from host to target.
/// 初始化从施法者到目标的导弹移动。
/// </summary>
public override void StartMove(Vector3 vHost, Vector3 vTarget)
{
if (m_bArea)
{
CalcRange((vTarget - vHost).normalized);
m_vOrgPos = m_vPos = vHost + GetRandOff();
}
else
{
m_vOrgPos = m_vPos = vHost;
}
m_vMoveDir = vTarget - m_vPos;
m_vMoveDir.y = 0;
Normalize(ref m_vMoveDir);
// Random initial angle around Y axis (PI/2 to 3*PI/2 range)
// 围绕Y轴的随机初始角度(PI/2到3*PI/2范围)
float fAngle = Mathf.PI / 2.0f + Mathf.PI * Random.value;
Quaternion q = Quaternion.AngleAxis(fAngle * Mathf.Rad2Deg, Vector3.up);
m_vMoveDir = q * m_vMoveDir;
m_fCurVel = _missile_vel;
}
/// <summary>
/// Tick missile movement. Returns true when target is hit.
/// 更新导弹移动。当命中目标时返回true。
/// </summary>
public override bool TickMove(uint dwDeltaTime, Vector3 vHostPos, Vector3 vTargetPos)
{
float fTime = dwDeltaTime / 1000.0f;
Vector3 vDir = vTargetPos - m_vPos;
float fDist = m_fCurVel * fTime;
if (fDist >= Normalize(ref vDir))
{
return true;
}
float fAngle = Vector3.Dot(m_vMoveDir, vDir);
if (fAngle > _angle_limit)
{
// Close enough to target direction, accelerate and move directly
// 足够接近目标方向,加速并直接移动
m_fCurVel += _missile_acc * fTime;
m_vPos += vDir * fDist;
m_vMoveDir = vDir;
}
else
{
// Rotate toward target
// 向目标旋转
m_vPos += m_vMoveDir * fDist;
Vector3 vUp = Vector3.Cross(m_vMoveDir, vDir);
Normalize(ref vUp);
Quaternion q = Quaternion.AngleAxis(_missile_rot * fTime * Mathf.Rad2Deg, vUp);
m_vMoveDir = q * m_vMoveDir;
}
return false;
}
}
}