因为VR中的瞬移标志有时候感觉不太明显,所以想要在手柄和标志之间生成一条抛物线,总结了一下抛物线的基础知识。
平抛运动
平抛运动可用两种 途径来解答:一种是位移路径,另一种是速度路径。
- 位移路径
水平:s=vt
h=Vot+ 0.5gt*t,Vo为竖直方向的初速速 - 速度:Vx=s/t
Vy=Vo+gt
LineRenderer的用法
常用的属性有:
- alignment:组件是否面向相机
- endColor,startColor:开始和结束的颜色
- endWidth,startWidth:开始和结束的宽度
- material:设置lineRenderer的材质
- positionCount:set the number of line segments(分割,段,部分)
- setPositions:set the positions of all vertices in the line,设置lineRenderer的所有顶点。
开始生成抛物线吧
第一种生成抛物线的方法是已知抛物线的起点和终点,求两点间的抛物线方程
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GenerateRay : MonoBehaviour {
public float ShotSpeed = 10; // 抛出的速度
public Transform pointA; // 起点
public Transform pointB; // 终点
private float g = -9.8f; // 重力加速度
private float time; // A-B的时间
private Vector3 speed; // 初速度向量
private Vector3 Gravity; // 重力向量
private LineRenderer lineRenderer;
public Material lineMat;
public float startWidth = 0.21f;
public float endWidth = 0.21f;
public Color lineColor = Color.green;
public int lineVertex = 20;
void Start()
{
initLineRenderer();
// 时间=距离/速度
time = Vector3.Distance(pointA.position, pointB.position) / ShotSpeed;
// 设置起始点位置为A
transform.position = pointA.position;
// 通过一个式子计算初速度
//h=Vo*t+0.5f*g*t*t
speed = new Vector3((pointB.position.x - pointA.position.x) / time,
(pointB.position.y - pointA.position.y) / time - 0.5f * g * time,
(pointB.position.z - pointA.position.z) / time);
// 重力初始速度为0
Gravity = Vector3.zero;
g = -2 * (pointA.position.y - pointB.position.y);
generateLineRenderer();
}
private float dTime = 0;
// Update is called once per frame
void FixedUpdate()
{
Vector3 currentPos = Vector3.zero;
//// v=gt
Gravity.y = g * dTime;
dTime += Time.fixedDeltaTime;
////模拟位移 x=Vo*t+
transform.position += (speed + Gravity) * Time.fixedDeltaTime;
}
void initLineRenderer()
{
if (GetComponent<LineRenderer>())
{
lineRenderer = GetComponent<LineRenderer>();
}
else
{
lineRenderer = gameObject.AddComponent<LineRenderer>();
}
lineRenderer.enabled = false;
lineRenderer.alignment = LineAlignment.Local;
lineRenderer.positionCount = lineVertex;
lineRenderer.startWidth = startWidth;
lineRenderer.endWidth = endWidth;
lineRenderer.material = lineMat;
lineRenderer.startColor = lineColor;
lineRenderer.endColor = lineColor;
}
private void generateLineRenderer()
{
lineRenderer.positionCount = lineVertex;
Vector3[] linePoints = new Vector3[lineVertex+1];
for (int i = 0; i <lineVertex; i++)
{
float x = pointA.position.x + (pointB.position.x - pointA.position.x) / lineVertex * i;
float y = pointA.position.y + 0.5f * g * ( (float)i / lineVertex) * ((float)i / lineVertex);
float z = pointA.position.z + (pointB.position.z - pointA.position.z) / lineVertex * i;
linePoints[i] = new Vector3(x, y, z);
}
lineRenderer.enabled = true;
lineRenderer.SetPositions(linePoints);
}
private void Update()
{
if(Input.GetKeyDown(KeyCode.Space))
{
generateLineRenderer();
}
}
}