90 lines
3.2 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|