【发布时间】:2021-04-08 05:36:59
【问题描述】:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class MoveOnCurvedLines : MonoBehaviour
{
public LineRenderer lineRenderer;
public float speed;
public bool go = false;
public bool moveToFirstPositionOnStart = false;
public float rotSpeed;
public bool random = false;
public int currentCurvedLinePointIndex;
private Vector3[] positions;
private Vector3[] pos;
private int index = 0;
private bool goForward = true;
private List<GameObject> curvedLinePoints = new List<GameObject>();
private int numofposbetweenpoints;
private bool getPositions = false;
int randomIndex;
int curvedPointsIndex;
// Start is called before the first frame update
void Start()
{
curvedLinePoints = GameObject.FindGameObjectsWithTag("Curved Line Point").ToList();
if (curvedLinePoints != null && curvedLinePoints.Count > 0)
{
transform.rotation = curvedLinePoints[1].transform.rotation;
}
if (random)
GetNewRandomIndex();
}
Vector3[] GetLinePointsInWorldSpace()
{
positions = new Vector3[lineRenderer.positionCount];
//Get the positions which are shown in the inspector
lineRenderer.GetPositions(positions);
//the points returned are in world space
return positions;
}
// Update is called once per frame
void Update()
{
if (lineRenderer.positionCount > 0 && getPositions == false)
{
pos = GetLinePointsInWorldSpace();
numofposbetweenpoints = pos.Length / curvedLinePoints.Count;
if (moveToFirstPositionOnStart == true)
{
transform.position = pos[index];
}
getPositions = true;
}
if (go == true && lineRenderer.positionCount > 0)
{
Move();
transform.localRotation = Quaternion.RotateTowards(transform.localRotation, curvedLinePoints[c].transform.localRotation, Time.deltaTime * rotSpeed);
}
var dist = Vector3.Distance(transform.position, curvedLinePoints[curvedPointsIndex].transform.position);
if (dist < 0.1f)
{
if (curvedPointsIndex < curvedLinePoints.Count - 1)
curvedPointsIndex++;
currentCurvedLinePointIndex = curvedPointsIndex;
}
}
int counter = 0;
int c = 1;
void Move()
{
Vector3 newPos = transform.position;
float distanceToTravel = speed * Time.deltaTime;
bool stillTraveling = true;
while (stillTraveling)
{
Vector3 oldPos = newPos;
newPos = Vector3.MoveTowards(oldPos, pos[index], distanceToTravel);
distanceToTravel -= Vector3.Distance(newPos, oldPos);
if (newPos == pos[index]) // Vector3 comparison is approximate so this is ok
{
// when you hit a waypoint:
if (goForward)
{
bool atLastOne = index >= pos.Length - 1;
if (!atLastOne)
{
index++;
counter++;
if (counter == numofposbetweenpoints)
{
c++;
counter = 0;
}
if (c == curvedLinePoints.Count - 1)
{
c = 0;
}
}
else { index--; goForward = false; }
}
else
{ // going backwards:
bool atFirstOne = index <= 0;
if (!atFirstOne)
{
index--;
counter++;
if (counter == numofposbetweenpoints)
{
c++;
counter = 0;
}
if (c == curvedLinePoints.Count - 1)
{
c = 0;
}
}
else { index++; goForward = true; }
}
}
else
{
stillTraveling = false;
}
}
transform.position = newPos;
}
}
在更新这一行中旋转变换:
transform.localRotation = Quaternion.RotateTowards(transform.localRotation, curvedLinePoints[c].transform.localRotation, Time.deltaTime * rotSpeed);
但首先它不应该与 'c' int 变量一起使用,因为计算错误,List curveLinePoints 中有 30 个立方体。但是当使用 numofposbetweenpoints 变量进行计算时,numofposbetweenpoints 中只有 20 个,然后当增加“c”变量时,它只会增加 20 而不是 30,但也许我在这部分错了。
第二个它根本不旋转。
在屏幕截图中,平台是移动的对象。创建楼梯的Cubes是curvedLinePoints List。
平台正在沿着立方体之间的 LineRenderer 位置移动,但我希望平台将面向弯曲线点列表中的立方体而不是 LineRenderer 位置旋转!
在数组 pos 上有 610 个位置,但我希望变换面向每个弯曲线点旋转。
在我看来,我认为当平台到达最后一个位置然后开始向下移动时,平台应该旋转绿色轴应该面朝下,因为平台现在正在向下移动,所以它应该看着曲线点正在向下的方向,但平台一直向前看,从不旋转到它正在移动的方向。
当平台到达/通过最后一个弯曲线点时,我认为这就是逻辑上应该是这样的。
【问题讨论】:
-
很高兴看到my answer 仍在帮助人们。游戏应该如何知道沿着移动轨迹的每个位置使用哪个旋转航路点?您需要某种方式告诉代码在每个航路点之间转弯的速度。我猜假设平台具有恒定的旋转速度是不正确的。最简单的方法是只拥有与位置航点相同数量的方向航点,并在它们之间进行插值。