创建曲线以显示对象在Unity中的投影位置

问题描述 投票:0回答:1

我下面有一些代码,可以将对象沿曲线投影到给定位置,并且可以完美地工作。

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的示例,但是我不确定如何将其合并到移动对象的方式中。任何有关如何执行此操作的帮助将不胜感激。

c# unity3d curve
1个回答
0
投票

我编辑了您的代码,以使LineRenderer创建路径。这个想法是您使用一个位置作为下一个位置的输入来预先生成对象的坐标。 (因此,不仅取决于对象的变换)。

请确保在检查器中设置Material,否则您只会看到一条粉红色的线。我希望这就是您的想法。

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);

    }
}

© www.soinside.com 2019 - 2024. All rights reserved.