Study] Portal System
- 김영호
- 2022년 5월 25일
- 1분 분량
최종 수정일: 2023년 4월 27일
CameraManager.cs_SyncCamToPlayer()
pubic void SyncCamToPlayer()
{
//Calculate the relative position of the player and portal
Vector3 offset = cam_player.position - currentPortal.position;
//Sync position
cam_Target.position = targetPortal.position + offset;
//Sync rotation
float angularDifferenceBetweenPortalRotations
= Quaternion.Angle(targetSpace.rotation, currentSpace.rotation);
Quaternion portalRotationalDiffernce
= Quaternion.AngleAxis(angularDiffernceBetweenPortalRotations,
Vector3.up);
Vector3 newCameraDirection = portalRotationalDiffernce *
cam_player.forward;
cam_Target.rotation = Quaternion.LookRotation(newCameraDirection,
Vector3.up);
}
SyncCamToPlayer는 포탈 문의 이미지를 실시간으로 받아올 카메라의 위치를 Player와 동기화 시켜주는 함수이다.
offset은 플레이어와 플레이어가 속한 공간의 포탈의 위치의 차이 이고, 움직여야하는 카메라의 position은 해당 카메라가 속한 포탈의 position + offset으로 하여 위치를 동기화 시켜준다.
이 후에 Quaternion의 함수 Angle(Quaternion간의 사이각)로 현재와 대상의 공간의 각도차이를 구한 뒤, Vector3.up(Y축)을 기준으로 각도 차이만큼 돌린 Quaternion을 구한다.
새로 구한 Quaternion에 플레이어의 카메라의 forward를 곱해서 대상 카메라가 바라봐야할 Vector를 구하고 Quaternion.LookRotation으로 대상 카메라를 회전시킨다.
PortalSystem.cs_Telleport()
void Telleport()
{
if(!isOverlap) return;
if(palyer == nul) return;
Vector3 toPlayer = player.position - transform.position;
float dot = Vector3.Dot(transform.up, toPlayer);
if(dot < 0f)
{
//Rotate player
float rotationDiff = -Quaternion.Angle(transform.rotation,
linkedPortal.rotation);
rotationDiff += 180f; //전후 반전
player.Rotate(Vector3.up, rotationDiff);
//Transport other portal
Vector3 positionOffset = Quaternion.Euler(0f, rotationDiff, 0f)
* toPlayer;
player.position = linkedPortal.position + positionOffset;
//Reset (Complete the Telleport)
isoverlap = false;
player = null;
//양측 포탈에 카메라가 존재함, 그 두개의 카메라의 Enable상태를 변경
CameraManager. Instance().SwapingSpace();
}
}
OnTrigger로 tag == "Player"를 찾아 isOverlap을 true로 바꾼 뒤 텔레포트를 준비한다.
Player가 Portal의 Collider에 접촉해 있는 동안에 Portal과 Player 사이의 Vector를 구하고 Portal의 Y축 Vector와의 내적을 구해 해당 값이 음수가 되면 Player를 서로 연결되어있는 Portal들 간의 회전차를 구하고 Player를 회전차만큼 회전을 시켜주며 위치를 이동시켜준다.
해당 게시글에서는 포탈끼리 등을 맞댄상태(-180f으로 전후반전을 해줬던 이유)로만 제대로 작동했다.
이를 좀 더 자유롭게(상대적으로) 사용하기 위해 다음 게시물에서 수정해보겠다.