using UnityEngine; namespace BrewMonster { /// /// Helix (spiral) movement pattern. /// Mirrors C++ CGfxHelixMove exactly (A3DSkillGfxEvent2.cpp:167-215). /// 螺旋移动模式,完全镜像C++ CGfxHelixMove。 /// 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; } /// /// Initialize helix movement from host to target. /// 初始化从施法者到目标的螺旋移动。 /// 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; } /// /// Tick helix movement. Returns true when target is reached. /// 更新螺旋移动。当到达目标时返回true。 /// 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; } /// /// Override to also read radius from param value. /// 重写以从参数值中读取半径。 /// public override void SetParam(GFX_SKILL_PARAM param) { base.SetParam(param); m_fRadius = param.value.fVal; // C# union access: param.value.fVal } } }