[Unity, C#] 제일 가까운 아이템 줍기
유니티에서 아이템 줍기 기능을 구현하려면,
1) 플레이어가 아이템을 인식할 조건을 추가하고
2) 해당 조건을 만족할 때 아이템을 줍는 기능을 구현하면 된다.
- 플레이어의 자식으로 빈
GameObject
를 추가한다. - 추가한
GameObject
의 컴포넌트로Circle Collider
(콜라이더)를 추가해준다. 해당 Collider의Is Trigger
를 체크해준다. - 추가한
GameObject
의 컴포넌트로 스크립트를 추가해준다. (OnTriggerEnter
)
💡
Trigger?GameObject
끼리 충돌이 발생한 경우, 인식은 하되 물리적으로 부딪치지는 않게 하고 싶을 때 설정한다.
일반적으로 플레이어가 Trigger
가 아닌 경우, Trigger
가 아닌 GameObject
와의 충돌은 플레이어가 벽에 부딪히는 경우, Trigger
인 GameObject
와의 충돌은 코인과 접촉했을 때 코인이 획득되는 경우를 생각하면 된다.
💡
OnTriggerEnter 사용 시 주의OnTriggerEnter
는 기본적으로 두 GameObject
가 충돌할 때 호출된다. 그러나 충돌하는 두 GameObject
가 모두 Collider
를 포함해야 하며, 적어도 하나의 GameObject
는 isTrigger = true
여야 한다.
플레이어의 자식으로 ItemScope
라는 GameObject
를 추가해주었고, 스크립트는 다음과 같다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ItemScope : MonoBehaviour
{
List<Item> ItemsInScope;
private void Awake()
{
ItemsInScope = new List<Item>();
}
private void Update()
{
// 인식 범위 내에 아이템이 없을 경우
if (ItemsInScope.Count == 0)
{
Player.Instance.LetterF.SetActive(false);
}
// 인식 범위 내에 아이템이 하나라도 있을 경우
else
{
Player.Instance.LetterF.SetActive(true);
// F키를 누르면
if (Input.GetKeyDown(KeyCode.F))
{
// 가장 가까운 아이템을 찾아 그 아이템을 획득한다.
Vector3 playerPos = Player.Instance.transform.position;
Item nearestItem = ItemsInScope[0];
for (int i=0; i<ItemsInScope.Count; ++i)
{
if (Vector3.Distance(playerPos, nearestItem.transform.position) >
Vector3.Distance(playerPos, ItemsInScope[i].transform.position))
{
nearestItem = ItemsInScope[i];
}
}
nearestItem.PickUp();
}
}
}
private void OnTriggerEnter2D(Collider2D collision)
{
Item item = collision.GetComponent<Item>();
if (item != null)
ItemsInScope.Add(item);
}
private void OnTriggerExit2D(Collider2D collision)
{
Item item = collision.GetComponent<Item>();
if (item != null)
ItemsInScope.Remove(item);
}
}
ItemScope
내에 아이템이 하나라도 있을 시 플레이어 위에 F키 이미지(LetterF
)가 표시된다. 또한 ItemScope
내에 아이템이 하나 이상 있을 때 F키를 누르면 가장 가까운 아이템이 획득되도록 구현해보았다.
ItemScope
내의 모든 아이템을 획득하도록 짜고 싶다면 nearestItem
을 찾지 않고 ItemsInScope
의 모든 아이템에서 PickUp
함수를 실행하면 된다.