Как создать гравитацию, направленную к конкретной точке?
Нужно сделать так, чтобы объект притягивался к конкретной точке (наподобие гравитации Земли). Объект должен плавно перемещаться между несколькими точками гравитации.
Из всего, что нашел на других форумах - создать свой собственный код гравитации через AddForce, но сколько ни пробовал, пока не получается.
Вот имеющийся неработающий код:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GravityPoint : MonoBehaviour {
public float force=12.0f;
void OnTriggerEnter2D(Collider2D coll)
{
GameObject colliderWith = coll.gameObject;
if (colliderWith.tag == "Player")
{
Vector3 playerPos = colliderWith.transform.position;
Vector3 pointPos = coll.transform.position;
Vector2 pointVec = new Vector2( pointPos.x-playerPos.x, pointPos.y-playerPos.y);
Rigidbody2D playerBody = colliderWith.GetComponent<Rigidbody2D>();
playerBody.AddForce(pointVec*force, ForceMode2D.Impulse);
}
}
}
Ответы (2 шт):
Вам нужен класс, отвечающий за гравитацию. Например
Public class Gravity
{
float X {get;set;} // координаты точки гравитации
float Y {get;set;}
float Z {get;set;}
float Acceleration {get;set;} // Ускорение падения, для данной гравитации
}
Далее вы находите вектор направления от вашего объекта к точке притяжение через координаты, и постоянно перемещаете его туда со скоростью X, саму скорость вы каждый раз увеличиваете на Acceleration, до соприкосновения с объектом, препятствующем этому перемещению, естественно
Нужно просто найти направление к точке и расстояние до неё и найти ускорение свободного падения по формуле, затем прибавить полученное значение к вектору скорости:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Gravity : MonoBehaviour {
public Rigitbody2D playerRb;
public Transform playerTr;
public Vector2 gravityPoint;
public float pointMass = 100; // масса точки, которая используется в расчётах
const long gravityConst = 15000000000; // единица делённая на гравитационную постоянную (чтобы не хранить много знаков после запятой)
private float distanse; // расстояние до точки
private float angle; // угол в сторону точки (в радианах)
private Vector2 deltaPos; // позиция точки относительно "игрока"
private float acceleration;
private Vector2 accelerationVector; // ускорение свободного падения
void Update() {
deltaPos = gravityPoint - playerTr.position;
angle = Mathf.Atan2(deltaPos.y, deltaPos.x);
distanse = Mathf.sqrt(deltaPos.x * deltaPos.x + deltaPos.y * deltaPos.y); // sqrt(x^2 + y^2) ищем катет по т. Пифагора
acceleration = pointMass / (distanse * distanse * gravityConst) // G(M / R^2);
accelerationVector = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) * acceleration;
playerRb.velocity = playerRb.velocity + accelerationVector * Time.deltaTime;
}
}
Или пример без космической физики:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Gravity : MonoBehaviour {
public Rigitbody2D playerRb;
public Transform playerTr;
public Vector2 gravityPoint;
public float force = 7; // постоянное ускорение
private float angle; // угол в сторону точки (в радианах)
private Vector2 deltaPos; // позиция точки относительно "игрока"
private Vector2 accelerationVector; // ускорение свободного падения
void Update() {
deltaPos = gravityPoint - playerTr.position;
angle = Mathf.Atan2(deltaPos.y, deltaPos.x);
accelerationVector = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) * forse;
playerRb.velocity = playerRb.velocity + accelerationVector * Time.deltaTime;
}
}
Школьная программа физики и разработка игр - неотделимые вещи)