ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 이벤트 함수 Update(), FixedUpdate()
    카테고리 없음

    안녕하세요.

     

    이번 카테고리에는 평소 사용하던

     

    Update()FixedUpdate() 함수에 대해 다뤄 보려고 합니다.


    Unity엔진 에는 많은 이벤트 함수들이 있죠.

     

    (Awak(), Start(), Update(), FixedUpdate(), LateUpdate() 등등..)

     

    그중에서도 Update()  FixedUpdate() 의 알고 있던 차이점과

     

    더불어 몰랐던 부분까지 함께 살펴 보겠습니다.

     


    먼저! 

     

    프레임(Frame)이라는 것 부터 살펴 보겠습니다.

     

    Fram이란 

     

    1초에 화면이 몇 번 다시 그려질 수 있는지를 나타내는 단위 라고 합니다.

     

     

     

    유니티 엔진은 프레임 단위로 처리가 이루어지고 매 프레임마다 작업을 수행 할 수 있는데요

     

    이러한 단위 표시를 FPS 를 사용 합니다.

    (Frame Per Second)

     

    30 Frame = 1초에 화면이 30번

    60 Frame = 1초에 화면이 60번

     

    Frame은 디스플레이 장치, 컴퓨터의 성능 등에 영향을 받기에

     

    고사양 일 수록 프레임이 높아 지며

     

    1초에 30번 그려지는 것 보다, 1초에 60번 그려지는게

     

    좀 더 부드럽게 보여지는것 입니다.

     

    요약 : 프레임 수가 높을 수록 화면이 부드럽게 보인다.

     


    여기서 Update()FixedUpdate()를 살펴 보자면, 

     

    Update()는 매 프레임 마다 주기적으로 계속 실행을 한다.

    (1) 프레임 속도는 환경마다 다르기에 물리 처리를 Update()에서 실행 하면 오차가 발생 할 수 있다.

     

    FixedUpdate()는 고정된 값으로 동일한 시간에 실행이 된다.

    (1) 디폴트 값으로 0.02f를 가지며, Unity 엔진 내부에서 고정 값을 변경 할 수 있다.

    (unity -> projects settings -> time -> fiexed Timestep)

    (2) 프레임과 상관 없이 고정된 값으로 실행이 되기에, 물리 처리를 오차 없이 실행 시킬 수 있다.


    여기 까지가 알 고 있던 내용 이였습니다.

     

    물리 연산을 제외하고는 크게 신경을 쓰지 않았던 부분 인데,

     

    좀 더 알아본 결과

     

    TimeScale에 의존 여부를 알 수 있었는데요

     

    Update()는 Time.timeScale = 0 이 될 때에도 실행이 되지만,

    FixedUpdate()는 Time.timeScale = 0 이 될 때 실행이 안된다는 사실..

    (알고 계셨나요..?)

     

    Why???

     

    그래서 직접 실행을 해보았습니다.

     

    간단히 TestTimeScale 이라는 스크립트를 만들고

     

    start() 함수 에서 Time.timeScale = 0; 을 실행 시켜 둔 뒤

     

    Update()와 FixedUpdate()에서 Debug.Log로 출력을 해 보았습니다.

     

    - 결과 -

     

     

    여기서 의문점이 2가지 들었습니다.

     

    1. 왜 FixedUpdate()에서만 TimeScale의 영향을 받는가..?

    2. FixedUpdate()가 왜 1회 실행 하였는가..??

    (유니티 생명주기(LifeCycle)를 보면 FixedUpdate() 함수가 Start() 함수 보다 늦게 실행이 되는데..?)

     


    1번 문제는 간략하게 얘기 하자면

     

    Time.timeScaleUpdate 에서는 영향을 안받고

    FixedUpdate 에서만 영향을 받는다고 합니다.

     

    매 프레임 마다 호출되는 Update는 호출 간격이 일정하지 않기에, Time.timeScale의 영향을 받지 않는다고 하며,

    고정된 시간 마다 계속 호출되는 FixedUpdateTime.timeScale의 영향을 받는다고 하는데...

     

    아직 궁금증이 확 풀리진 않았지만,

     

    이와 같은 사실을 모르고.. time.timeScale = 0 일시 변경되면 안되는 로직을 Update에서 구현을 했다면...

     

    큰 낭패를 볼 수도 있었을것 같습니다..

     


    2번 문제 같은 경우는

     

    Time.timeScale이 0으로 설정 됐음에도 실행이 됐다면, 유니티 버전 또는 스크립트와 프로젝트 문제로

     

    자세히 검토하고 디버그를 해야 할 문제이지만

     

    여기서의 원인은 간단히

     

    이미 실행 대기 중이던 'FixedUpdate'가 실행이 된 것 입니다.

     

    로직 구현을 FixedUpdate에서 했을 경우, 물리적 상태나 조건이 만족 되었고 이미 실행 대기중인 경우 입니다.

     


    요약 하자면 UpdateTimeScale에 영향을 안받고

    FixedUpdate는 영향을 받으며

     

    일시 정지를 해도 배경음악은 보통 나오게 구현이 되어있는 경우를 생각하면

     

    이해가 빨리 될 것.. 이라고 하는데요.

     

    *일시 정지를 시켜도 프레임은 진행이 된다는 것으로 알면 된다고 합니다.

     


    추가 적으로 Time.timeScale = 0일 경우에도 Update 함수 자체는 실행이 되지만

     

    이 안에서 deltaTime을 사용하여 움직임을 제어한게 있다면 멈춘다고 합니다.

     

     

    간단히 Translate를 사용해 이동을 시켜 보았습니다.

     

    함수 자체는 실행이 되지만, 큐브의 움직임은 멈춘 모습.

     

    부족함도 많고 알아야 할 부분들이 너무나도 많지만, 그렇기에 알아가는 재미가 있는것 같습니다.

     

    +_+

     

    감사합니다.

     

    댓글

김효겸 / Tel. 010-7735-0580 / E-mail. dollzzang2@hanmail.net