Skip to content
Home » 유니티 인벤토리 드래그 | [유니티 3D 강좌] Fps 서바이벌 디펜스 Part 16 : 인벤토리 드래그\U0026드롭 24769 좋은 평가 이 답변

유니티 인벤토리 드래그 | [유니티 3D 강좌] Fps 서바이벌 디펜스 Part 16 : 인벤토리 드래그\U0026드롭 24769 좋은 평가 이 답변

당신은 주제를 찾고 있습니까 “유니티 인벤토리 드래그 – [유니티 3D 강좌] FPS 서바이벌 디펜스 Part 16 : 인벤토리 드래그\u0026드롭“? 다음 카테고리의 웹사이트 kk.taphoamini.com 에서 귀하의 모든 질문에 답변해 드립니다: kk.taphoamini.com/wiki. 바로 아래에서 답을 찾을 수 있습니다. 작성자 케이디 이(가) 작성한 기사에는 조회수 7,288회 및 좋아요 66개 개의 좋아요가 있습니다.

유니티 인벤토리 드래그 주제에 대한 동영상 보기

여기에서 이 주제에 대한 비디오를 시청하십시오. 주의 깊게 살펴보고 읽고 있는 내용에 대한 피드백을 제공하세요!

d여기에서 [유니티 3D 강좌] FPS 서바이벌 디펜스 Part 16 : 인벤토리 드래그\u0026드롭 – 유니티 인벤토리 드래그 주제에 대한 세부정보를 참조하세요

인벤토리 슬롯을 드래그하면 아이템 슬롯이 이동되거나 교체되고,
우클릭을 하면 아이템을 먹거나, 장착해보자.

====================================
본 강좌가 도움이 되셨다면,
♥ 구독 (Subscribe)
♥ 좋아요 (like)
Part16 소스 파일
http://keidy.tistory.com/attachment/[email protected]
(3D 오브젝트 및 UI, 이미지는 자작이미지고, 효과음은 freesound.org의 프리소재입니다)
Asset 다운로드 링크 :
https://drive.google.com/open?id=1L1yRhgZDrULdKrqh3_KgIiNHQZ6-Xn0e

====================================
▶ 후원 : https://www.patreon.com/keidy
▶ 티스토리 : http://keidy.tistory.com/
▶ 구름IDU – https://edu.goorm.io/lecture/3991/유니티-2d-rpg-게임-제작하기
▶ 인프런 : https://www.inflearn.com/
====================================

► 본 강좌는 무료입니다.
– 모든 후원은 더 나은 양질의 컨텐츠를 계속 제작할 수 있는
가장 큰 원동력이 됩니다.

유니티 인벤토리 드래그 주제에 대한 자세한 내용은 여기를 참조하세요.

Chapter 5-3. 인벤토리 : 인벤토리 드래그 앤 드롭, UnityEngine …

인프런에 있는 케이디님의 [유니티 3D] 실전! 생존게임 만들기 – Advanced 강의를 듣고 정리한 필기입니다. 강의 들으러 가기 Click.

+ 여기에 표시

Source: ansohxxn.github.io

Date Published: 8/20/2021

View: 587

[Unity3D] 인벤토리 [Part 3] – Item Drag & Swap – 참된코딩

3). 드래그가 끝났을 때. – 슬롯에 아이템이 존재하지 않으면 함수를 종료한다. – 싱글톤을 이용해 인벤토리 내에 있는 Swap함수 …

+ 여기를 클릭

Source: truecode.tistory.com

Date Published: 8/16/2021

View: 761

[Unity]EventSystem을 이용해 아이템UI 드래그 및 다른 슬롯에 …

여러 방법이 있지만 이게 가장 간단한 방법 같아서 정리한다. 아이템 사용 이런거는 없고 단수. 드래그, 드랍할 UI오브젝트에 Drag관련 인터페이스가 …

+ 여기에 보기

Source: penguinofdev.tistory.com

Date Published: 4/30/2022

View: 1456

Unity Drag and Drop from Inventory – unity3d – Stack Overflow

I am currently trying to implement an interface in unity 3d with an inventory including 2D icons which I want to drag and drop from the …

+ 자세한 내용은 여기를 클릭하십시오

Source: stackoverflow.com

Date Published: 7/9/2022

View: 5865

주제와 관련된 이미지 유니티 인벤토리 드래그

주제와 관련된 더 많은 사진을 참조하십시오 [유니티 3D 강좌] FPS 서바이벌 디펜스 Part 16 : 인벤토리 드래그\u0026드롭. 댓글에서 더 많은 관련 이미지를 보거나 필요한 경우 더 많은 관련 기사를 볼 수 있습니다.

[유니티 3D 강좌] FPS 서바이벌 디펜스 Part 16 : 인벤토리 드래그\u0026드롭
[유니티 3D 강좌] FPS 서바이벌 디펜스 Part 16 : 인벤토리 드래그\u0026드롭

주제에 대한 기사 평가 유니티 인벤토리 드래그

  • Author: 케이디
  • Views: 조회수 7,288회
  • Likes: 좋아요 66개
  • Date Published: 2018. 10. 9.
  • Video Url link: https://www.youtube.com/watch?v=qkRZ8kaChuQ

Chapter 5-3. 인벤토리 : 인벤토리 드래그 앤 드롭, UnityEngine.EventSystems

인프런에 있는 케이디님의 [유니티 3D] 실전! 생존게임 만들기 – Advanced 강의를 듣고 정리한 필기입니다. 😀

🌜 강의 들으러 가기 Click

Chapter 5. 인벤토리

🚖 인벤토리에서 우클하면 장착 및 소비

슬롯에 있는 아이템 우클 무기라면 해당 무기로 장착 그냥 아이템이라면 소비

마우스 클릭 이벤트

using UnityEngine.EventSystems ; public class Slot : MonoBehaviour , IPointerClickHandler { // 오버라이딩 하기 }

IPointerClickHandler 인터페이스 이 인터페이스를 상속 받은 스크립트라면 마우스 클릭 이벤트를 받을 수 있다. 마우스 클릭 될 때 발생하는 이벤트 함수를 오버라이딩 해야 한다. OnPointerClick (PointerEventData eventData) 이 스크립트가 붙은 오브젝트에 마우스 클릭 이벤트 발생시 호출

인터페이스 인터페이스 이름 – 우클 – 빠른 작업 및 리팩터링 오버라이딩 해야 할 함수들의 자동으로 써주어서 편하다.

EventSystem 이벤트에 대한 Raycast는 Canvas의 Graphic Raycaster 컴포넌트에서 쏴주고 어떤 종류의 이벤트인지에 대한 답을 Raycast 로 쏴주는건 EventSystem 오브젝트이다. 이 이벤트에 대한 Raycast를 받기 위해선 UI들은 Raycast Target 가 체크 되어 있어야 하며 일반 오브젝트들은 Collider 가 붙어 있어야 한다.

📜Slot.cs

using System.Collections ; using System.Collections.Generic ; using UnityEngine ; using UnityEngine.UI ; using UnityEngine.EventSystems ; public class Slot : MonoBehaviour , IPointerClickHandler , IBeginDragHandler , IDragHandler , IEndDragHandler , IDropHandler { // … private WeaponManager theWeaponManager ; void Start () { theWeaponManager = FindObjectOfType < WeaponManager >(); } // … public void OnPointerClick ( PointerEventData eventData ) { if ( eventData . button == PointerEventData . InputButton . Right ) { if ( item != null ) { if ( item . itemType == Item . ItemType . Equipment ) { // 장착 StartCoroutine ( theWeaponManager . ChangeWeaponCoroutine ( item . weaponType , item . itemName )); } else { // 소비 Debug . Log ( item . itemName + ” 을 사용했습니다.” ); SetSlotCount (- 1 ); } } } } }

theWeaponManager 을 [SerializeField]를 사용하여 직접 할당하지 않고 FindObjectOfType 로 할당 해준 이유 게임 도중 Instantiate 될 예정인 🟦프리팹들은 [SerializeField] 인 것들은 자기 자신 안에 있는 객체(프리팹)들만 참조 가능하기 때문에 어차피 게임이 시작되면 None이 되버려서 그렇다. 이 스크립트 📜Slot.cs가 붙는 대상은 🟦프리팹인 Slot 들이다. 게임 시작전에 배치 되는 오브젝트가 아니라 인벤토리를 활성화 해야만 생성되는 애들이기 때문에 게임 시작 전에 [SerializeField]인 멤버에 다른 타 오브젝트를 할당하면 어차피 게임 시작 되더라도 찾을 수 없다고 None이 되어버린다. 아직 에셋으로만 존재하고 오브젝트화 되지 않은 프리팹에선 Hierarchy에 있는 오브젝트들을 serializefiled 슬롯에 넣을 수 없다. (넣을 순 있긴 하지만 게임 시작되면 None이 되어버린다.) Hierarchy에 있는 것들을 serializefield에 넣어 봤자 소용 없다. 프리팹이니까. 물론 이미 Hierarchy에 꺼내놓은 프리팹 즉 이미 오브젝트화 되있는건 상관 X Instantiate으로 생성할 경우의 얘기

을 [SerializeField]를 사용하여 직접 할당하지 않고 FindObjectOfType 로 할당 해준 이유 따라서 위와 같이 게임이 시작되면 theWeaponManager 을 FindObjectOfType 로 찾아 📜WeaponManager.cs 를 가진 오브젝트를 할당해주는 것이다.

게임 시작부터 오브젝트로 존재하는 프리팹이라면 👉 외부 오브젝트를 [SerializeField] 로 프리팹 오브젝트에 드래그 앤 드롭 할당 가능.

Instantiate 으로 게임 도중에 생성하는 프리팹이라면 [SerializeField] 로 선언된 변수에 직접 외부 오브젝트를 드래그 앤 드롭 해주는게 의미가 없다. 게임 시작하자마자 None이 되버림. 이런 경우엔 FindObjectOfType 밖에 답이 없음.

📜Slot.cs 가 붙어 있는 오브젝트에 ( Slot 에) 마우스 클릭 이벤트가 발생하면 OnPointerClick 이벤트 함수가 자동 실행된다.

PointerEventData 마우스 혹은 터치 입력 이벤트에 관한 정보들이 담겨 있다. 이벤트가 들어온 버튼, 클릭 수, 마우스 위치, 현재 마우스 움직이고 있는지 여부 등등 여러가지를 담고 있다

해당 슬롯에 마우스 우클릭 이벤트가 들어 오면 if ( eventData . button == PointerEventData . InputButton . Right ) 해당 아이템이 무기라면 👉 장착한다. 📜WeaponManager.cs 의 ChangeWeaponCoroutine 함수 실행 해당 아이템이 무기가 아니라면 👉 소비한다. 해당 슬롯의 아이템 갯수 1 감소 시키기 SetSlotCount(-1) 알아서 이 함수 안에서 슬롯의 아이템 개수가 0 개 이하면 해당 슬롯을 클리어 시키는 ClearSlot() 함수도 호출 한다.

🚖 인벤토리 드래그

인벤토리의 슬롯에 있는 아이템을 드래그 앤 드롭 하면 슬롯에 든 아이템의 위치를 다른 슬롯으로 바꿀 수 있게 한다. 이미 다른 아이템이 있는 위치에 드래그 앤 드롭 하면 두 아이템 위치를 맞바꾼다.

DragSlot

슬롯을 드래그 할 때 고려해야 할 점

위 사진과 같이 드래그 하려는 슬롯이 다른 슬롯들 보다 뒤에 가려진다. 보기 안좋음! 이유 👉 UI 요소들의 렌더링 순서는 Hierarchy 상에서 위에 있는 UI 부터 렌더링 되어서 그렇다. 첫번째 슬롯은 Hierarchy 상에서 슬롯들 중 가장 위에 있기 때문에 가장 먼저 그려진다. 따라서 위와 같이 첫 번째 슬롯을 드래그 하면, 제일 먼저 그려지기 때문에 다른 슬롯들 보다 뒤에서 그려지는 것이다. 드래그 한 슬롯의 원래 자리는 비워진다. 보기 안좋음! 드래그 한 슬롯은 다른 공간에 복사될 필요가 있다.

원래 슬롯도 그대로 그려지고 사본 슬롯이 드래그 되도록.

위와 같이 1️⃣ 뒤에 가려지지도 않고 2️⃣ 원래 자리가 비워지지 않도록 하려면 1️⃣ 다른 슬롯들보다 먼저 그려져야 한다. Hierarchy 상에서 위에 위치 하도록 해야 한다. 2️⃣ 드래그 된 슬롯은 사본으로 만들어야 한다.

DragSlot 이라는 이름의 이미지 UI 를 Inventory_Base 자식으로 추가한다. 1️⃣ Grid Setting 보다 아래에 위치하도록 한다. 다른 슬롯들 보다 나중에 그려져 뒤에 묻히지 않도록 2️⃣ 드래그 된 슬롯은 이 DragSlot 에서 사본으로서 참조 되도록 한다.

이라는 이름의 이미지 UI 를 자식으로 추가한다. 이 또한 다른 Slot 의 Item_Image 들과 마찬가지로 투명도 0 값을 기본으로 해둔다. 드래그 할 때만 보여야 하는 이미지 이므로 (슬롯의 사본으로서)

의 들과 마찬가지로 투명도 0 값을 기본으로 해둔다. 사이즈를 슬롯과 동일하게 해 준다.

마우스 드래그 이벤트

using UnityEngine ; using UnityEngine.EventSystems ; public class Test : MonoBehaviour , IBeginDragHandler , IDragHandler , IEndDragHandler { public void OnBeginDrag ( PointerEventData eventData ) { // 오버라이딩 하기 } public void OnDrag ( PointerEventData eventData ) { // 오버라이딩 하기 } public void OnEndDrag ( PointerEventData eventData ) { // 오버라이딩 하기 } }

IBeginDragHandler 인터페이스 OnBeginDrag (PointerEventData eventData) 이 스크립트가 붙은 오브젝트를 마우스 드래그를 시작 했을 때 호출

인터페이스 IDragHandler 인터페이스 OnDrag (PointerEventData eventData) 이 스크립트가 붙은 오브젝트를 마우스 드래그 중인 동안 계속 호출

인터페이스 IEndDragHandler 인터페이스 OnEndDrag (PointerEventData eventData) 이 스크립트가 붙은 오브젝트를 마우스 드래그 하는 것을 끝냈을 때 호출

인터페이스

📜DragSlot.cs

using System.Collections ; using System.Collections.Generic ; using UnityEngine ; using UnityEngine.UI ; public class DragSlot : MonoBehaviour { static public DragSlot instance ; public Slot dragSlot ; [ SerializeField ] private Image imageItem ; void Start () { instance = this ; } public void DragSetImage ( Image _itemImage ) { imageItem . sprite = _itemImage . sprite ; SetColor ( 1 ); } public void SetColor ( float _alpha ) { Color color = imageItem . color ; color . a = _alpha ; imageItem . color = color ; } }

instance 이 DragSlot UI 이미지 오브젝트를 담는다. 즉, 자기 자신을 담는다. static 이므로 한번 자기 자신을 담은 후로는 게임 내내 메모리에 자기 자신이 유지된다. 동일한 자기 자신에 대해 여러 곳에서 공유할 수 있다.

dragSlot 드래그 대상이 되는 Slot 을 참조 드래그 대상이 되는 Slot 의 Sprite이미지가 복사되어 들어갈 것

imageItem 자기 자신의 이미지 컴포넌트

Start() 게임 시작 되면 instance 에 자기 자신 할당

DragSetImage(Image _itemImage) 드래그 되는 슬롯의 이미지가 들어옴. 자기 자신의 이미지에 인수로 들어온 Sprite 이미지 할당 투명도를 다시 1 로 불투명하게

SetColor(float _alpha) 본인의 이미지 컴포넌트 imageItem 의 이미지 투명도

dragSlot 는 게임 도중 드래그가 발생할 때 할당될 것이다.

는 게임 도중 드래그가 발생할 때 할당될 것이다. imageItem 는 dragSlot 본인의 이미지 컴포넌트. 드래그 대상이 되는 Slot 의 Sprite 이미지가 소스 이미지에 할당 될 곳.

는 본인의 이미지 컴포넌트.

📜Slot.cs

using System.Collections ; using System.Collections.Generic ; using UnityEngine ; using UnityEngine.UI ; using UnityEngine.EventSystems ; public class Slot : MonoBehaviour , IPointerClickHandler , IBeginDragHandler , IDragHandler , IEndDragHandler , IDropHandler { //… // 마우스 드래그가 시작 됐을 때 발생하는 이벤트 public void OnBeginDrag ( PointerEventData eventData ) { if ( item != null ) { DragSlot . instance . dragSlot = this ; DragSlot . instance . DragSetImage ( itemImage ); DragSlot . instance . transform . position = eventData . position ; } } // 마우스 드래그 중일 때 계속 발생하는 이벤트 public void OnDrag ( PointerEventData eventData ) { if ( item != null ) DragSlot . instance . transform . position = eventData . position ; } // 마우스 드래그가 끝났을 때 발생하는 이벤트 public void OnEndDrag ( PointerEventData eventData ) { DragSlot . instance . SetColor ( 0 ); DragSlot . instance . dragSlot = null ; } }

OnBeginDrag(PointerEventData eventData) 드래그 되는 대상인, 드래그가 시작 된 슬롯에서 호출 아이템이 있는 슬롯이라면 드래그 슬롯에 자기 자신 할당. dragSlot 에서 자기 자신을 참조하게 된다. 드래그 슬롯의 이미지를 자신의 아이템 이미지로 드래그 슬롯의 위치를 드래그가 발생한 위치로

OnDrag(PointerEventData eventData) 드래그 되는 대상인, 드래그 중인 슬롯에서 계속 호출 아이템이 있는 슬롯이라면 드래그 슬롯의 위치를 드래그가 발생한 위치로 드래그 슬롯이 마우스 드래그 위치를 따라 움직임

OnEndDrag(PointerEventData eventData) 드래그가 끝났을 때 드래그 되는 대상인 슬롯에서 호출 드래그 슬롯 다시 초기화 투명하게 만들고 참조 중이던 슬롯과의 연결 끊기

🚖 인벤토리 드롭

📜Slot.cs

// 해당 슬롯에 무언가가 마우스 드롭 됐을 때 발생하는 이벤트 public void OnDrop ( PointerEventData eventData ) { if ( DragSlot . instance . dragSlot != null ) ChangeSlot (); } private void ChangeSlot () { Item _tempItem = item ; int _tempItemCount = itemCount ; AddItem ( DragSlot . instance . dragSlot . item , DragSlot . instance . dragSlot . itemCount ); if ( _tempItem != null ) DragSlot . instance . dragSlot . AddItem ( _tempItem , _tempItemCount ); else DragSlot . instance . dragSlot . ClearSlot (); }

OnEndDrag 과 OnDrop 의 차이 OnEndDrag 👉 나 자신을 드래그 하는 것을 끝냈을 때 호출 내가 드래그 되는 것이 끝났을 때! 드래그가 종료했을 때, 드래그 대상이 되었던 오브젝트에서 호출 됨. OnDrop 👉 누군지 모르겠지만 내 자신한테 드롭 된 무언가가 있을 때 호출. 나한테 누가 드롭 되었을 때! 드래그를 멈춘 위치에 있는 오브젝트에서 호출 됨. 드롭 된 다른 곳의 OnDrop 이, 드래그를 끝낸 내 OnEndDrag 보다 먼저 실행된다.

OnDrop(PointerEventData eventData) 드래그 대상이 아니라, 드롭 위치 대상이 된 슬롯에서 호출된다. 현재 드래그 슬롯이 null 이 아니라면 드래그 되고 있는 슬롯이 자신에게 드롭되었다는 뜻이므로 ChangeSlot()을 통하여 슬롯을 서로 바꾼다. 드롭 위치 대상이 된 슬롯이 비어있든 아이템이 있든 그건 상관 없다.

ChangeSlot() A 슬롯을 드래그 하여 B 슬롯에 드롭하여, A 슬롯 B 슬롯 서로 자리를 바꾸려면 B 슬롯을 복사하여 다른 곳에 일단 보관 _tempItem , _tempItemCount B 슬롯 자리에 A 슬롯 추가 A 슬롯은 dragSlot 에서 참조 중. ChangeSlot()이 호출되는 즉, 드롭 위치가 된 슬롯에다가 A 슬롯을 추가한다. AddItem ( DragSlot . instance . dragSlot . item , DragSlot . instance . dragSlot . itemCount ); A 슬롯 자리에 임시 보관해 놨던 B 슬롯 추가 드롭 위치 대상인 B 슬롯이 빈 슬롯이 아니라면 A 슬롯 자리에 B 슬롯을 추가한다. DragSlot . instance . dragSlot . AddItem ( _tempItem , _tempItemCount ) B 슬롯이 빈 슬롯이였다면 A 슬롯을 비워주기만 하면 된다. DragSlot.instance.dragSlot.ClearSlot();

마우스 충돌 가리지 않게

위까지 해도, 슬롯을 아무리 드래그 해도 슬롯 교체가 제대로 이루어지지 않는다. 그 이유는 드롭 되는 위치의 대상이 슬롯의 OnDrop 가 제대로 호출되지 않았기 때문이다. ⭐이미지를 드래그 하여 옮기는 과정에서 DropSlot 이미지가 마우스 이벤트 Raycast를 대신 받아 버리기 때문에, DropSlot 뒤에 있는 드롭 되는 위치의 대상이 되는 Slot 이미지가 마우스 이벤트를 받지 못하여 OnDrop 가 제대로 호출되지 않았던 것이다.

체크 된 마우스를 놓고 드롭 해주어야만, 즉 직접 드롭 위치가 되는 Slot 에다가 직접 마우스를 대고 드롭해주어야만이 그 슬롯의 OnDrop이 호출 될 수 있었다. 근데 사실상 DropSlot 를 드래그 해오기 때문에 DropSlot 가 가려버리기 쉽상..

DropSlot 의 Raycast Target 을 해제 해주어 Raycast 를 못 받게 하면 해결 된다. 어차피 마우스 이벤트는 드래그 시작 대상이 됐었던 슬롯과 드롭 위치 대상이 됐었던 슬롯에서 일어나기 때문에 DropSlot 는 이벤트 못 받아도 괜찮다. 이게 체크 되있으면 DropSlot 이 드래그 과정에서 드롭 위치 대상이 되는 슬롯의 앞을 가려 OnDrop 호출, 즉 마우스의 충돌을 방해한다. 뒤에 있는 드롭 위치 대상이 되는 슬롯에 마우스가 직접적으로 닿아야 OnDrop 호출이 이루어 지는데 DropSlot 이 충돌을 대신 앞에서 받아버리기 때문이다.

의 을 해제 해주어 Raycast 를 못 받게 하면 해결 된다. 체크 해제해주면 DropSlot 는 이벤트 Raycast를 받지 못해 그냥 관통되고 DropSlot 가 가리고 있더라도 드롭 위치 대상이 되는 슬롯까지 Raycast가 잘 도달 하여 OnDrop가 잘 호출 된다.

🚖 인벤토리 활성화 되면 공격 카메라 회전 등등 비활성화

📜PlyaerController.cs

void Update () { IsGround (); TryJump (); TryRun (); TryCrouch (); Move (); MoveCheck (); if (! Inventory . invectoryActivated ) { CameraRotation (); CharacterRotation (); } }

인벤토리가 활성화 되면 마우스 움직임에 따른 카메라 회전, 캐릭터 회전 제한.

📜WeaponSway.cs

void Update () { if (! Inventory . invectoryActivated ) TrySway (); }

인벤토리가 활성화 되면 마우스 움직임에 따른 무기 흔들림 제한.

📜CloseWeaponController.cs

protected void TryAttack () { if (! Inventory . invectoryActivated ) { if ( Input . GetButton ( “Fire1” )) { if (! isAttack ) { if ( CheckObject ()) { if ( currentCloseWeapon . isAxe && hitInfo . transform . tag == “Tree” ) { StartCoroutine ( thePlayerController . TreeLookCoroutine ( hitInfo . transform . GetComponent < TreeComponent >(). GetTreeCenterPosition ())); StartCoroutine ( AttackCoroutine ( “Chop” , currentCloseWeapon . workDelayA , currentCloseWeapon . workDelayB , currentCloseWeapon . workDelay )); return ; } } StartCoroutine ( AttackCoroutine ( “Attack” , currentCloseWeapon . attackDelayA , currentCloseWeapon . attackDelayB , currentCloseWeapon . attackDelay )); } } } }

인벤토리가 활성화 되면 근접 무기 좌클릭 제한.

📜GunController.cs

void Update () { if ( isActivate ) { GunFireRateCalc (); if (! Inventory . invectoryActivated ) { TryFire (); TryReload (); TryFineSight (); } } }

인벤토리가 활성화 되면 총 발사, 재장전, 정조준 제한.

📜WeaponManager.cs

void Update () { if (! Inventory . invectoryActivated ) { if (! isChangeWeapon ) { if ( Input . GetKeyDown ( KeyCode . Alpha1 )) // 1 누르면 ‘맨손’으로 무기 교체 실행 StartCoroutine ( ChangeWeaponCoroutine ( “HAND” , “맨손” )); else if ( Input . GetKeyDown ( KeyCode . Alpha2 )) // 2 누르면 ‘서브 머신건’으로 무기 교체 실행 StartCoroutine ( ChangeWeaponCoroutine ( “GUN” , “SubMachineGun1” )); else if ( Input . GetKeyDown ( KeyCode . Alpha3 )) // 3 누르면 ‘도끼’로 무기 교체 실행 StartCoroutine ( ChangeWeaponCoroutine ( “AXE” , “Axe” )); else if ( Input . GetKeyDown ( KeyCode . Alpha4 )) // 4 누르면 ‘곡괭이’로 무기 교체 실행 StartCoroutine ( ChangeWeaponCoroutine ( “PICKAXE” , “Pickaxe” )); } } }

인벤토리가 활성화 되면 무기 교체 제한.

***

🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우 언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄

맨 위로 이동하기

참된코딩 :: [Unity3D] 인벤토리 [Part 3]

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209

using System .Collections; using System .Collections.Generic; using UnityEngine; using UnityEngine.UI; using System .Xml.Serialization; public class Inventory : MonoBehaviour { // 공개 public List < GameObject > AllSlot; // 모든 슬롯을 관리해줄 리스트. public RectTransform InvenRect; // 인벤토리의 Rect public GameObject OriginSlot; // 오리지널 슬롯. public float slotSize; // 슬롯의 사이즈. public float slotGap; // 슬롯간 간격. public float slotCountX; // 슬롯의 가로 개수. public float slotCountY; // 슬롯의 세로 개수. // 비공개. private float InvenWidth; // 인벤토리 가로길이. private float InvenHeight; // 인밴토리 세로길이. //private float EmptySlot; // 빈 슬롯의 개수. void Awake() { // 인벤토리 이미지의 가로, 세로 사이즈 셋팅. InvenWidth = (slotCountX * slotSize) + (slotCountX * slotGap) + slotGap; InvenHeight = (slotCountY * slotSize) + (slotCountY * slotGap) + slotGap; // 셋팅된 사이즈로 크기를 설정. InvenRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, InvenWidth); // 가로. InvenRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, InvenHeight); // 세로. // 슬롯 생성하기. for ( int y = 0 ; y < slotCountY; y + + ) { for ( int x = 0 ; x < slotCountX; x + + ) { // 슬롯을 복사한다. GameObject slot = Instantiate(OriginSlot) as GameObject; // 슬롯의 RectTransform을 가져온다. RectTransform slotRect = slot.GetComponent < RectTransform > (); // 슬롯의 자식인 투명이미지의 RectTransform을 가져온다. RectTransform item = slot.transform.GetChild( 0 ).GetComponent < RectTransform > (); slot.name = “slot_” + y + “_” + x; // 슬롯 이름 설정. slot.transform.SetParent(transform); // 슬롯의 부모를 설정. (Inventory객체가 부모임.) // 슬롯이 생성될 위치 설정하기. slotRect.localPosition = new Vector3((slotSize * x) + (slotGap * (x + 1 )), – ((slotSize * y) + (slotGap * (y + 1 ))), 0 ); // 슬롯의 자식인 투명이미지의 사이즈 설정하기. slotRect.localScale = Vector3.one; slotRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, slotSize); // 가로 slotRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, slotSize); // 세로. // 슬롯의 사이즈 설정하기. item.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, slotSize – slotSize * 0. 3f); // 가로. item.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, slotSize – slotSize * 0. 3f); // 세로. // 리스트에 슬롯을 추가. AllSlot.Add(slot); } } // 빈 슬롯 = 슬롯의 숫자. //EmptySlot = AllSlot.Count; Invoke( “Init” , 0. 01f); } void Init() { ItemIO.Load(AllSlot); } // 아이템을 넣기위해 모든 슬롯을 검사. public bool AddItem(Item item) { // 슬롯에 총 개수. int slotCount = AllSlot.Count; // 넣기위한 아이템이 슬롯에 존재하는지 검사. for ( int i = 0 ; i < slotCount; i + + ) { // 그 슬롯의 스크립트를 가져온다. Slot slot = AllSlot[i].GetComponent < Slot > (); // 슬롯이 비어있으면 통과. if ( ! slot.isSlots()) continue ; // 슬롯에 존재하는 아이템의 타입과 넣을려는 아이템의 타입이 같고. // 슬롯에 존재하는 아이템의 겹칠수 있는 최대치가 넘지않았을 때. (true일 때) if (slot.ItemReturn().type = = item.type & & slot.ItemMax(item)) { // 슬롯에 아이템을 넣는다. slot.AddItem(item); return true ; } } // 빈 슬롯에 아이템을 넣기위한 검사. for ( int i = 0 ; i < slotCount; i + + ) { Slot slot = AllSlot[i].GetComponent < Slot > (); // 슬롯이 비어있지 않으면 통과 if (slot.isSlots()) continue ; slot.AddItem(item); return true ; } // 위에 조건에 해당되는 것이 없을 때 아이템을 먹지 못함. return false ; } // 거리가 가까운 슬롯의 반환. public Slot NearDisSlot(Vector3 Pos) { float Min = 10000f; int Index = – 1 ; int Count = AllSlot.Count; for ( int i = 0 ; i < Count; i + + ) { Vector2 sPos = AllSlot[i].transform.GetChild( 0 ).position; float Dis = Vector2.Distance(sPos, Pos); if (Dis < Min) { Min = Dis; Index = i; } } if (Min > slotSize) return null ; return AllSlot[Index].GetComponent < Slot > (); } // 아이템 옮기기 및 교환. public void Swap(Slot slot, Vector3 Pos) { Slot FirstSlot = NearDisSlot(Pos); // 현재 슬롯과 옮기려는 슬롯이 같으면 함수 종료. if (slot = = FirstSlot | | FirstSlot = = null ) { slot.UpdateInfo( true , slot.slot.Peek().DefaultImg); return ; } // 가까운 슬롯이 비어있으면 옮기기. if ( ! FirstSlot.isSlots()) { Swap(FirstSlot, slot); } // 교환. else { int Count = slot.slot.Count; Item item = slot.slot.Peek(); Stack < Item > temp = new Stack < Item > (); { for ( int i = 0 ; i < Count; i + + ) temp.Push(item); slot.slot.Clear(); } Swap(slot, FirstSlot); { Count = temp.Count; item = temp.Peek(); for ( int i = 0 ; i < Count; i + + ) FirstSlot.slot.Push(item); FirstSlot.UpdateInfo( true , temp.Peek().DefaultImg); } } } // 1: 비어있는 슬롯, 2: 안 비어있는 슬롯. void Swap(Slot xFirst, Slot oSecond) { int Count = oSecond.slot.Count; Item item = oSecond.slot.Peek(); for ( int i = 0 ; i < Count; i + + ) { if (xFirst ! = null ) xFirst.slot.Push(item); } if (xFirst ! = null ) xFirst.UpdateInfo( true , oSecond.ItemReturn().DefaultImg); oSecond.slot.Clear(); oSecond.UpdateInfo( false , oSecond.DefaultImg); } } Colored by Color Scripter

[Unity]EventSystem을 이용해 아이템UI 드래그 및 다른 슬롯에 등록하기(IDragHandler, IDropHandler)

여러 방법이 있지만 이게 가장 간단한 방법 같아서 정리한다.

아이템 사용 이런거는 없고 단수

드래그, 드랍할 UI오브젝트에 Drag관련 인터페이스가 포함된 스크립트를 추가

예시)

public class ItemDragHandler : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler

그리고 인터페이스에 해당하는 함수를 구현해주면 된다.

드래그해서 마우스를 따라다니게 하고 싶으므로 IDragHandler의 OnDrag함수를 구현해주면 된다.

예)

public void OnDrag(PointerEventData eventData)

{

transform.position = eventData.position;

}

참고로 eventData.position 말고 Input.mousePosition 을 써도 된다.

아이템을 놓았을 때 제자리로 돌아가게 하고 싶다하면 IEndDragHandler의 OnEndDrag를 처리해주면 된다.

UI 가려질 때

위 예시 이미지와는 다르게 움직이면 다른 UI에 가려진다.

UI의 hierarchy 때문에 발생하는 문젠데 방법은 여러가지 있다.

1. 코드상에서 setsibling 같은 함수를 이용해 순서를 정해주는 방법

2. 캔버스를 여러개 두어 캔버스 간의 order를 정해놓는 것

3. 해당 오브젝트를 드래그할때만 Canvas 바로 아래의 자식으로 놓는 방법

여기서 나는 3번을 택해서 작업했다.

예시)

public void OnBeginDrag(PointerEventData eventData)

{

_startParent = transform.parent;

transform.SetParent(GameObject.FindGameObjectWithTag(“UI Canvas”).transform);

}

이런식으로 놓고 드래그가 끝날 때는 다시 원래대로 돌려주는 것을 잊지말자.

public void OnEndDrag(PointerEventData eventData)

{

transform.SetParent(_startParent);

transform.localPosition = Vector3.zero;

}

OnDrop 이벤트 발생안할 때(못 받을 때)

위처럼 하고나면 몇몇 UI에는 OnDrop 이벤트가 발생하지 않을 것이다.

결론부터 말하면 Raycast 문제다.

드래그하고 있는 오브젝트를 Canvas 바로 밑으로 올려 해당 오브젝트보다 하위에 존재하는 UI들이 반응하지 않는다.

흰색이 드래그 되고 있는 UI 오브젝트고 갈색이 OnDrop 이벤트를 받을 오브젝트다.

위 사진은 발생이 안되는 경우로 흰색이 갈색보다 위에 있어서 안된다.

흰색이 갈색보다 아래에 있을 때는 된다.

UI관련된 그래픽 컴포넌트들은 GraphicRaycast라고 따로 받는 레이캐스트가 존재한다.

UI관련 오브젝트(예를 들면 Image)에 raycastTarget이라고 적힌 옵션이 있을 것이다.

이걸 에디터에서 바로 꺼주면 드래그가 안되니 코드 상에서 잠시 꺼주면 된다.

1. 드래그 시작 -> 해당 그래픽 컴포넌트 raycast 꺼주기

2. 드래그 끝났을 때 -> 다시 raycast 켜주기

이러한 방식이 맘에 들지 않는다면 직접 GraphciRaycaster를 이용해 우리가 3d게임에서 raycast로 오브젝트를 검출하듯이 똑같이 UI도 태그나 다양한 방식을 이용해 검출해서 사용하면 된다.

나는 전자를 선택해 이렇게 했다.

예시)

public void OnBeginDrag(PointerEventData eventData)

{

_itemBeingDragged = gameObject.GetComponentInParent().GetItem();

_startParent = transform.parent;

transform.SetParent(GameObject.FindGameObjectWithTag(“UI Canvas”).transform);

GetComponent().raycastTarget = false;

}

public void OnEndDrag(PointerEventData eventData)

{

transform.SetParent(_startParent);

transform.localPosition = Vector3.zero;

_itemBeingDragged = null;

GetComponent().raycastTarget = true;

}

다른 슬롯에서 OnDrop 구현

OnDrop 이벤트를 받을 다른 슬롯창에서 구현해주면 된다.

참고로 Drag할 아이템은 하나여서 관련 클래스쪽에서 static으로 선언했다. (public static Item _itemBeingDragged;)

다른 슬롯의 코드 예시다.

예시)

public Image _icon;

public void OnDrop(PointerEventData eventData)

{

var item = ItemDragHandler._itemBeingDragged;

if (item != null)

{

_icon.sprite = item.icon;

_icon.enabled = true;

}

}

결과 이미지

프로젝트 소스는 github에서 확인 가능하다.

https://github.com/AntarticPenguin/ProjectF/tree/master/Assets/01.Scripts/Item

틀린 부분 지적은 언제나 환영입니다.

Unity Drag and Drop from Inventory

I am very new to Unity so please excuse my amateur understanding of things. I am currently trying to implement an interface in unity 3d with an inventory including 2D icons which I want to drag and drop from the inventory which should then let the gameObejct spawn. I have tried to implement the exact codes from Jayanam on YouTube, adding you the links here: Create inventory UI: https://www.youtube.com/watch?v=-xB4xEmGtCY&list=PLg7sMWZoap4B8N1pR8nl2-eG_D5k9MfWY

Inventory Script: https://www.youtube.com/watch?v=Hj7AZkyojdo&list=PLg7sMWZoap4B8N1pR8nl2-eG_D5k9MfWY&index=2

Inventory UI Drag and Drop: https://www.youtube.com/watch?v=Pc8K_DVPgVM&list=PLg7sMWZoap4B8N1pR8nl2-eG_D5k9MfWY&index=3

Drop Item: https://www.youtube.com/watch?v=db6ofSbAXnE&list=PLg7sMWZoap4B8N1pR8nl2-eG_D5k9MfWY&index=4

Everything works fine, until I reach the point where I want to drop the Item. I can see that it calls the drop-function, but my gameObject doesn’t spawn. I am adding you my codes here and I hope that someone might have the answer.

GameObject:

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public class Child : MonoBehaviour, IInventoryItem { public string Name { get { return “Child”; } } public Sprite _Image = null; public Sprite Image { get { return _Image; } } public void OnPickup() { // TODO: Add logic what happens when child stays in the sun for too long gameObject.SetActive(false); } public void OnDrop() { RaycastHit hit = new RaycastHit(); Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); if(Physics.Raycast(ray, out hit, 1000)) { gameObject.SetActive(true); gameObject.transform.position = hit.point; } } }

HUD Script to handle the Inventory:

using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class HUD : MonoBehaviour { public Inventory Inventory; // Start is called before the first frame update void Start() { Inventory.ItemAdded += InventoryScript_ItemAdded; Inventory.ItemRemoved += Inventory_ItemRemoved; } private void InventoryScript_ItemAdded(object sender, InventoryEventArgs e) { Transform inventoryPanel = transform.Find(“InventoryPanel”); foreach(Transform slot in inventoryPanel) { // Border … Image Transform imageTransform = slot.GetChild(0).GetChild(0); Image image = slot.GetChild(0).GetChild(0).GetComponent(); ItemDragHandler itemDragHandler = imageTransform.GetComponent(); // We found the empty slot if (!image.enabled) { image.enabled = true; image.sprite = e.Item.Image; // TODO: Store a reference to the item itemDragHandler.Item = e.Item; break; } } } private void Inventory_ItemRemoved(object sender, InventoryEventArgs e) { Transform inventoryPanel = transform.Find(“InventoryPanel”); foreach (Transform slot in inventoryPanel) { Transform imageTransform = slot.GetChild(0).GetChild(0); Image image = imageTransform.GetComponent(); ItemDragHandler itemDragHandler = imageTransform.GetComponent(); //We found the item in the UI if (itemDragHandler.Item.Equals(e.Item)) { image.enabled = false; image.sprite = null; itemDragHandler.Item = null; break; } } } }

Item Drag Handler to pull the Item Image out of the Inventory:

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public class ItemDragHandler : MonoBehaviour, IDragHandler, IEndDragHandler { public IInventoryItem Item { get; set; } public void OnDrag(PointerEventData eventData) { transform.position = Input.mousePosition; } public void OnEndDrag(PointerEventData eventData) { transform.localPosition = Vector3.zero; } }

Item Drop Handler:

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public class ItemDropHandler : MonoBehaviour, IDropHandler { public void OnDrop(PointerEventData eventData) { RectTransform invPanel = transform as RectTransform; if(!RectTransformUtility.RectangleContainsScreenPoint(invPanel, Input.mousePosition)) { Debug.Log(“Drop item”); } } }

Inventory Script:

using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class Inventory : MonoBehaviour { private const int SLOTS = 4; private List mItems = new List(); public event EventHandler ItemAdded; public event EventHandler ItemRemoved; //TODO: delete collider, Item should be picked up by mouse public void AddItem(IInventoryItem item) { if(mItems.Count < SLOTS) { Collider collider = (item as MonoBehaviour).GetComponent(); if (collider.enabled) { collider.enabled = false; mItems.Add(item); item.OnPickup(); if (ItemAdded != null) { ItemAdded(this, new InventoryEventArgs(item)); } } } } public void RemoveItem(IInventoryItem item) { if (mItems.Contains(item)) { mItems.Remove(item); item.OnDrop(); Collider collider = (item as MonoBehaviour).GetComponent(); if (collider != null) { collider.enabled = true; } if (ItemRemoved != null) { ItemRemoved(this, new InventoryEventArgs(item)); } } } }

Inventory Item Class

using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public interface IInventoryItem { string Name { get; } Sprite Image { get; } void OnPickup(); void OnDrop(); } public class InventoryEventArgs: EventArgs { public InventoryEventArgs(IInventoryItem item) { Item = item; } public IInventoryItem Item; }

I would be really grateful if someone could help me out. I have been trying forever and I’m going crazy.

Mastering UI Development with Unity: An in-depth guide to developing …

0 Bąi đįnh giį Google khōng xįc minh bąi đįnh giį nhưng có kiểm tra để tģm nội dung giả vą xoį nội dung đó khi tģm thấy Viết bąi đįnh giį

Mastering UI Development with Unity: An in-depth guide to developing … Bởi Ashley Godbold

키워드에 대한 정보 유니티 인벤토리 드래그

다음은 Bing에서 유니티 인벤토리 드래그 주제에 대한 검색 결과입니다. 필요한 경우 더 읽을 수 있습니다.

이 기사는 인터넷의 다양한 출처에서 편집되었습니다. 이 기사가 유용했기를 바랍니다. 이 기사가 유용하다고 생각되면 공유하십시오. 매우 감사합니다!

사람들이 주제에 대해 자주 검색하는 키워드 [유니티 3D 강좌] FPS 서바이벌 디펜스 Part 16 : 인벤토리 드래그\u0026드롭

  • 유니티
  • 유니티 강좌
  • 유니티 3D 강좌
[유니티 #3D #강좌] #FPS #서바이벌 #디펜스 #Part #16 #: #인벤토리 #드래그\u0026드롭


YouTube에서 유니티 인벤토리 드래그 주제의 다른 동영상 보기

주제에 대한 기사를 시청해 주셔서 감사합니다 [유니티 3D 강좌] FPS 서바이벌 디펜스 Part 16 : 인벤토리 드래그\u0026드롭 | 유니티 인벤토리 드래그, 이 기사가 유용하다고 생각되면 공유하십시오, 매우 감사합니다.

See also  삼성 장로 교회 | 3-22-20 삼성 장로 교회 주일 동영상 예배 실황 상위 77개 답변

Leave a Reply

Your email address will not be published. Required fields are marked *