프로젝트 중에 만든 인터렉션 매니저
public interface IInteractable
{
string GetInteractPrompt();
void OnInteract();
}
public class InteractionManager : MonoBehaviour
{
[SerializeField] private float checkRate = 0.05f;
private float lastCheckTime;
[SerializeField] private float maxCheckDistance;
[SerializeField] private LayerMask layerMask;
private GameObject curInteractGameobject;
private IInteractable curInteractable;
[SerializeField] private TextMeshProUGUI promptText;
private Camera camera;
private void Start()
{
camera = Camera.main;
}
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);
}
}
}
private void SetPromptText()
{
promptText.gameObject.SetActive(true);
// 키보드 K를 누르면 열쇠 획득 가능
promptText.text = string.Format("<b>[K]</b> {0}", curInteractable.GetInteractPrompt());
}
public void OnInteractInput(InputAction.CallbackContext callbackContext)
{
if (callbackContext.phase == InputActionPhase.Started && curInteractable != null)
{
curInteractable.OnInteract();
curInteractGameobject = null;
curInteractable = null;
promptText.gameObject.SetActive(false);
}
}
}
다른 분이 작성한 코드를 분석하는 시간을 가졌다.
RayCast를 스크린의 정 가운데로 두었고
curInteractGameObject
를 저장해 두고 새로운 오브젝트에 닿으면 갈아치우는 형식이었다.
모르던 부분은 GetComponent<인터페이스> 부분이다.
코드를 읽고 내가 이해한 것은 Ray에 닿은 오브젝트는 인터페이스가 있어야 되겠다는 생각이었다.
인터페이스가 없는 오브젝트가 들어간다면 어떻게 될지 궁금해졌다.
InputAction.CallbackContext
는 강의에서 보았지만, 좀 더 알아보는 시간을 가져야 겠다.