using UnityEngine; namespace BrewMonster { /// /// Parabolic trajectory movement with gravity. /// Mirrors C++ CGfxParabolicMove exactly (A3DSkillGfxEvent2.cpp:54-92). /// 抛物线轨迹移动(带重力),完全镜像C++ CGfxParabolicMove。 /// public class CGfxParabolicMove : CGfxMoveBase { protected Vector3 m_vOrgPos; protected Vector3 m_vHorzVel; protected float m_fVertVel; protected float m_fTotalTime; protected float m_fCurTime; protected float m_fSpeed; private const float _fly_speed = 20.0f / 1000.0f; // units per ms, same as C++ private const float _gravity = 9.8e-6f; // gravity constant, same as C++ public CGfxParabolicMove(GfxMoveMode mode) : base(mode) { } /// /// Initialize parabolic trajectory from host to target. /// 初始化从施法者到目标的抛物线轨迹。 /// 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_vHorzVel = vTarget - m_vPos; float fVert = m_vHorzVel.y; m_vHorzVel.y = 0; float fDist = Normalize(ref m_vHorzVel); float fMax = _fly_speed * m_dwMaxFlyTime; if (fMax >= fDist) { m_fSpeed = _fly_speed; } else { m_fSpeed = fDist / m_dwMaxFlyTime; } m_fTotalTime = fDist / m_fSpeed; m_vHorzVel *= m_fSpeed; m_fVertVel = fVert / m_fTotalTime + 0.5f * _gravity * m_fTotalTime; m_vMoveDir = (m_vHorzVel + m_fVertVel * Vector3.up).normalized; m_fCurTime = 0; } /// /// Tick parabolic movement. Returns true when target is reached. /// 更新抛物线移动。当到达目标时返回true。 /// public override bool TickMove(uint dwDeltaTime, Vector3 vHostPos, Vector3 vTargetPos) { m_fCurTime += dwDeltaTime; if (m_fCurTime >= m_fTotalTime) { return true; } float fVertVel = m_fVertVel - _gravity * m_fCurTime; float fVertDist = 0.5f * (fVertVel + m_fVertVel) * m_fCurTime; m_vPos = m_vOrgPos + m_fCurTime * m_vHorzVel + fVertDist * Vector3.up; m_vMoveDir = (m_vHorzVel + fVertVel * Vector3.up).normalized; return false; } } }