[英]2D Projectile Trajectory Prediction(unity 2D)
using (unity 2019.3.7f1) 2d.使用(统一 2019.3.7f1)2d。 I have a player that moves around using a pullback mechanic and has a max power(like in Angry Birds).
我有一个玩家使用回撤机制四处移动并且具有最大功率(例如在愤怒的小鸟中)。 I'm trying to draw a line(using a line renderer) that shows the exact path the player will go.
我正在尝试绘制一条线(使用线渲染器),以显示玩家将 go 的确切路径。 I'm trying to make the line curve just like the player's path will.
我试图让线条曲线就像玩家的路径一样。 so far I've only managed to make a straight line in a pretty scuffed way.
到目前为止,我只设法以一种非常磨损的方式制作一条直线。 The known variables are the Jump Power and the player's position, there is no friction.
已知变量为 Jump Power 和玩家的 position,没有摩擦。 and I believe gravity is a constant(-9.81).
我相信重力是一个常数(-9.81)。 Also, I would like to have a variable that allows me to control the line's length.
另外,我想要一个变量来控制线条的长度。 And, if possible, the line will not go through objects and would act as if it has a collider.
而且,如果可能的话,这条线不会 go 穿过物体,而是会像有一个对撞机一样工作。
// Edit // 编辑
This is my current code.这是我当前的代码。 I changed The function so it would return the list's points because I wanted to be able to access it in Update() so it would only draw while I hold my mouse button.
我更改了 function 所以它会返回列表的点,因为我希望能够在 Update() 中访问它,所以它只会在我按住鼠标按钮时绘制。
My problem is that the trajectory line doesn't seem to curve, it goes in the right angle but it's straight.我的问题是轨迹线似乎没有弯曲,它成直角但它是直的。 the line draws in the right direction and angle, but my initial issue of the line not curving remains unchanged.
这条线以正确的方向和角度绘制,但我最初的线不弯曲问题保持不变。 If you could please come back to me with an answer I would appreciate it.
如果你能请回来给我一个答案,我将不胜感激。
enter code here
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TrajectoryShower : MonoBehaviour
{
LineRenderer lr;
public int Points;
public GameObject Player;
private float collisionCheckRadius = 0.1f;
public float TimeOfSimulation;
private void Awake()
{
lr = GetComponent<LineRenderer>();
lr.startColor = Color.white;
}
// Update is called once per frame
void Update()
{
if (Input.GetButton("Fire1"))
{
lr.positionCount = SimulateArc().Count;
for (int a = 0; a < lr.positionCount;a++)
{
lr.SetPosition(a, SimulateArc()[a]);
}
}
if (Input.GetButtonUp("Fire1"))
{
lr.positionCount = 0;
}
}
private List<Vector2> SimulateArc()
{
float simulateForDuration = TimeOfSimulation;
float simulationStep = 0.1f;//Will add a point every 0.1 secs.
int steps = (int)(simulateForDuration / simulationStep);
List<Vector2> lineRendererPoints = new List<Vector2>();
Vector2 calculatedPosition;
Vector2 directionVector = Player.GetComponent<DragAndShoot>().Direction;// The direction it should go
Vector2 launchPosition = transform.position;//Position where you launch from
float launchSpeed = 5f;//The initial power applied on the player
for (int i = 0; i < steps; ++i)
{
calculatedPosition = launchPosition + (directionVector * ( launchSpeed * i * simulationStep));
//Calculate gravity
calculatedPosition.y += Physics2D.gravity.y * (i * simulationStep);
lineRendererPoints.Add(calculatedPosition);
if (CheckForCollision(calculatedPosition))//if you hit something
{
break;//stop adding positions
}
}
return lineRendererPoints;
}
private bool CheckForCollision(Vector2 position)
{
Collider2D[] hits = Physics2D.OverlapCircleAll(position, collisionCheckRadius);
if (hits.Length > 0)
{
for (int x = 0;x < hits.Length;x++)
{
if (hits[x].tag != "Player" && hits[x].tag != "Floor")
{
return true;
}
}
}
return false;
}
} }
This is basically a sum of 2 vectors along the time.这基本上是 2 个向量的总和。
You have your initial position (x0, y0), initial speed vector (x, y) and gravity vector (0, -9.81) being added along the time.您会同时添加初始 position (x0, y0)、初始速度矢量 (x, y) 和重力矢量 (0, -9.81)。 You can build a function that gives you the position over time:
您可以构建一个 function,随着时间的推移为您提供 position:
f(t) = (x0 + x*t, y0 + y*t - 9.81t²/2)
translating to Unity:
Vector2 positionInTime(float time, Vector2 initialPosition, Vector2 initialSpeed){
return initialPosition +
new Vector2(initialSpeed.x * t, initialSpeed.y * time - 4.905 * (time * time);
}
Now, choose a little delta time, say dt = 0.25
.现在,选择一点增量时间,例如
dt = 0.25
。
Time | Position
0) 0.00 | f(0.00) = (x0, y0)
1) 0.25 | f(0.25) = (x1, y1)
2) 0.50 | f(0.50) = (x2, y2)
3) 0.75 | f(0.75) = (x3, y3)
4) 1.00 | f(1.00) = (x4, y4)
... | ...
Over time, you have a lot of points where the line will cross.随着时间的流逝,您将有很多线会交叉的点。 Choose a time interval (say 3 seconds), evaluate all the points between 0 and 3 seconds (using
f
) and put your line renderer to cover one by one.选择一个时间间隔(比如 3 秒),评估 0 到 3 秒之间的所有点(使用
f
),然后让你的线渲染器一个接一个地覆盖。
The line renderer have properties like width, width over time, color, etc. This is up to you.线渲染器具有宽度、随时间变化的宽度、颜色等属性。这取决于您。
Here's a simple way to visualize this.这是一种可视化的简单方法。
To create your line you want a bunch of points.要创建你的线,你需要一堆点。
private float collisionCheckRadius = 0.1f;
private void SimulateArc()
{
float simulateForDuration = 5f;//simulate for 5 secs in the furture
float simulationStep = 0.1f;//Will add a point every 0.1 secs.
int steps = (int)(simulateForDuration/simulationStep);//50 in this example
List<Vector2> lineRendererPoints = new List<Vector2>();
Vector2 calculatedPosition;
Vector2 directionVector = new Vector2(0.5f,0.5f);//You plug you own direction here this is just an example
Vector2 launchPosition = Vector2.zero;//Position where you launch from
float launchSpeed = 10f;//Example speed per secs.
for(int i = 0; i < steps; ++i)
{
calculatedPosition = launchPosition + ( directionVector * (launchSpeed * i * simulationStep));
//Calculate gravity
calculatedPosition.y += Physics2D.gravity.y * ( i * simulationStep) * ( i * simulationStep);
lineRendererPoints.Add(calculatedPosition);
if(CheckForCollision(calculatedPosition))//if you hit something
{
break;//stop adding positions
}
}
//Assign all the positions to the line renderer.
}
private bool CheckForCollision(Vector2 position)
{
Collider2D[] hits = Physics2D.OverlapCircleAll(position, collisionCheckRadius);
if(hits.Length > 0)
{
//We hit something
//check if its a wall or seomthing
//if its a valid hit then return true
return true;
}
return false;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.