如何在不留空隙的情况下为线条渲染器形状设置动画

时间:2017-10-31 20:53:10

标签: c# unity3d

我使用下面的代码根据点数创建带有线条渲染器的形状。对于大于3的点(三角形等),第一个和最后一个点不会像其他点那样关闭形状。

1 。如何在没有任何明显间隙的情况下关闭超过3个点的形状?

2 。如何为形状设置动画,以便在特定的持续时间内绘制线条(可能使用协程)?

body

3 个答案:

答案 0 :(得分:0)

如果确保LineRenderer的最后一个点与第一个点相同,则应始终关闭任何给定的形状。像for一样运行for (int i = 0; i < Points - 1; i++)循环(所以每个点都是最后一个,也是<而不是<=)。然后在for循环完成时用lineRenderer.SetPosition(Point - 1, lineRenderer.GetPosition(0));关闭形状。

请注意,数组从0开始,这就是为什么Point - 1是lineRenderer的最后一点。

对于动画,我不知道一个简单的方法。我要做的是使用协程将每个点移动到最终目的地。例如,您首先添加第一个点,然后在第一个点的顶部添加第二个点。然后你(在协程中随着时间的推移)移动第二个点到它的最终位置(使用SetPosition来移动它)。当它到达它的最终位置时,在它的顶部添加第三个点,并将其移动到它的最终位置。重复每一点。

答案 1 :(得分:0)

第一个(可能是显而易见的)解决方案是在 LineRenderer 上设置循环选项。然而,在许多情况下,这似乎并没有给出视觉上令人满意的结果。

我会像这样修复问题,这会给出很好的视觉效果:

<head>

lineRenderer.positionCount = Points + 2;    //+2 to close the shape and create one more piece to extend over the gap.

绘制完整的形状,然后再创建一个,在开始时循环回来。这可能不会让人觉得优雅,但它很简单,看起来就像我想象的那样。

至于动画,尝试这样的事情:

for (int i = 0; i <= Points + 1; i++) // one more piece

您基本上已经拥有了所有内容,现在通过设置您正在使用的值的动画来设置动画。当然,有很多方法可以实现不同的效果,但是大多数方法都是将动画进度值应用于绘图的不同参数。您可以使用协程或仅使用常规的Update()循环,如示例所示。我希望这会有所帮助;)

答案 2 :(得分:0)

因此,我们的想法是增加将顶点连接到顶点的线渲染器。

下面的解决方案是针对一个立方体,但我添加了一个额外的顶点,它很好。 我唯一无法测试的是循环设置,因为我在5.5 ...我认为它有效... 另外,我没有通过任何材料,我猜你有。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
    [SerializeField]
    private float step = 0.5f;  // How fast it draws
    private List<Vector3> vertices = null;
    private LineRenderer line = null;
    private void Start()
    {
        // This creates a square
        this.vertices = new List<Vector3>()
        {
            new Vector3(-1,-1,0), new Vector3(1,-1,0), new Vector3(1,1,0),new Vector3(-1, 1, 0)
        };
        StartCoroutine(Draw());
    }
    private IEnumerator Draw()
    {
        int index = 1;
        int vertexPos = 1;
        // Set the LineRenderer basics with 2 vertices
        this.line = this.gameObject.AddComponent<LineRenderer>();
        this.line.startWidth = this.line.endWidth= 0.1f;
        this.line.numPositions = 2; 
        // Set both point at same starting position   
        this.line.SetPosition(0,this.vertices[0]);
        this.line.SetPosition(1, this.vertices[0]);
        Vector3 temp = this.vertices[0];        // Get the current vertex position
        Vector3 target = this.vertices[index];  // Get the target vertex position
        while (true)
        {     
            // Move the current pos to the target pos                      
            temp = Vector3.MoveTowards(temp, target, Time.deltaTime * this.step);
            this.line.SetPosition(vertexPos, temp);
            // Is the target reached
            if (temp == target)
            {
                // This is for final run when closing the shape
                // It means we reach target and index is 0 so end of shape
                // Break the coroutine
                if(index == 0)
                {
                    this.line.loop = true;  // Could not test this one on 5.5
                    yield break;
                }
                // Increase the LineRenderer size by 1
                vertexPos++;
                this.line.numPositions++;
                // Place the new vertex at the position of the previous
                this.line.SetPosition(vertexPos, temp);

                // Increase the index and check if we reached the end of the vertex list
                // If end of vertex list, then we use the first one to close
                if (++index == this.vertices.Count)
                {
                    index = 0;
                }
                // Set new target
                target = this.vertices[index];
            }
            yield return null;
        }
    }
}