상세 컨텐츠

본문 제목

유니티 오브젝트 상하좌우로 왔다갔다 하기

유니티/기능

by MJ_119 2024. 8. 27. 14:18

본문

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

public class Oscillator : MonoBehaviour
{
    Vector3 startPosition;

    // 오브젝트를 놓을 위치를 지정
    [SerializeField] Vector3 movementVector;
    [SerializeField] [Range(0,1)] float movementFactor;
    [SerializeField] float period = 2f;

    void Start()
    {
        // 오브젝트의 시작 위치
        startPosition = transform.position;
    }

    void Update()
    {
        float cycles = Time.time / period;

        const float tau = Mathf.PI * 2;
        float rawSinWave = Mathf.Sin(cycles * tau);

        movementFactor = (rawSinWave + 1f) / 2f;

        // movementFactor값에따라 오브젝트를 놓을 위치 저장
        Vector3 offset = movementVector * movementFactor;

        // 오브젝트 이동
        transform.position = startPosition + offset;
    }
}

 

 - 사인 값을 활용해서 좌우, 상하로 오브젝트를 왔다 갔다 하기

 - period의 값을 높이면 천천히 움직이고 줄이면 빠르게 움직임

 

 

@ period가 0이 되면 에러가 나와서 에러를 방지하려고 코드를 추가함.

 

void Update()
    {
        // 에러 방지
        if ( period == 0 ) return;
        if ( period <= Mathf.Epsilon ) return;


        float cycles = Time.time / period;

        const float tau = Mathf.PI * 2;
        float rawSinWave = Mathf.Sin(cycles * tau);

        movementFactor = (rawSinWave + 1f) / 2f;

        // movementFactor값에따라 오브젝트를 놓을 위치 저장
        Vector3 offset = movementVector * movementFactor;

        // 오브젝트 이동
        transform.position = startPosition + offset;
    }

1. if (period == 0) return;

  • 설명: 이 조건문은 period가 정확히 0일 때 코드를 실행하지 않고 리턴(return)하는 역할을 합니다.
  • 비교 연산: == 연산자는 두 값이 정확히 동일한지를 비교합니다. period가 0일 때만 조건이 참(true)입니다.

2. if (period <= Mathf.Epsilon) return;

  • 설명: 이 조건문은 period가 Mathf.Epsilon 이하일 때 코드를 실행하지 않고 리턴하는 역할을 합니다.
  • Mathf.Epsilon: Mathf.Epsilon은 매우 작은 양의 값으로, 부동소수점 수의 연산에서 발생할 수 있는 미세한 오차를 다루기 위해 사용됩니다. 유니티에서 Mathf.Epsilon은 약 1.4013e-45로 정의되어 있습니다.
  • 비교 연산: <= 연산자는 period가 Mathf.Epsilon보다 작거나 같을 때 조건을 참으로 평가합니다.

3. 차이점

  • 정확성:
    • == 0은 정확하게 0인 값을 찾습니다. 그러나 부동소수점(floating-point) 연산에서는 0이라고 기대한 값이 매우 작은 수(예: 0.000000001)로 나타날 수 있습니다. 이 경우 == 0 조건은 참이 되지 않습니다.
    • <= Mathf.Epsilon은 0뿐만 아니라 부동소수점 연산에서 발생할 수 있는 작은 값들을 포함합니다. 즉, period가 0에 매우 가까운 값이더라도 조건이 참이 됩니다.
  • 안정성:
    • 부동소수점 비교에서는 직접 ==를 사용하는 것보다, Mathf.Epsilon과 같은 작은 값을 사용하는 것이 안정적입니다. 이는 부동소수점 연산의 불확실성(예: 매우 작은 값들이 0이 아닐 가능성) 때문에 발생하는 문제를 방지할 수 있습니다.

4. 어떤 코드가 더 좋은가?

  • 일반적으로 if (period <= Mathf.Epsilon) return;이 더 좋은 코드입니다.

이 코드가 더 좋은 이유는 다음과 같습니다:

  • 부동소수점 오차 처리: 부동소수점 연산에서는 연산 오차로 인해 0이 아닌 매우 작은 값이 나올 수 있습니다. 이 경우 <= Mathf.Epsilon 조건은 이러한 작은 오차를 포괄하여 보다 안전하게 동작합니다.
  • 유연성: 이 조건은 0뿐만 아니라 0에 매우 가까운 값들도 처리하므로, 코드가 더 유연하게 작동할 수 있습니다.

관련글 더보기