winAPI 41 Camera(2)

CJB_ny·2022년 9월 19일
0

WinAPI

목록 보기
40/79
post-thumbnail

오늘 배운거 👍👍👍

  • 렌더링 좌표 오류 수정 : 음수값 좌표 수정.

  • 렌더링 좌표, 실제 좌표 변환 및 구분 (개념)

  • 미세한 오차에 의한 흔들림 현상 (유니티 LateUpdate 구현) 카메라 흔들림.


플레이어나 (몬스터의 경우) 그런 경우 부모의 render함수 사용하지 않고

자체적인 render함수를 호출하여 화면에 자기 자신을 그리고있다.

(virtual 로 상속을 했으니까)

이렇게 오브젝트의 '실제위치'를 얻어와서 사용하고있는데

'렌더링용 위치'를 알아야한다.

이렇게 바꿔주고 그대로 코드 사용하면 된다.

오류 수정 ❗

현재 CameraManager에서 _diff - objPos뺄 경우 에러가 나서 애니매이션이 안 보였는데

애니매이션의 위치값이 음수여서 그랬었다.

이렇게 -1 곱해주면은 일단 되기는 하는데 절대값을 씌워야겠다.

구현해야 할 부분

현재 몬스터 texture도 플레이어와 동일한 텍스쳐로 변경했다.

카메라 잘 움직이는데

collider가 따라오지를 않는다.

Colldier에서 renderPos를 GetRenderPos에 _finalPos를 넣어서 얻어온다.

이 _finalPos는 변경되면 안된다.

카메라 다양한 효과

Fade, 움직이기 등등

LookAt 변경될 때 부드럽게 움직이게 한다던가 등등..

Smooth Flollow

이거 두개 급격하게 차이가 벌어지면은 천천히 쫒아 갈 수 있게 구현하도록 하자.

일단 StartScene에서 마우스 왼쪽버튼 클릭발생한다면은 카메라가 클릭한 방향을 쫒아가도록 일단 구현해보도록 하자.

KeyManager의 update안에서 윈도우함수 GetcursorPos를 사용해서 얻어오도록 하자.

근데 getcursorPos 윈도우 전체 기준 함수이다.

전체 윈도우 좌표기준이다.

저 동그라미 친 부분을 빼주어야한다.

이것을 계산해주는 함수가 ScreenToClient라는 윈도우 함수이다.

이렇게 구현을 해주도록 하고 이거 메크로로 만들어 주도록 하자.

그래서 이렇게 매크로 사용을 하는데 이대로하면은 우리가 생각한대로 동작을 안한다.

이유

현재 카메라가 찍고있는 부분이 저 부분일 때

저 사각형안에있는 장면들이 실제 우리 윈도우에 나올 것이다.

지금 좌상단 네모 안에서 1시방향을 봤으면 좋겠다라고 해서 그 부분을 눌렀다고 가정을 하자.

내가 누른 부분 (빨강색)은 카메라가 찍고있는 파란색 부분(파란 점 부분을 중심으로)을 찍기를 원한 것이다.

그렇게 눌렀을 때 '누른 지점(빨강점)'을 보게되서 그 장면이 빨강점이있는 윈도우 화면에 나오게 되니까

내가보고 있는 지점(빨강점 윈도우)이 카메라가 보고있는 지점(파란점 윈도우)이 될 것이다.

그러니까,

정리 ❗❗❗

내가 보고있는 장면(빨강점 윈도우)에서 카메라가

" 빨강점을 봤으면 좋겠다 ". 하고 생각하고 누른 행위는

'렌더링 좌표' 기준으로 생각을 한 것이다.

지금 당연하게도 현재 내 윈도우(빨강점 네모)는 렌더링 좌표를 기준으로 내 눈에 보여지고있는 것이다.

실제 좌표가 아니라!

그런데, 카메라고 보고자하는 LookAt은 '실제 좌표'로 셋팅해주어야한다.

빨간점이 내가 봐달라고한 좌표인데 카메라가 이동을 해서 빨간점을 기준으로 보여준다는 것은

빨간점 (카메라가찍고있는 부분)과 나의 윈도우 화면상의 차이값을 계산을 해서

렌더링 좌표를 빼주어서 내 윈도우 화면이 보이게 하는 것이다.

개념이 반대인 것이다.

그동안은 '실제좌표'인 오브젝트들이 카메라가 보고있는 곳을 기준으로 변형했을 때의
좌표를 얻어서 출력을 했다면은

거꾸로 내가얻은 마우스 좌표는 내가 보고있는 화면 좌표(렌더링 좌표)를 눌러서 '실제 좌표'를 얻어내서 그것을 카메라의 LookAt으로 잡아주어야한다.

그래서 CameraManager는 실제죄표, 렌더링 좌표 둘다 알아야한다.

실제 좌표구하기 ❗❗❗ (이해 안가니 함 더보기)

렌더링 좌표에서 _diff만큼 더해준다. 이게 실제 좌표가 될 것이다.

그래서 MOUSE_POS는 현재 '렌더링 좌표'인데 실제 좌표를 구해야한다.

그래서 이렇게 얻은 마우스좌표가 바로 내가 셋팅하고 싶은 lookAtPos이 되는 것이다.
(렌더링 좌표를 -> 실제 좌표로 변환한 좌표)

잘 동작한다.

근데 이렇게 한방에 이동하는게 아니라 서서히 이동하고 싶은 것이다.

_lookAtPos, _corLookPos (보정 위치), _prevLookPos 이렇게 세개로 나누어서 위치를 관리를 하도록 하고

_diff의 차이값이 _lookPos - centerPos에서 _corLookPos로 바뀌었다.

어떻게 보정할 것이냐?

그러면 이제 _lookAtPos랑 _prevLookPos를 어떻게 계산을 해서 보정을 할 것인가?

이렇게 현재보고 있는 위치 - 이전에 보고있던 위치 벡터로 뺀다음에 정규화해서 그 방향으로 500의 속도로 deltaTime만큼 곱해서 간다.

이거를 조금 바꿔서

_corLookPos 보정 위치에다가 += 연산해서 이전위치에다가

_lookDir 500.f DeltaTime_F 만큼의 양을 더해주도록 하자.

그래서 보정위치 (현재위치)는 다시

밑줄 부분처럼 보정값이 끝나고 나면은 이전 위치로 되돌아간다.

도착하고 나서 흔들흔들 ❗

막 흔들흔들 거린다.

이래서 유니티에서는 카메라가 오브젝트 따라갈 때 LateUpdate를 통해 따라가게 해주었었는데

한프레임의 물체의 이동이 다 끝나고 나서 LateUpdate를 통해 해당 좌표를 따라가게 했었다.

흔들흔들 하는 이유는

내가 봐야할 곳을 '초과'해서 그런것이다.

이곳을 향해서 가야하는데 dt만큼 더하고 나니까

조금 더 앞으로 가버렸다. 다으번에는 방향 거꾸로 가버리기 때문에 왔다리 갔다리 하는 것이다.

현재 _corLookPos를 500이라는 일정속도 만큼 dt의 시간동안 더해서 가는 방식이라면은

절대 오차 보정할 수 없다.

오차를 얼만큼으로 정할 건데? dt는 때에따라 다른 값이 나오는데..

그래서 이런 개념을 적용할 때에는 시간 개념을 적용해야한다.

500.f이라는 속도로 간다라고 하기 보다는 몇초에 걸쳐서 간다고하는 게 좋다.

그래서 이전위치 prevLookAtPos와 현재위치 lookAtPos의 차이가 생겼으면은

5초에 걸쳐서 이동을 한다던지 1초에 걸쳐서 이동을 한다던지 해야할 것이다.

제한시간을 정해놓고 비율에 맞춰서 쭉 쫒아가는게 좋은 방법이였을 것이다.

10초가 넘어버리면 이런 연산자체를 하지 않을 것이다.

미세한 오차때문에 해야되나?

profile
https://cjbworld.tistory.com/ <- 이사중

0개의 댓글