티스토리 뷰

비행기 도그파이팅 게임을 만들다보면 적 위치에 맞춰서 표적 마크를 보여줘야 한다. 안 그러면 잘 안 보이니까....


표적 마크가 적의 위치에 따라서 바뀌는걸 여러가지 방법으로 구현할 수 있다. 적 오브젝트의 자식으로 추가해두는 것이 한 가지 방법. 그러나 3D 객체가 자유자재로 움직이는 상황에서 그대로 2D UI가 유지되도록 하는 것은 귀찮기도 하고 또 효율도 별로라서 다른 방법을 생각했다.


필요한건 플레이어의 카메라와 적의 게임오브젝트, UI 정보. 이것들이 있으면 UI가 그려져야 할 위치를 계산할 수 있다. 나는 UI를 그리기 위해 NGUI를 사용하기로 했다. Camera의 WorldToViewport 행렬을 이용해서 Viewport 상에서의 위치를 계산하고 이것을 NGUI의 좌표계로 변환하는 것이다. 생각보다 쉽게 구현된다. 적이 내 뒤에 있을 경우에는 이미지가 보이지 않아야 하므로 UISprite를 z 값에 따라서 끄고 켜주도록 했다.


아래는 그 코드이다.


using UnityEngine;
using System.Collections;

public class EnemyMark : MonoBehaviour {

    public Camera PlayerCamera;
    public GameObject Enemy;

    UIRoot UIRoot;
    UISprite SpriteMark;


    void Start () {
        UIRoot = GameObject.Find ("UI Root").GetComponent<UIRoot> ();
        SpriteMark = this.GetComponent<UISprite> ();
    }
    
    void Update () {
        float ratio = (float)UIRoot.activeHeight / Screen.height;
        float uiWidth = Mathf.Ceil (Screen.width * ratio);
        float uiHeight = Mathf.Ceil (Screen.height * ratio);

        Vector3 worldPos = Enemy.transform.position;
        Vector3 viewportPos = PlayerCamera.WorldToViewportPoint (worldPos);
        SpriteMark.enabled = viewportPos.z >= 0;

        Vector3 uiPos = new Vector3 ();
        uiPos.x = (viewportPos.x - 0.5f) * uiWidth;
        uiPos.y = (viewportPos.y - 0.5f) * uiHeight;
        uiPos.z = 0;

        this.transform.localPosition = uiPos;
    }
}


댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday