Создайте кривую, чтобы показать, где объект будет проецироваться в Unity. - PullRequest
0 голосов
/ 05 апреля 2020

У меня есть некоторый код ниже, который проецирует объект вдоль кривой в заданную позицию, и он отлично работает.

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, но я не уверен, как включить это в мой способ перемещения объекта. Любая помощь о том, как это сделать, будет высоко ценится.

1 Ответ

0 голосов
/ 05 апреля 2020

Я отредактировал ваш код, чтобы 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);

    }
}

...