using Fort23.Core; #if !COMBAT_SERVER using UnityEngine; #endif public class ParabolaPath : CObject { public Vector2 startPos; public Vector2 targetPos; private Vector2 posOff; private float gravity = (float)(-19); public float addH; public ParabolaPath() { } public ParabolaPath(Vector2 startPos, Vector2 targetPos) { SetPos(startPos, targetPos); } // public void SetPos(Vector2 startPos, Vector2 targetPos) // { // SetPos(new Vector2(startPos), new Vector2(targetPos)); // } public void SetPos(Vector3 startPos, Vector3 targetPos) { SetPos(startPos, targetPos); } public void SetPos(Vector2 startPos, Vector2 targetPos) { this.startPos = startPos; this.targetPos = targetPos; posOff = this.targetPos - this.startPos; } public Vector2 GetPos(float t) { t = Mathf.Clamp(t, 0, 1); float h = posOff.y + posOff.magnitude / 2 + addH; float v0; float angle; float time; CalculatePathWithHeight(posOff, h, out v0, out angle, out time); return CalculatePath(v0, angle, time, t); } private Vector2 CalculatePath(float v0, float angle, float step, float t) { float v = step * t; float x = v0 * v * Mathf.Cos(angle); float y = v0 * v * Mathf.Sin(angle) - 0.5f * -gravity * Mathf.Pow(v, (float)2); return new Vector2(x, y) + startPos; } private float QuadraticEquation(float a, float b, float c, float sign) { float v = b * b - 4 * a * c; v = Mathf.Max((float)0.01f, v); return (-b + sign * Mathf.Sqrt(v)) / (2 * a); } private void CalculatePathWithHeight(Vector2 targetPos, float h, out float v0, out float angle, out float time) { h = Mathf.Max((float)0.01f, h) * 0.5f; float xt = targetPos.x; float yt = targetPos.y; float g = -gravity; float a = (-0.5f * g); float c = -yt; float b = Mathf.Sqrt(2 * g * h); float tplus = QuadraticEquation(a, b, c, (float)1); float tmin = QuadraticEquation(a, b, c, (float)(-1)); time = tplus > tmin ? tplus : tmin; angle = Mathf.Atan(b * time / xt); v0 = b / Mathf.Sin(angle); } public override void ActiveObj() { } public override void DormancyObj() { } }