Для тех, кто ищет решение этой проблемы, вот решение:
private float _power = 0.5f;
private float _mass = 0.5f;
private float _powerMultiplier = 2000f; //Adjust this to lower or raise max reach
public void Update()
{
Vector2 target = Global.Player1.CastlePosition;
Vector2 source = transform.position;
if (!CanHitCoordinate(source, target))
{
_power += 0.01f;
return;
}
float angle = CalculateAngleToHitCoordinate(source, target);
Vector3 newAngle = new Vector3(0, 0, angle);
_cannon.transform.localEulerAngles = newAngle;
}
private float CalculateAngleToHitCoordinate(Vector2 source, Vector2 target)
{
float power = _power * _powerMultiplier;
float x = -(source.x - target.x);
float y = -(source.y - target.y);
float v = (power/mass) * Time.fixedDeltaTime;
float g = -Physics2D.gravity.y; //Needs to be positive
float sqrt = (v * v * v * v) - (g * (g * (x * x) + 2 * y * (v * v)));
sqrt = Mathf.Sqrt(sqrt);
double angleInRadians = Math.Atan((v * v + sqrt)/(g * x));
return (float)angleInRadians * Mathf.Rad2Deg;
}
private float CalculateDelta(Vector2 source, Vector2 target)
{
float power = _power * _powerMultiplier;
float x = (source.x - target.x);
float y = -(source.y - target.y);
float v = (power/0.5f) * Time.fixedDeltaTime;
float g = -Physics2D.gravity.y;
return (v * v * v * v) - (g * (g * (x * x) + 2 * y * (v * v)));
}
public bool CanHitCoordinate(Vector2 source, Vector2 target)
{
return CalculateDelta(source, target) >= 0;
}
Это для источника стрельбы к цели справа от него. Для того, чтобы стрелять в направлении цели на левой просто сделать эти два изменения в коде выше:
float x = (source.x - target.x); //Remove "-"
Vector3 newAngle = new Vector3(0, 180, angle); //Point towards the left
Там действительно нет необходимости использовать двойники здесь, вы можете придерживаться с поплавком только для простоты (и использовать 'Mathf.Sqrt() '). Какая ценность 'g'? –
g - -9,81. Благодарю. – user1841016