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

111 lines
3.5 KiB
C#

using UnityEngine;
namespace BrewMonster
{
/// <summary>
/// Curved movement with lateral acceleration.
/// Mirrors C++ CGfxCurvedMove exactly (A3DSkillGfxEvent2.cpp:217-265).
/// 带横向加速度的曲线移动,完全镜像C++ CGfxCurvedMove。
/// </summary>
public class CGfxCurvedMove : CGfxMoveBase
{
protected bool m_bFromRight;
protected float m_fLatSpd;
protected float m_fTime;
protected float m_fSpeed;
protected Vector3 m_vAxisX;
protected Vector3 m_vAxisZ;
protected Vector3 m_vZSpd;
private const float _fly_speed = 20.0f / 1000.0f; // units per ms, same as C++
private const float _curved_acc = 20.0e-6f; // lateral acceleration, same as C++
public CGfxCurvedMove(GfxMoveMode mode) : base(mode)
{
m_bFromRight = true;
}
/// <summary>
/// Initialize curved movement from host to target.
/// 初始化从施法者到目标的曲线移动。
/// </summary>
public override void StartMove(Vector3 vHost, Vector3 vTarget)
{
if (m_bArea)
{
CalcRange((vTarget - vHost).normalized);
m_vPos = vHost + GetRandOff();
}
else
{
m_vPos = vHost;
}
m_vAxisZ = vTarget - m_vPos;
float fDist = Normalize(ref m_vAxisZ);
float fMax = m_dwMaxFlyTime * _fly_speed;
if (fMax >= fDist)
{
m_fSpeed = _fly_speed;
}
else
{
m_fSpeed = fDist / m_dwMaxFlyTime;
}
m_fTime = fDist / m_fSpeed;
m_fLatSpd = _curved_acc * 0.5f * m_fTime;
// Calculate lateral axis
// 计算横向轴
if (Mathf.Abs(m_vAxisZ.y) > 0.9f)
{
Vector3 vY = Vector3.Cross(m_vAxisZ, Vector3.right);
Normalize(ref vY);
m_vAxisX = Vector3.Cross(vY, m_vAxisZ);
}
else
{
m_vAxisX = Vector3.Cross(Vector3.up, m_vAxisZ);
}
// Randomly choose direction (left or right)
// 随机选择方向(左或右)
if (Random.value > 0.5f)
{
m_vAxisX = -m_vAxisX;
}
m_vZSpd = m_fSpeed * m_vAxisZ;
m_vMoveDir = (m_vZSpd + m_fLatSpd * m_vAxisX).normalized;
}
/// <summary>
/// Tick curved movement. Returns true when target is reached.
/// 更新曲线移动。当到达目标时返回true。
/// </summary>
public override bool TickMove(uint dwDeltaTime, Vector3 vHostPos, Vector3 vTargetPos)
{
float fDelta = dwDeltaTime;
float fVEnd = m_fLatSpd - _curved_acc * fDelta;
float fOff = 0.5f * (m_fLatSpd + fVEnd) * fDelta;
m_fLatSpd = fVEnd;
m_vPos += fDelta * m_vZSpd + fOff * m_vAxisX;
m_vMoveDir = (m_vZSpd + m_fLatSpd * m_vAxisX).normalized;
m_fTime -= fDelta;
return m_fTime <= 0;
}
/// <summary>
/// Override to also read fromRight flag from param value.
/// 重写以从参数值中读取fromRight标志。
/// </summary>
public override void SetParam(GFX_SKILL_PARAM param)
{
base.SetParam(param);
m_bFromRight = param.value.bVal; // C# union access: param.value.bVal
}
}
}