3D 공간에 아이콘을 표시하고 상호작용을 처리하는 기능을 제공합니다. 특정 객체와의 충돌 시 아이콘을 표시하고 클릭 이벤트를 통해 추가적인 동작을 트리거할 수 있습니다.
주요 기능
- 아이콘 표시: 특정 Collider와 충돌할 때 아이콘을 표시하고, 충돌이 종료되면 아이콘을 숨깁니다.
- 이벤트 시스템: 유니티의 UnityEvent를 사용하여 아이콘 클릭 및 충돌 이벤트를 처리합니다.
- 아이콘 회전: 아이콘은 항상 카메라를 바라보도록 회전하여 사용자에게 시각적으로 잘 보이도록 합니다.
사용 방법
- 프리팹 연결: iconCanvasPrefab 필드에 아이콘으로 사용할 Canvas 프리팹을 연결합니다.
- 위치 설정: iconPosition 필드에 아이콘이 표시될 위치의 Transform을 연결합니다.
- 물리 설정: 이 스크립트를 사용하는 객체에 BoxCollider와 Rigidbody 컴포넌트를 추가합니다. Rigidbody는 중력을 사용하지 않도록 설정되어 있습니다.
- 이벤트 핸들러: 에디터에서 onClickEvent, onTriggerEnterEvent, onTriggerExitEvent 이벤트에 대한 핸들러를 설정하여 아이콘 클릭 및 충돌 이벤트에 대한 추가 동작을 정의할 수 있습니다.
코드
using UnityEngine;
using UnityEngine.Events;
[RequireComponent(typeof(BoxCollider))]
[RequireComponent(typeof(Rigidbody))]
public class IconController : MonoBehaviour
{
[Header("Icon Settings")]
[SerializeField] private GameObject iconCanvasPrefab;
[SerializeField] private Transform iconPosition;
[Header("Events")]
public UnityEvent onClickEvent;
public UnityEvent onTriggerEnterEvent;
public UnityEvent onTriggerExitEvent;
private Camera _mainCamera;
private Canvas _iconCanvas;
private bool _isIconVisible;
private void Start()
{
if (TryGetComponent(out BoxCollider boxCollider))
{
boxCollider.isTrigger = true;
}
if (TryGetComponent(out Rigidbody rb))
{
rb.useGravity = false;
}
_mainCamera = Camera.main;
}
private void Update()
{
if (!_isIconVisible) return;
UpdateIconRotation();
}
private void OnDrawGizmos()
{
if (TryGetComponent(out BoxCollider boxCollider))
{
Gizmos.color = Color.red;
Gizmos.DrawWireCube(transform.position + boxCollider.center, boxCollider.size);
}
}
private void OnTriggerEnter(Collider other)
{
// if (other != _playerCollider) return;// 다른 사람이 들어갔을 경우에 대한 처리 필요.
ShowIcon();
onTriggerEnterEvent?.Invoke();
}
private void OnTriggerExit(Collider other)
{
// if (other != _playerCollider) return;// 다른 사람이 들어갔을 경우에 대한 처리 필요.
HideIcon();
onTriggerExitEvent?.Invoke();
}
public void OnClickIcon()
{
onClickEvent?.Invoke();
}
public void ShowIcon()
{
if (_iconCanvas == null) CreateIcon();
_iconCanvas.enabled = true;
_isIconVisible = true;
}
public void HideIcon()
{
if (_iconCanvas == null) return;
_iconCanvas.enabled = false;
_isIconVisible = false;
}
private void CreateIcon()
{
if (iconCanvasPrefab == null) return;
if (iconPosition == null) return;
GameObject canvasObj = Instantiate(iconCanvasPrefab, iconPosition);
if (canvasObj.TryGetComponent(out Canvas canvas))
{
_iconCanvas = canvas;
_iconCanvas.transform.position = iconPosition.position;
_iconCanvas.worldCamera = _mainCamera;
}
}
private void UpdateIconRotation()
{
_iconCanvas.transform.LookAt(_mainCamera.transform);
_iconCanvas.transform.Rotate(0f, 180f, 0f);
}
}