c# - 创建一条曲线以显示对象在 Unity 中的投影位置
问题描述
我在下面有一些代码,可以将对象沿曲线投影到给定位置,并且效果很好。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour {
public GameObject platform;
public Vector3 targetPos;
public float speed = 10;
public float arcHeight = 1;
Vector3 startPos;
GameObject line;
// Use this for initialization
void Start () {
startPos = transform.position;
targetPos = platform.transform.position;
targetPos.x -= 0.7f;
targetPos.y += 1.5f;
}
// Update is called once per frame
void Update () {
movePlayer();
}
void movePlayer()
{
// Compute the next position, with arc added in
float x0 = startPos.x;
float x1 = targetPos.x;
float dist = x1 - x0;
float nextX = Mathf.MoveTowards(transform.position.x, x1, speed * Time.deltaTime);
float baseY = Mathf.Lerp(startPos.y, targetPos.y, (nextX - x0) / dist);
float arc = arcHeight * (nextX - x0) * (nextX - x1) / (-0.25f * dist * dist);
Vector3 nextPos = new Vector3(nextX, baseY + arc, transform.position.z);
transform.position = nextPos;
// Do something when we reach the target
if (nextPos == targetPos) Arrived();
}
void Arrived()
{
Destroy(gameObject);
}
}
我现在希望能够添加一条可见曲线,该曲线将显示对象的路径。我看过一些使用 LineRenderer 的示例,但我不确定如何将其合并到我移动对象的方式中。任何有关如何做到这一点的帮助将不胜感激。
解决方案
我编辑了您的代码以让 LineRenderer 创建路径。这个想法是您提前生成对象的坐标,使用位置作为下一个位置的输入。(所以不仅仅取决于你的对象的变换)。
一定要Material
在inspector中设置a,否则你只会看到一条粉红色的线。我希望这是你的想法。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move : MonoBehaviour
{
public GameObject platform;
public Vector3 targetPos;
public float speed = 10;
public float arcHeight = 1;
Vector3 startPos;
GameObject line;
/// <summary>
/// Our linerenderer
/// </summary>
private LineRenderer lineRenderer;
/// <summary>
/// Line material.
/// </summary>
[SerializeField]
private Material lineMaterial;
// Use this for initialization
private void Start()
{
startPos = transform.position;
targetPos = platform.transform.position;
targetPos.x -= 0.7f;
targetPos.y += 1.5f;
// Add a linerenderer.
lineRenderer = gameObject.AddComponent<LineRenderer>();
if (lineMaterial == null)
{
Debug.LogError("No LineMaterial specified!");
}
// If you do not want to use worldspace, set this to false:
lineRenderer.useWorldSpace = true;
// Set preferred texture mode for texture.
lineRenderer.textureMode = LineTextureMode.RepeatPerSegment;
// Shadows, or not?
//lineRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
//lineRenderer.receiveShadows = false;
// Finally, set the material that you want to assign.
// Remember: If you use default shader, it needs to be set to "Transparent" to get your texture's alpha working.
lineRenderer.sharedMaterial = lineMaterial;
}
// Update is called once per frame
private void Update()
{
movePlayer();
}
private void movePlayer()
{
// Compute the next position, with arc added in
Vector3 nextPos = newPosition(transform.position, speed * Time.deltaTime);
transform.position = nextPos;
// Calculate upcoming positions.
Vector3[] points = generateUpcomingPositions(nextPos);
CreateLine(points);
// Do something when we reach the target
if (nextPos == targetPos) Arrived();
}
private Vector3 newPosition(Vector3 currentPosition, float delta)
{
float x0 = startPos.x;
float x1 = targetPos.x;
float dist = x1 - x0;
float nextX = Mathf.MoveTowards(currentPosition.x, x1, delta);
float baseY = Mathf.Lerp(startPos.y, targetPos.y, (nextX - x0) / dist);
float arc = arcHeight * (nextX - x0) * (nextX - x1) / (-0.25f * dist * dist);
Vector3 nextPos = new Vector3(nextX, baseY + arc, currentPosition.z);
return nextPos;
}
private Vector3[] generateUpcomingPositions(Vector3 currentPosition)
{
int steps = 10;
float delta = (1.0f / ((steps - 1))) * 2.0f;// Double delta.
List<Vector3> points = new List<Vector3>();
Vector3 newPos = currentPosition;
for (int i = 0; i < steps; i++)
{
// Use newPos as input for location.
newPos = newPosition(newPos, delta * i);
points.Add(newPos);
}
return points.ToArray();
}
private void Arrived()
{
Destroy(gameObject);
}
/// <summary>
/// Create a line with a given name, width and points.
/// </summary>
/// <param name="points"></param>
private void CreateLine(Vector3[] points)
{
// Set the positions.
lineRenderer.positionCount = points.Length;
lineRenderer.SetPositions(points);
}
}
推荐阅读
- batch-file - 在 bat FOR /R 循环中获取子目录名称并相应地命名文件
- javascript - 使用数组属性设置 React 或 Recoil 状态对象的更简单方法
- javascript - 使用 vue.js 提高表列上悬停效果的反应性/性能
- javascript - 如果 data-attribut 等于 0,“parents().filter”返回未定义
- python - 具有许多值的 Python Dash 下拉列表
- cmd - 卸载 anaconda 后 Cmd 崩溃,退出代码为 1
- python-3.x - 为什么通过 boto 将文件上传到 s3 会受到限制?我怎样才能让它更快?
- javascript - 如何构造循环以检查嵌套数组中是否不存在对象值
- javascript - 在玩笑测试中忽略某些导入函数的最佳方法
- python - Big Sur 上的 2019 Macbook Pro + 最新版 Spyder 上的 Pandas 导入错误