20241024 / Unity_6차 7주차 목요일
오늘은 Interface를 활용하여 상호작용 가능한 오브젝트 - 아이템을 만들어 보았다.
다음은 IInteractable 인터페이스를 ItemObject가 상속받아 구현한 코드다.
public interface IInteractable
{
public string GetInteractPrompt();
public void OnInteract();
}
public class ItemObject : MonoBehaviour, IInteractable
{
public ItemData data;
public string GetInteractPrompt()
{
string str = $"{data.displayName}\n{data.description}";
return str;
}
public void OnInteract()
{
CharacterManager.Instance.Player.itemData = data;
CharacterManager.Instance.Player.addItem?.Invoke();
Destroy(gameObject);
}
}
Interface도 여타 클래스 상속과 같이 Unity에서 GetComponent 메서드로 불러올 수 있다.
public GameObject curInteractGameObject;
private IInteractable curInteractable;
private void Update()
{
if (Time.time - lastCheckTime > checkRate)
{
lastCheckTime = Time.time;
Ray ray = camera.ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2));
RaycastHit hit;
if (Physics.Raycast(ray, out hit, maxCheckDistance, layerMask))
{
if (hit.collider.gameObject != curInteractGameObject)
{
curInteractGameObject = hit.collider.gameObject;
curInteractable = hit.collider.GetComponent<IInteractable>();
SetPromptText();
}
}
else
{
curInteractGameObject = null;
curInteractable = null;
promptText.gameObject.SetActive(false);
}
}
}
위 코드는 플레이어가 바라보는 방향에 IInteractable 객체가 있는 지 확인하여 멤버에 저장하는 부분이다.
당연이 저렇게 불러온 IInteractable 객체는 IInteractable의 메서드를 사용할 수 있다.
private void SetPromptText()
{
promptText.gameObject.SetActive(true);
promptText.text = curInteractable.GetInteractPrompt();
}
public void OnInteractInput(InputAction.CallbackContext context)
{
if (context.phase == InputActionPhase.Started && curInteractable != null)
{
curInteractable.OnInteract();
curInteractGameObject = null;
curInteractable = null;
promptText.gameObject.SetActive(false);
}
}
지금은 IInteractable을 상속받은 클래스가 ItemObject 하나뿐이지만 상자나 문서 같은 것들도 상속받아서
플레이어가 E키를 눌러 OnInteract 메서드를 호출하면 상자는 열리고, 문서는 읽을 수 있게 만들 수 있다.