프로그래밍 공부
작성일
2023. 11. 24. 15:01
작성자
WDmil
728x90

3인칭 카메라를 구현해보자.

 

Obejct의 Front와 Back, 그리고 Cam의 Rotationvalue와 Movevalue값을 알고 있어야 한다.

 

간단한 코드 예시를 살펴보자.

	float distance = 20.0f;
	float height = 20.0f;
	float moveDamping = 5.0f; // 따라가는 속도
	float rotDamping = 0.0f; // 회전에서 따라가는 속도
	float rotY = 0;			// 쿼터뷰로 하였을 때, 45도각도를 바라보고 싶을 수도있기 때문,

	float destRot = 0.0f;
	Vector3 destPos;

	Vector3 focusOffset;	// 카메라의 타겟 오프셋

	// 특정 타겟을 바라보는데 X축 앵글로만 안바라보게 하고싶을 수 있다.
	// 모델 유지 카메라만 이동하게
	bool isLookAtTargetX = true;
	bool isLookAtTargetY = true;

	// 회전행렬 저장
	Matrix rotMatrix;

 

카메라에 들어가야 하는 데이터들이다.

 

우선, distance와 height는 현재 카메라가 위치해야할 Obejct와 Cam간의 거리,

 

Height는 Cam의 높이값이다.

 

mveDamping은 따라가는 속도,

 

rotDamping은 회전속도.

 

rotY는, Cam의 각도를 지정한다. 보통 안쓴다.

 

destRot과 destPos는 현재 Pos와 Rot의 갱신과정을 기록한다.

 

focusOffset은, 카메라가 바라보는 위치이다.

 

isLoockAtTargetX는 카메라의 X축이동을 허가하느냐 마느냐,

Y는 Y축의 이동을 허가하느냐 마느냐이다.

 

Rot에 관여한다.


void Camera::FollowMode()
{
	// 대상 회전을 부드럽게 따라가기 위해 보간 (Lerp)을 사용합니다.
	destRot = MATH->Lerp(destRot, target->GetLocalRotation().y, rotDamping * DELTA);

	// 회전 행렬을 계산하고 보간된 회전을 적용합니다.
	rotMatrix = XMMatrixRotationY(destRot + rotY);

	// 세계 공간에서의 전방 벡터를 계산합니다.
	Vector3 forward = XMVector3TransformNormal(Vector3::Forward(), rotMatrix);

	// 목표 위치를 지정된 거리와 높이로 대상 뒤에 설정합니다.
	destPos = target->GetGlobalPosition() - forward * distance;
	destPos.y += height;

	// 부드럽게 카메라를 대상 위치로 이동시킵니다.
	localPosition = MATH->Lerp(localPosition, destPos, moveDamping * DELTA);

	// 최종 대상 위치를 얻기 위해 포커스 오프셋을 적용합니다.
	Vector3 offset = XMVector3TransformCoord(focusOffset, rotMatrix);
	Vector3 targetPos = target->GetGlobalPosition() + offset;

	// 카메라에서 대상까지의 방향을 계산하고 정규화합니다.
	Vector3 dir = (targetPos - localPosition).GetNormalized();

	// 수직 회전을 무시하고 XZ 평면으로 방향을 투영합니다.
	forward = Vector3(dir.x, 0.0f, dir.z).GetNormalized();

	// 활성화된 경우, 카메라가 X축을 따라 대상을 보도록 로컬 회전을 업데이트합니다.
	if (isLookAtTargetX)
		localRotation.x = acos(Vector3::Dot(forward, dir));

	// 활성화된 경우, 카메라가 Y축을 따라 대상을 보도록 로컬 회전을 업데이트합니다.
	if (isLookAtTargetY)
		localRotation.y = atan2(dir.x, dir.z);
}

카메라가 FollowMode일경우, 지정된 Obejct를 따라가게 할 경우, 동작하는 Cam 내부의 함수이다.

 

대상회전을 부드럽게 따라가기위해 현재 rotDamping과 DETLTA로 선형보간을 작업한다.

 

rotDamping은 따라가는 속도에 선형보간을 작업함으로, 부드럽게 회전하게 된다.

 

해당 target과 Cam간의 거리가 벌어지면 빠르게, 좁혀지면 천천히 회전하게 된다.

 

현재 Obejct에서 전방Vector가 어디인지 확인한다.

 

현재 목표위치는, Cam의 앞에서 distance만큼 이동한 거리가, target의 Position방향으로 이동했을 때의 위치이다.

 

destPos.y 에 높이값을 추가하여. 높이보정을 해준다.

 

Cam의 localPosition은 현재 위치에서 찾은 destPos까지 움직임속도에 DELTA값을 곱한만큼 보간하여 움직인다.

 

ROtation은 목표의 회정네 따라 로컬 회전을 적용하도록 isLookAtTargetX와 isLookAtTargetY를 참조하여,

 

x값에 forward와 dir의 각도에 acos하여 파이각도로 적용한다.

 

y또한 같다.

 

시연 예시

 

728x90