LineRender에서 만든 다이어그램 애니메이션
14876 단어 Unity
LineRenderer
는 Positions
이 배열에서 여러 점을 지정하면 최초의 것부터 순서대로 선을 연결하여 표시하는 구성 요소입니다.한편,
Vector3.Lerp
은 두 점 사이에 선형 삽입값을 하는 함수이다.https://docs.unity3d.com/ja/current/ScriptReference/Vector3.Lerp.html
Line Render에서 그래프를 애니메이션으로 만들려면 고려해야 할 점이 2시라면 Lerp로 포지션을 만지작거리면 애니메이션이 되지만 3시 이상이면 그 구성 요소를 직접 만드는 것이 좋기 때문에 만들기로 했습니다.
결국 이런 느낌이었어.
여러 점 기반 Lerp
여러 점을 뛰어넘을 수 있는 Lerp 같은 것을 실현합니다.먼저 모든 점 간의 거리 목록을 작성하여 0.0~1.0의 값을 바탕으로 점이 어느 선분에 속하는지 구한 다음에 이 선분에 Lerp를 설치합니다.
바로 코드 전문입니다.
LineRendererProgressor.cs
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
[ExecuteInEditMode]
[RequireComponent(typeof(LineRenderer))]
public class LineRendererProgressor : MonoBehaviour
{
private LineRenderer LineRenderer
{
get
{
if (lineRenderer) return lineRenderer;
return lineRenderer = GetComponent<LineRenderer>();
}
}
private LineRenderer lineRenderer;
[SerializeField] private Vector3[] positions;
public float Progress
{
get => progress;
set {
progress = value;
if (positions == null || positions.Length == 0) return;
UpdateLineRenderer();
}
}
[SerializeField] private float progress;
private void OnValidate()
{
if (positions == null || positions.Length == 0) return;
UpdateLineRenderer();
}
private void UpdateLineRenderer()
{
// 値の制限と終了判定
progress = Mathf.Clamp01(progress);
if (positions.Length == 1 || progress <= 0.0f)
{
LineRenderer.positionCount = 1;
LineRenderer.SetPosition(0, positions[0]);
return;
}
if (progress >= 1.0f)
{
LineRenderer.positionCount = positions.Length;
LineRenderer.SetPositions(positions);
return;
}
// 距離リストと合計
var distanceList = MakeDistanceList(positions);
var totalDistance = distanceList.Sum();
// 現在どの線分にあるか取得
var distanceCompleted = totalDistance * progress;
var currentIndex = GetIndexByDistanceCompleted(positions,
distanceList, distanceCompleted);
// 先端位置を計算
var distanceArrayToCurIdx = distanceList.Take(currentIndex);
var completedDistInCurSeg = distanceCompleted - distanceArrayToCurIdx.Sum();
var currentSegLength = distanceList[currentIndex];
var t = completedDistInCurSeg / currentSegLength;
var edgePos = Vector3.Lerp(positions[currentIndex], positions[currentIndex + 1], t);
// 更新
LineRenderer.positionCount = currentIndex + 2;
for (var i = 0; i < currentIndex + 2; ++i)
{
LineRenderer.SetPosition(i, i > currentIndex ? edgePos : positions[i]);
}
}
private IReadOnlyList<float> MakeDistanceList(Vector3[] points)
{
var distanceList = new List<float>();
for (var i = 0; i < points.Length - 1; ++i)
{
distanceList.Add(Vector3.Distance(points[i], points[i + 1]));
}
return distanceList;
}
private int GetIndexByDistanceCompleted(Vector3[] points, IReadOnlyList<float> distanceList, float distanceCompleted)
{
var distanceProcessed = 0f;
for (var i = 0; i < points.Length - 1; ++i)
{
if (distanceList[i] + distanceProcessed > distanceCompleted)
{
return i;
}
distanceProcessed += distanceList[i];
}
return points.Length - 1;
}
}
기본적으로 평론 중의 일만 하면 간단하다.수학 능력이 있으면 더 영리한 설치가 있을 수 있지만 제가 없어서 포기했는데...세그먼트의 길이가 자주 사용되기 때문에 목록에 저장합니다.
또한 첨단 위치의 계산을 준비했던 Lerp에서 그곳만 되돌아오는 Multi Lerp 같은 함수를 정의하면 다른 클래스도 사용할 수 있다.그러나 이런 상황에서 Multi Lerp에서 진행된 것과 같은 계산은 다시 Update Line Render에서 해야 한다는 것이 미묘할 수 있기 때문에 이번에는 모두 Update Line Render에 넣었다.
Reference
이 문제에 관하여(LineRender에서 만든 다이어그램 애니메이션), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/Gok/items/c07bd10484f8654c3c68텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)