1vdlrwnsv1 님의 블로그
유니티 개발 숙련주차4. 아이템 상호작용 본문
아이템 상호작용 구현
인터페이스 정의
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public interface IInteractable
{
public string GetInteractPromp();
public void OnInteract();
}
public class ItemObject : MonoBehaviour , IInteractable
{
public ItemData data;
public string GetInteractPromp()
{
string str = $"{data.displayName}\n{data.description}";
return str;
}
public void OnInteract()
{
CharacterManager.instance.player.itemData = data;
CharacterManager.instance.player.addItem?.Invoke();
Destroy(gameObject);
}
}
- IInteractable 인터페이스는 상호작용 가능한 오브젝트들이 공통적으로 가져야 할 메서드를 정의한다.
- GetInteractPromp(): 플레이어가 오브젝트를 바라볼 때 출력할 프롬프트(설명) 문자열을 반환.
- OnInteract(): 플레이어가 상호작용할 때 실행되는 로직.
- IInteractable을 구현하여 ItemObject가 상호작용 가능하도록 설정.
- GetInteractPromp(): 아이템의 이름과 설명을 반환하여 UI에 표시.
- OnInteract(): 플레이어가 아이템과 상호작용하면,
- CharacterManager.instance.player.itemData에 아이템 데이터 저장.
- addItem 이벤트 호출.
- Destroy(gameObject);를 통해 아이템을 게임 내에서 삭제.
ItemData (아이템 데이터) 정의
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum ItemType
{
Equipable,
Cusmable,
Resource
}
public enum ConsumableType
{
Health,
Hunger
}
public class ItemDataConsumable
{
public ConsumableType type;
public float value;
}
[CreateAssetMenu(fileName = "Item", menuName = "New Item")]
public class ItemData : ScriptableObject
{
[Header("Info")]
public string displayName;
public string description;
public ItemType type;
public Sprite icon;
public GameObject dropPrefab;
[Header("Stacking")]
public bool canStack;
public int maxStackAmount;
[Header("Cunsumable")]
public ItemDataConsumable[] consumables;
}
- ScriptableObject를 이용해 아이템 정보를 저장하는 데이터 클래스.
- displayName: 아이템 이름.
- description: 아이템 설명.
- type: 아이템 유형(장비, 소비, 자원).
- icon: UI에서 사용할 아이콘.
- dropPrefab: 아이템을 드롭할 때 사용할 프리팹.
- canStack: 아이템 중첩 가능 여부.
- maxStackAmount: 최대 중첩 개수.
- consumables: 소비형 아이템일 경우 효과 값 저장.
Interaction 상호작용
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
public class Interaction : MonoBehaviour
{
public float checkRate = 0.05f;
private float lastCheckTime ;
public float maxCheckDistance;
public LayerMask layerMask;
public GameObject curInteractGameObject;
private IInteractable curInteractable;
public TextMeshProUGUI promptText;
private Camera camera;
// Start is called before the first frame update
void Start()
{
camera = Camera.main;
}
// Update is called once per frame
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);
promptText.text = curInteractable.GetInteractPromp();
}
public void OnInteractInput(InputAction.CallbackContext context)
{
if(context.phase == InputActionPhase.Started && curInteractable != null)
{
curInteractable.OnInteract();
curInteractGameObject = null;
curInteractable = null;
promptText.gameObject.SetActive(false);
}
}
}
- 플레이어의 시야 중앙에서 레이를 쏴서 상호작용 가능한 오브젝트를 감지.
- curInteractGameObject가 변경될 때 SetPromptText() 호출하여 프롬프트 UI 표시.
- OnInteractInput(): 플레이어가 상호작용 키를 누르면 OnInteract() 호출.
5. Player 클래스에서 아이템 추가 이벤트 설정
public class Player : MonoBehaviour
{
public PlayerController controller;
public PlayerCondition condition;
public ItemData itemData;
public Action addItem;
private void Awake()
{
CharacterManager.instance.player = this;
controller = GetComponent<PlayerController>();
condition = GetComponent<PlayerCondition>();
}
}
- itemData: 현재 플레이어가 얻은 아이템 저장.
- CharacterManager.instance.player = this;를 통해 싱글톤 방식으로 플레이어 참조 설정.
- https://1vdlrwnsv1.tistory.com/15(플레이어 만드는 법)
상호작용 과정 정리
- 플레이어의 Interaction 스크립트가 Raycast를 통해 상호작용 가능한 오브젝트 감지.
- 감지된 오브젝트가 IInteractable을 구현하고 있으면 SetPromptText() 실행.
- 플레이어가 상호작용 키를 누르면 OnInteractInput()이 실행되어 OnInteract() 호출.
- 아이템(ItemObject)의 OnInteract()가 실행되어 플레이어가 아이템을 얻음.
- 아이템 정보(ItemData)가 Player 클래스에 저장되고, addItem 이벤트가 호출됨.
- 아이템을 습득한 후 Destroy(gameObject);를 실행하여 씬에서 아이템 제거.
이번 학습내용은 상당히 어려워서 이해하는데 시간이 꽤 걸림 사실 아직도 이해안됨 혼자 개발하긴 조금 무리가 있다
'Unity숙련주차' 카테고리의 다른 글
Unity, 밸브사의 Portal 게임을 클론 해보자잇 (0) | 2025.03.18 |
---|---|
유니티 개발 숙련주차 3. 조명기능 만져서 낮과 밤 구현 (0) | 2025.03.05 |
유니티 개발 숙련 2. 플레이어에게 데미지 주기 (0) | 2025.03.05 |
유니티 게임개발 숙련 1. 플레이어 만들기 (0) | 2025.03.04 |