【发布时间】:2021-05-21 07:43:38
【问题描述】:
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class WaypointsFollower : MonoBehaviour
{
public float speed;
public Waypoints waypoints;
public Transform capsule;
public bool go;
public bool goForward;
public float rotationSpeed;
private int index = 0;
private int counter = 0;
private int c = 0;
private List<GameObject> curvedLinePoints = new List<GameObject>();
public int numofposbetweenpoints;
private bool getonce;
private bool getBackwardIndexOnce = true;
private void Start()
{
waypoints = GameObject.Find("Waypoints").GetComponent<Waypoints>();
curvedLinePoints = GameObject.FindGameObjectsWithTag("Curved Line Point").ToList();
if(waypoints.moveInReverse == false)
{
goForward = true;
}
else
{
goForward = false;
}
if(goForward)
{
index = 0;
}
}
private void Update()
{
if (getonce == false)
{
numofposbetweenpoints = curvedLinePoints.Count;
getonce = true;
}
if (go == true && waypoints.lineRendererPositions.Count > 0)
{
if(goForward == false && getBackwardIndexOnce)
{
index = waypoints.lineRendererPositions.Count - 1;
getBackwardIndexOnce = false;
}
Move();
}
}
private void Move()
{
Vector3 newPos = transform.position;
float distanceToTravel = speed * Time.deltaTime;
bool stillTraveling = true;
while (stillTraveling)
{
Vector3 oldPos = newPos;
// error exception out of bound on line 55 to check !!!!!
newPos = Vector3.MoveTowards(oldPos, waypoints.lineRendererPositions[index], distanceToTravel);
distanceToTravel -= Vector3.Distance(newPos, oldPos);
if (newPos == waypoints.lineRendererPositions[index]) // Vector3 comparison is approximate so this is ok
{
// when you hit a waypoint:
if (goForward)
{
bool atLastOne = index >= waypoints.lineRendererPositions.Count - 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;
}
private void RotateTo()
{
// Determine which direction to rotate towards
Vector3 targetDirection = -capsule.position;
// The step size is equal to speed times frame time.
float singleStep = rotationSpeed * Time.deltaTime;
// Rotate the forward vector towards the target direction by one step
Vector3 newDirection = Vector3.RotateTowards(capsule.forward, targetDirection, singleStep, 0.0f);
// Draw a ray pointing at our target in
Debug.DrawRay(capsule.position, newDirection, Color.red);
// Calculate a rotation a step closer to the target and applies rotation to this object
capsule.rotation = Quaternion.LookRotation(newDirection);
}
}
变换沿航点移动,但我希望胶囊面向每个 numofposbetweenpoints 旋转。
有很多路点或多或少超过 4000 个,但点之间只有 10 个 numofpos。 此屏幕截图将清除它。 waypoints 是 linerenderer 的位置,numofposbetweenpoints 是连接线渲染器线的每条线的立方体。
在屏幕截图中,大立方体是脚本中的变换,该变换沿着作为 linerenderer 位置的 ping 线移动。背景中的小方块是linerenderer线的连接点。
我希望胶囊在每次变换移动时平滑地旋转观察 numofposbetweenpoints(小立方体),胶囊应该平滑地旋转观察下一个 numofposbetweenpoints。 numofposbetweenpoints 只有 10 个。
这是底部的旋转部分:
private void RotateTo()
{
// Determine which direction to rotate towards
Vector3 targetDirection = -capsule.position;
// The step size is equal to speed times frame time.
float singleStep = rotationSpeed * Time.deltaTime;
// Rotate the forward vector towards the target direction by one step
Vector3 newDirection = Vector3.RotateTowards(capsule.forward, targetDirection, singleStep, 0.0f);
// Draw a ray pointing at our target in
Debug.DrawRay(capsule.position, newDirection, Color.red);
// Calculate a rotation a step closer to the target and applies rotation to this object
capsule.rotation = Quaternion.LookRotation(newDirection);
}
在这一行,它每次都缺少下一个小立方体:
Vector3 targetDirection = -capsule.position;
我有小立方体 numofposbetweenpoints 的数量,但我如何获得对每个小立方体的引用并使 numofposbetweenpoints 索引每次都增加?
我在第 50 行:
numofposbetweenpoints = curvedLinePoints.Count;
curvedLinePoints 是一个列表,但我不确定如何对列表中的游戏对象进行旋转。
这是我到目前为止所做的,我认为轮换正在起作用,但不是我想要的:
在顶部我添加了:
private int rotationIndex = 0;
然后在 RotateTo 我将其更改为:
private void RotateTo()
{
var distance = Vector3.Distance(capsule.position, curvedLinePoints[rotationIndex].transform.position);
if(distance < 0.1f)
{
rotationIndex++;
}
// Determine which direction to rotate towards
Vector3 targetDirection = curvedLinePoints[rotationIndex].transform.position -capsule.position;
// The step size is equal to speed times frame time.
float singleStep = rotationSpeed * Time.deltaTime;
// Rotate the forward vector towards the target direction by one step
Vector3 newDirection = Vector3.RotateTowards(capsule.forward, targetDirection, singleStep, 0.0f);
// Draw a ray pointing at our target in
Debug.DrawRay(capsule.position, newDirection, Color.red);
// Calculate a rotation a step closer to the target and applies rotation to this object
capsule.rotation = Quaternion.LookRotation(newDirection);
}
两个问题:
-
即使我将旋转速度设置为 30,它的旋转速度仍然有点慢。为什么 30 这么慢?
-
旋转是在这个屏幕截图中的所有轴上,但我希望它只在 Y 轴上旋转,但是因为要使胶囊站立,我必须在 Y 轴上旋转时将 X 设置为 -90,它会改变胶囊 -喜欢缩放它。我希望胶囊能像自己一样旋转。
这是在游戏开始旋转之前运行游戏时胶囊在原版中的样子:
【问题讨论】:
-
为了清楚起见,您想以相同的速度沿当前对象的方向旋转对象吗?或者想立即旋转到列表中的下一个对象
curvedLinePoints,同时向它移动? -
@TEEBQNE 朝着它前进。但请注意,变换正在朝着,但我希望胶囊旋转。变换是移动胶囊旋转到列表曲线线点中的下一个对象的变换。你明白了。
-
@TEEBQNE 更新了我的问题,包括我做了什么、结果是什么以及我希望它是什么样的。我有两个问题。
-
刚刚回来并能够回答您更新的问题。如果您需要更多信息/详细信息,或者第二个 sn-p 不起作用,请告诉我。