Unity

Line Renderer를 활용한 움직이는 플랫폼 구현

우대비 2025. 3. 6. 16:20
반응형

LineRenderer를 이용한 Moving Platform 구현 방법

 

1. 사용되는 맴버 변수

[SerializeField] private float speed; // 플랫폼의 이동 속도를 조절하는 변수입니다.

private Vector3[] positions; // LineRenderer의 정점 정보를 저장하는 배열입니다.
private LineRenderer lineRenderer; // LineRenderer 컴포넌트를 참조하는 변수입니다.

private bool isLoop = false; // LineRenderer가 루프 모드인지 여부를 나타내는 변수입니다.
private bool isForward = true; // 플랫폼이 현재 정점 배열의 순방향으로 이동 중인지 여부를 나타내는 변수입니다.

private int curIdx = 0; // 현재 정점의 인덱스를 나타내는 변수입니다.
private int nextIdx = 1; // 다음 정점의 인덱스를 나타내는 변수입니다.

private Vector3 prevPosition; // 플랫폼 위에 있는 오브젝트를 옮기기 위해 사용하는 위치 값입니다.

 

 

2. 초기화

private void Awake()
{
    lineRenderer = GetComponentInParent<LineRenderer>();
    positions = new Vector3[lineRenderer.positionCount];
    lineRenderer.GetPositions(positions);
    transform.position = prevPosition = positions[0];
    isLoop = lineRenderer.loop;
}

LineRenderer에서 정점 정보를 받아오고, Loop 정보를 받아옵니다.

초기 위치로 이동하고, prevPosition에 위치 값을 넣어줍니다.

 

3. Update

private void Update()
{
    MovePlatform();
    MoveObjectOnPlatform();
}

매 프레임 MovePlatform 함수를 호출하여 이동 로직을 수행합니다.

이후 MoveObjectOnPlatform 함수를 통해 플랫폼 위에 있는 오브젝트도 같이 옮겨줍니다.

 

 

4. Move

private void MovePlatform()
{
    Vector3 dir = (positions[nextIdx] - positions[curIdx]).normalized;
    float goalDist = Vector3.Distance(positions[nextIdx], positions[curIdx]);

    transform.position += dir * Time.deltaTime * speed;
    float curDist = Vector3.Distance(transform.position, positions[curIdx]);
}

다음 정점까지의 방향을 계산 후, 해당 방향으로 이동합니다.

이때, 거리를 실시간으로 계산하여, 목표 지점에 도달했는지 체크합니다.

 

if (goalDist <= curDist)
{
    curIdx = nextIdx;

목표 지점 이상으로 멀리 왔다면, 다음 정점으로의 이동이 끝났다는 의미이기 때문에, 다음 정점을 찾아서 업데이트 해야합니다.

 

if (isLoop)
{
    nextIdx = (nextIdx + 1) % positions.Length;
}

루프 되는 경우 +1을 해주고, 끝 지점에 다다른 경우에는 나머지 연산을 통해 다시 0으로 이동하면 됩니다.

 

else
{
    nextIdx = isForward ? nextIdx + 1 : nextIdx - 1;

그렇지 않은 경우에는 다시 뒤로 돌아가야 하기에 isForward라는 bool 변수를 활용합니다.

isForward가 true인 경우에는 +1 false인 경우에는 -1을 해줍니다.

 

if (nextIdx == positions.Length || nextIdx < 0)
{
    isForward = !isForward;
    nextIdx = Mathf.Clamp(nextIdx, 1, positions.Length - 2);
}

현재 위치가 positions 배열의 끝 지점에 위치한다면 isForward를 뒤집어주고 Clamp를 통해 다음 위치로 보정해줍니다.

 

 

5. MoveObjectOnPlatform

private void MoveObjectOnPlatform()
{
    Vector3 dir = transform.position - prevPosition;
    foreach (var target in targets)
        target.transform.position += dir; 

    prevPosition = transform.position;
}

이전 좌표와 현재 좌표를 비교하여 해당 방향만큼 모든 오브젝트에게 적용시킵니다.

이후, prevPosition에 현재 위치값을 넣어줍니다.

 

🎮 결과물

플랫폼 Loop 이동

플랫폼 왕복 이동

 

 

플레이어 캐리

 

반응형
LIST