플레이어가 현재 있는 위치에 해당하는 스크린이 켜지는 기능을 구현하고 싶다.
한 점이 부채꼴 위에 있는지 어떻게 파악해야 할까?
부채꼴의 시작과 끝 선을 a, b라고 할 때 점 A(x,y) 가 주어진다고 가정하자.

x축에서 a 와 b, A 사이의 거리를 각각 θa, θb, θA 라고 할 때
θa < θA < θb
위 조건을 만족하면 점 A 가 부채꼴 안에 있다고 할 수 있다.
점 A 를 지나는 반지름을 그은 후 직각삼각형을 만들어보면 삼각함수를 사용할 수 있다.


따라서 θA = arctan(y/x) 가 된다.
코드로 작성해보면 아래와 같다 (여기선 x, z 좌표를 가지고 각도를 구함)
각도를 항상 양수로 만들어주는 코드를 추가하였다.
private float CalcAngleWithX(Vector3 pos)
{
float thetaX = Mathf.Atan2(pos.z, pos.x) * 180 / Mathf.PI;
if (thetaX < 0)
{
return thetaX + 360;
}
return thetaX;
}
스크린 A, B, C 의 교점을 이용해 세 교점이 x축과 이루는 각도를 알아낸 후 플레이어 위치와 비교하면 플레이어가 어느 스크린을 보고 있는지 알 수 있다!
(예시코드라 성능은 생각하지 않고 일단 작동하는지에 중점을 두었다.)
public class PlayerManaer : MonoBehaviour
{
[SerializeField] Camera mainCamera;
[Space()]
[SerializeField] Transform center; // 중심
[SerializeField] Transform meet1; // 교점 1
[SerializeField] Transform meet2; // 교점 2
[SerializeField] Transform meet3; // 교점 3
[Space()]
[SerializeField] GameObject canvas1;
[SerializeField] GameObject canvas2;
[SerializeField] GameObject canvas3;
private void Update()
{
SetScreenArea();
}
private void SetScreenArea()
{
float thetaMeet1 = CalcAngleWithX(meet1.position);
float thetaMeet2 = CalcAngleWithX(meet2.position);
float thetaMeet3 = CalcAngleWithX(meet3.position);
float thetaPlayer = CalcAngleWithX(mainCamera.transform.position);
if (thetaMeet2 < thetaPlayer && thetaPlayer < thetaMeet1)
SetMainScreen(canvas1);
if (thetaMeet3 < thetaPlayer && thetaPlayer < thetaMeet2)
SetMainScreen(canvas3);
if (thetaPlayer > thetaMeet1 || thetaPlayer < thetaMeet3)
SetMainScreen(canvas2);
}
private float CalcAngleWithX(Vector3 pos)
{
float thetaX = Mathf.Atan2(pos.z, pos.x) * 180 / Mathf.PI;
if (thetaX < 0)
{
return thetaX + 360;
}
return thetaX;
}
private void SetMainScreen(GameObject canvas)
{
canvas1.SetActive(false);
canvas2.SetActive(false);
canvas3.SetActive(false);
canvas.SetActive(true);
}
}