[Unity] 적 미사일방향으로 화면에 느낌표 띄우기

jh Seo·2024년 3월 31일
0

유니티

목록 보기
41/50

적 투사체가 화면 바깥에서 돌진하고 있을 때,
플레이어에게 알려주기 위해서 느낌표를 해당 방향에 띄우려고 시도했다.

우선 떠오른 방법은 플레이어 위치와 카메라 너비 계산하기 였다.

코드로 구현 중 예전에 배웠던 camera의 viewport가 떠올랐다.
viewport내부에 해당 투사체 오브젝트가 있는지 체크할 수 있는지 찾아봤다.

Transforms position from world space into viewport space.
Viewport space is normalized and relative to the camera. The bottom-left of the camera is (0,0); the top-right is (1,1). The z position is in world units from the camera.

유니티 api인

public Vector3 WorldToViewportPoint(Vector3 position)

를 사용하면 world포지션을 viewport 공간으로 변환할 수 있다고 한다.
viewport는 왼쪽 밑이 (0,0) 좌표이고, 오른쪽 위가 (1,1) 좌표이다.

따라서 worldtoviewportpoint함수가 0~1이 아닌 값을 뱉어내면 화면 바깥에 있는 것이다.

    public GameObject missile;
    public GameObject exclamationMark;
    void Update()
    {
        Vector3 missilePosition = Camera.main.WorldToViewportPoint(missile.transform.position);
        if (missilePosition.x < 0 || missilePosition.x > 1 || missilePosition.y < 0 || missilePosition.y > 1)
        {
            ShowExclamationMark(missilePosition);
        }
    }

이런식으로 missilePosition을 체크해준 후, 이제 해당 방향에 느낌표를 위치하도록 하면 된다.

주의할점은 viewport는 0부터 1 사이 값만 가진다는 것이다.
mathf.clamp() 함수를 사용해 0.1에서 0.9의 값만 가지도록 느낌표의 위치를 지정해줬다.

 void ShowExclamationMark(Vector3 offScreenPosition)
{
	Vector3 screenPosition = new Vector3(Mathf.Clamp(offScreenPosition.x, 0.1f, 0.9f), Mathf.Clamp(offScreenPosition.y, 0.1f, 0.9f), offScreenPosition.z);
    exclamationMark.transform.position = Camera.main.ViewportToWorldPoint(screenPosition);
}

위치를 지정해준 후, 현재 0~1사이 값을 가진 좌표는 viewport 공간 한정이다.
따라서 ViewportToWorldPoint함수를 사용해 world공간으로 바꿔줘야 한다.

코드

public class AlertPlayer : MonoBehaviour
{
    public GameObject missile;
    public GameObject exclamationMark;
    void Update()
    {
        Vector3 missilePosition = Camera.main.WorldToViewportPoint(missile.transform.position);
        if (missilePosition.x < 0 || missilePosition.x > 1 || missilePosition.y < 0 || missilePosition.y > 1)
        {
            ShowExclamationMark(missilePosition);
        }
    }

    void ShowExclamationMark(Vector3 offScreenPosition)
    {
        Vector3 screenPosition = new Vector3(Mathf.Clamp(offScreenPosition.x, 0.1f, 0.9f), Mathf.Clamp(offScreenPosition.y, 0.1f, 0.9f), offScreenPosition.z);
        exclamationMark.transform.position = Camera.main.ViewportToWorldPoint(screenPosition);
    }
}
profile
코딩 창고!

0개의 댓글