Files
2026-03-02 17:14:59 +07:00

109 lines
3.5 KiB
C#

using UnityEngine;
namespace BrewMonster
{
/// <summary>
/// Helix (spiral) movement pattern.
/// Mirrors C++ CGfxHelixMove exactly (A3DSkillGfxEvent2.cpp:167-215).
/// 螺旋移动模式,完全镜像C++ CGfxHelixMove。
/// </summary>
public class CGfxHelixMove : CGfxMoveBase
{
protected float m_fFlyTime;
protected float m_fRadius;
protected float m_fShrinkRate;
protected float m_fAngle;
protected float m_fSpeed;
protected Vector3 m_vCenter;
protected Vector3 m_vAxisX;
protected Vector3 m_vAxisY;
private const float _fly_speed = 20.0f / 1000.0f; // units per ms, same as C++
private const float _ang_vel = Mathf.PI * 4.0f / 1000.0f; // angular velocity (radians per ms), same as C++
public CGfxHelixMove(GfxMoveMode mode) : base(mode)
{
m_fRadius = 0;
}
/// <summary>
/// Initialize helix movement from host to target.
/// 初始化从施法者到目标的螺旋移动。
/// </summary>
public override void StartMove(Vector3 vHost, Vector3 vTarget)
{
if (m_bArea)
{
CalcRange((vTarget - vHost).normalized);
m_vCenter = vHost + GetRandOff();
}
else
{
m_vCenter = vHost;
}
m_vMoveDir = vTarget - m_vCenter;
float fDist = Normalize(ref m_vMoveDir);
float fMax = _fly_speed * m_dwMaxFlyTime;
if (fMax >= fDist)
{
m_fSpeed = _fly_speed;
}
else
{
m_fSpeed = fDist / m_dwMaxFlyTime;
}
m_fFlyTime = fDist / m_fSpeed;
m_fShrinkRate = m_fRadius / m_fFlyTime;
// Calculate helix axes
// 计算螺旋轴
if (Mathf.Abs(m_vMoveDir.y) > 0.9f)
{
m_vAxisY = Vector3.Cross(m_vMoveDir, Vector3.right);
Normalize(ref m_vAxisY);
m_vAxisX = Vector3.Cross(m_vAxisY, m_vMoveDir);
}
else
{
m_vAxisX = Vector3.Cross(Vector3.up, m_vMoveDir);
Normalize(ref m_vAxisX);
m_vAxisY = Vector3.Cross(m_vMoveDir, m_vAxisX);
}
m_vPos = m_vCenter + m_vAxisX * m_fRadius;
m_fAngle = 0;
}
/// <summary>
/// Tick helix movement. Returns true when target is reached.
/// 更新螺旋移动。当到达目标时返回true。
/// </summary>
public override bool TickMove(uint dwDeltaTime, Vector3 vHostPos, Vector3 vTargetPos)
{
float fDelta = dwDeltaTime;
m_vCenter += m_vMoveDir * (m_fSpeed * fDelta);
m_fRadius -= m_fShrinkRate * fDelta;
m_fAngle -= _ang_vel * fDelta;
Vector3 vOff = m_vAxisX * (Mathf.Cos(m_fAngle) * m_fRadius)
+ m_vAxisY * (Mathf.Sin(m_fAngle) * m_fRadius);
m_vPos = m_vCenter + vOff;
m_fFlyTime -= fDelta;
return m_fFlyTime <= 0;
}
/// <summary>
/// Override to also read radius from param value.
/// 重写以从参数值中读取半径。
/// </summary>
public override void SetParam(GFX_SKILL_PARAM param)
{
base.SetParam(param);
m_fRadius = param.value.fVal; // C# union access: param.value.fVal
}
}
}