본문 바로가기

Unity

Unity(유니티) 정리: 04. 좌우이동 무한반복, Time.deltaTime, Time.time, Mathf.Sin()

슈퍼마리오같은 횡스크롤 게임에 자주 등장하는 지형이 있습니다.

공중에 떠있고 좌우로 무한 반복해서 왔다 갔다 하기때문에

타이밍을 잘 맞추어 올라타야하는 지형입니다.


기본설정

--------------

2D 프로젝트작성

1.GameObject >> 2D Object >> Sprite 추가

2.Google이미지 검색으로 "minecraft stone" 키워드의 아이콘 사이즈 이미지 하나를 다운로드

3.1에서 추가한 Sprite에 2의 다운로드 이미지를 설정

4.Hierarchy에서 Sprite를 드래그해서 Assets안으로 드롭 (Prefabs의 작성) 이름을 "Stone"으로 변경

5.Hierarchy에서 Sprite삭제, Assets안의 "Stone"을 Scene으로 드래그 드롭

6.C# script를 "StoneMove" 작성 "Stone"에 추가

-------------- 


구현1

--------------

float rightMax = 2.0f; //좌로 이동가능한 (x)최대값

float leftMax = -2.0f; //우로 이동가능한 (x)최대값

float currentPosition; //현재 위치(x) 저장

float direction = 3.0f; //이동속도+방향


void Start()

{

    currentPosition = transform.position.x;

}


void Update()

{

    currentPosition += Time.deltaTime * direction;

    if (currentPosition >= rightMax)

    {

        direction *= -1;

        currentPosition = rightMax;

    }

    //현재 위치(x)가 우로 이동가능한 (x)최대값보다 크거나 같다면

    //이동속도+방향에 -1을 곱해 반전을 해주고 현재위치를 우로 이동가능한 (x)최대값으로 설정

    else if (currentPosition <= leftMax)

    {

        direction *= -1;

        currentPosition = leftMax;

    }

    //현재 위치(x)가 좌로 이동가능한 (x)최대값보다 크거나 같다면

    //이동속도+방향에 -1을 곱해 반전을 해주고 현재위치를 좌로 이동가능한 (x)최대값으로 설정

    transform.position = new Vector3(currentPosition, 0, 0);

    //"Stone"의 위치를 계산된 현재위치로 처리

}

--------------

Time.deltaTime 은 이전 프레임이 완료되는데 소요된 시간입니다.

1프레임에 1씩 이동을 하게 하면 작동환경에 따라 실제 느끼는 이동속도가 달라집니다.

1초에 1프레임 ( Time.deltaTime=1)인 환경도 있고

1초에 10프레임 ( Time.deltaTime=0.1)인 환경도 있게 됩니다.

그런 경우 Time.deltaTime을 이용하면 시간당 처리하는 값을 동일하게 할 수 있습니다.


구현1로도 훌륭하다고 생각합니다...만..

같은 속도로 움직이니 뭔가 좀 딱딱하네요.

남들은 어떻게 하나 좀 검색을 해보았습니다.



구현2

--------------

Vector3 pos; //현재위치

float delta = 2.0f; // 좌(우)로 이동가능한 (x)최대값

float speed = 3.0f; // 이동속도


void Start () {

    pos = transform.position;

}

void Update () {

    Vector3 v = pos;

    v.x += delta * Mathf.Sin(Time.time * speed);

    // 좌우 이동의 최대치 및 반전 처리를 이렇게 한줄에 멋있게 하네요.

    transform.position = v;

}

--------------

중간에선 빠르고 양 끝에서는 느려지는 가속도 처리까지 되어 부드럽습니다.


delta * Mathf.Sin(Time.time * speed);

를 100% 이해하지는 못하고 있습니다(수학이...)...

Mathf.Sin() 를 찾아보니 f(라디안의 각도) 를 입력받아 -1과 1사이의 float값을 반환하는 함수입니다.

Time.time 은 게임개시후 각 프레임이 시작한 시간 입니다.


Time.time은 계속 증가하는 수이고.. 이것이 라디안식 계산된 각도로 Sin값이 계산되어

연속된 증가,감소의 반복이 발생되는 것으로 어림...이해를 해습니다.

-1과 1사이의 float값이니 delta값에 곱해도 -delta와 +delta사이의 수만 나오게 됩니다.

https://docs.unity3d.com/2017.3/Documentation/ScriptReference/Mathf.Sin.html

반응형