首先学习之前所需要的必备知识有:ScriptableObject,数据结构链表的使用,以及一些涉及到UnityEditor相关便于我们开发的,射线相关的UI以及EventSystems的命名空间,那么现在就开始吧。
首先我们需要整体的对物品进行一个描述,如它是什么类型的,是可以浇花的,还是可以种地的,还是可以攻击的,我们将在一个只用来写枚举的C#脚本中创建它,
- public enum ItemType
- {
- Seed,
- Commodity,
- Watering_tool,
- Hoeing_tool,
- Chopping_tool,
- Breaking_tool,
- Reping_tool,
- Collecting_tool,
- Reapable_scenery,
- Furinture,
- None,
- Count,
-
- }
只有枚举没有类名,
首先我们先写展现Item细节类的脚本ItemDetails,我们使用
[System.Serializable]让它即使不能被挂载到游戏对象上,也能被其它类识别然后调用,
- using UnityEngine;
-
- [System.Serializable]
- public class ItemDetails
- {
- public int itemCode;
- public ItemType itemType;
- public string itemDescription;
- public Sprite itemSprite;
- public string itemLongDescription;
- public short itemUseGridRadius;
- public float itemUseRadius;
- public bool isStartingItem;
- public bool canBePickUp;
- public bool canBeDropped;
- public bool canBeEaten;
- public bool canBeCarried;
- }
然后我们就可以开始写Item类了,(这里[ItemCodeDescription]需要自定义的,一会讲)ItemCode属性是非常重要的东西,每一个独一无二的Item都将拥有属于自己ItemCode,然后我们就可以在ItemCode中调用它
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class Item : MonoBehaviour
- {
- [ItemCodeDescription][SerializeField] private int _itemCode;
- private SpriteRenderer spriteRenderer;
-
- public int ItemCode
- {
- get
- {
- return _itemCode;
- }
- set
- {
- _itemCode = value;
- }
- }
-
- private void Awake()
- {
- spriteRenderer = GetComponentInChildren
(); - }
-
- private void Start()
- {
- if(ItemCode != 0)
- {
- Init(ItemCode);
- }
- }
-
- public void Init(int itemCodeParams)
- {
-
- }
- }
(这里[ItemCodeDescription]需要自定义的,一会讲)
弄完后我们需要一个链表数组来存储所有的Item
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- [CreateAssetMenu(fileName = "so_Itemlist", menuName = "Scriptable Objects/Item list")]
- public class SO_ItemList : ScriptableObject
- {
- public List
itemDetails; - }
回到Unity,我们为每一个Item创建独一无二的数据,这里就根据你的需求来填写这些数据了。
那么这个 iItemCodeDescription是从哪里来的呢,这里就设计到我们的UnityEditor知识了。
在你的脚本文件夹中创建两个如下名字的脚本
先 打开Attribute,我们只需要让它继承PropertyAttribute即可
- using UnityEngine;
-
- public class ItemCodeDescriptionAttribute : PropertyAttribute
- {
-
- }
剩下的脚本则需要引用UnityEditor命名空间,我们将在GUI上更改信息
-
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEditor;
-
- [CustomPropertyDrawer(typeof(ItemCodeDescriptionAttribute))] //告诉系统自定义特性名叫ItemCodeDescriptionAttribute
- public class ItemCodeDescriptionDrawer : PropertyDrawer
- {
- public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
- {
- return EditorGUI.GetPropertyHeight(property) * 2;
- }
-
- public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
- {
- EditorGUI.BeginProperty(position, label, property);
-
- if(property.propertyType == SerializedPropertyType.Integer)
- {
- EditorGUI.BeginChangeCheck();
-
- var newValue = EditorGUI.IntField(new Rect(position.x, position.y, position.width, position.height / 2),label,property.intValue);
-
- EditorGUI.LabelField(new Rect(position.x, position.y + position.height /2 , position.width, position.height / 2), "Item Description",
- GetItemDescription(property.intValue));
-
-
- //如果Item的ItemCode的值发生改变,则面板上的值也要发生变化
-
- if (EditorGUI.EndChangeCheck())
- {
- property.intValue = newValue;
- }
- }
-
-
- EditorGUI.EndProperty();
- }
-
- private string GetItemDescription(int itemCode)
- {
- SO_ItemList so_itemList;
-
- so_itemList = AssetDatabase.LoadAssetAtPath("Assets/Scriptable Object Assets/Items/so_Itemlist.asset", typeof(SO_ItemList)) as SO_ItemList;
-
- List
itemDetailLists = so_itemList.itemDetails; -
- ItemDetails itemDetail = itemDetailLists.Find(x => x.itemCode == itemCode);
-
- if(itemDetail!= null)
- {
- return itemDetail.itemDescription;
- }
- else
- {
- return "";
- }
- }
- }
我们会用到链表系统SO_ItmeList,并且用 AssetDatabase.LoadAssetAtPath获取本地路径,找到SO_ItmeList里面所有的链表,然后用Find函数寻找相同itemCode的ItemDetails,如果找到了就返回它的描述字符串,否则返回空双引号"";
接下来就可以用你自定义的特性了
接下来我们创建一个父预制体,如下所示添加Item类,
把Item做成预制体后创建它的子对象操作如下
比如我做了一个南瓜Item,可以看到,我们给南瓜对应的编号,底下的Decsription就会跟着改变,我是10001,描述的内容就是南瓜
我们可以添加一些效果给场景中的Item类,例如有些Item的属性中是不能被拾取,例如这些草仅仅是风景用途
我们可以让在经过草的时候摆动一下。
写个新脚本用协程来实现
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class ItemNudge : MonoBehaviour
- {
- [SerializeField] private float pauseTime = 0.04f;
- private WaitForSeconds pause;
- private bool isAnimating = false;
-
- private void Awake()
- {
- pause = new WaitForSeconds(pauseTime);
- }
-
- private void OnTriggerEnter2D(Collider2D collision)
- {
- if (!isAnimating)
- {
- if(gameObject.transform.position.x < collision.transform.position.x) //如果在左边
- {
- StartCoroutine(nameof(RotateAndClock));
- }
- else
- {
- StartCoroutine(nameof(RotateClock));
- }
- }
- }
-
- private IEnumerator RotateAndClock()
- {
- isAnimating = true;
-
- for (int i = 0; i < 4; i++)
- {
- gameObject.transform.GetChild(0).Rotate(0f, 0f, 2f);
- yield return pause;
- }
-
- for (int i = 0; i < 5; i++)
- {
- gameObject.transform.GetChild(0).Rotate(0f, 0f, -2f);
- yield return pause;
- }
-
- gameObject.transform.GetChild(0).Rotate(0f, 0f, 2f);
-
- yield return pause;
-
- isAnimating = false;
- }
-
- private IEnumerator RotateClock()
- {
- isAnimating = true;
-
- for (int i = 0; i < 4; i++)
- {
- gameObject.transform.GetChild(0).Rotate(0f, 0f, -2f);
- yield return pause;
- }
-
- for (int i = 0; i < 5; i++)
- {
- gameObject.transform.GetChild(0).Rotate(0f, 0f, 2f);
- yield return pause;
- }
-
- gameObject.transform.GetChild(0).Rotate(0f, 0f, -2f);
-
- yield return pause;
-
- isAnimating = false;
- }
- }
再回到Item类在初始化方法中判断是不是ItemType.Reapable_scenery,是的话就给它添加我们刚刚新建的脚本
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class Item : MonoBehaviour
- {
- [ItemCodeDescription][SerializeField] private int _itemCode;
- private SpriteRenderer spriteRenderer;
-
- public int ItemCode
- {
- get
- {
- return _itemCode;
- }
- set
- {
- _itemCode = value;
- }
- }
-
- private void Awake()
- {
- spriteRenderer = GetComponentInChildren
(); - }
-
- private void Start()
- {
- if(ItemCode != 0)
- {
- Init(ItemCode);
- }
- }
-
- public void Init(int itemCodeParams)
- {
- if(itemCodeParams != 0)
- {
- ItemCode = itemCodeParams;
-
- ItemDetails itemDetails = InventoryManager.Instance.GetItemDetails(ItemCode);
-
- spriteRenderer.sprite = itemDetails.itemSprite;
-
- if(itemDetails.itemType == ItemType.Reapable_scenery) //如果该物品是风景类型的话
- {
- gameObject.AddComponent
(); - }
- }
- }
- }
接下来来实现如何做到拾取物品
我们给玩家添加一个新脚本就叫ItemPickUp,因为每一个Item身上都有一个触发器
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class ItemPickUp : MonoBehaviour
- {
- private void OnTriggerEnter2D(Collider2D collision)
- {
- if(collision.TryGetComponent
- (out Item item))
- {
- ItemDetails itemDetails = InventoryManager.Instance.GetItemDetails(item.ItemCode);
-
- if (itemDetails.canBePickUp)
- {
-
- }
- }
- }
- }
我们还需要一个背包系统InventoryManager,它和SO_ItemList的区别在于,它是一个存储你所能收集到的Item,而SO_ItemList则更像是一个登记所有物品信息的。
我们要写一个新枚举,我们将使用二维数组来控制使用的是哪一个背包。
-
- public enum InventoryLocation
- {
- player,
- chest,
- count,
- }
-
- public enum ItemType
- {
- Seed,
- Commodity,
- Watering_tool,
- Hoeing_tool,
- Chopping_tool,
- Breaking_tool,
- Reping_tool,
- Collecting_tool,
- Reapable_scenery,
- Furinture,
- None,
- Count,
-
- }
接着创建一个结构来管理背包中的Item
- [System.Serializable]
- public struct InventoryItem
- {
- public int itemCode;
- public int itemQuantity;
- }
还需要一个单例模式
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class Singleton<T> : MonoBehaviour where T : Component
- {
- private static T instance;
-
- public static T Instance
- {
- get
- {
- return instance;
- }
- }
-
- protected virtual void Awake()
- {
- if(instance == null)
- {
- instance = this as T;
- }
- else
- {
- Destroy(gameObject);
- }
- }
- }
w我们需要一个事件处理程序来完成它
- using System;
- using System.Collections;
- using System.Collections.Generic;
-
- public static class EventHandler
- {
- public static event Action
> InventoryUpdateEvent; -
- public static void CallInventoryUpdateEvent(InventoryLocation inventoryLocation,List
inventoryLists ) - {
- if(InventoryUpdateEvent != null)
- {
- InventoryUpdateEvent(inventoryLocation, inventoryLists);
- }
- }
-
-
- }
准备工作就绪,我们就可以继续写InventoryManager了
首先要考虑它的添加和移除物品,以及初始化的时候要创建的数组
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class InventoryManager : Singleton<InventoryManager>
- {
- private Dictionary<int, ItemDetails> itemDetailsDictionary; //通过itemDetails上的itemCode(int类型)的值寻找对应的itemDetails
- public List
[] inventoryLists; //一个存放所有InventoryItem的链表的数组 - [HideInInspector] public int[] inventoryListInCapcityInArray; //背包容量大小默认是12
-
- [SerializeField] private SO_ItemList itemLists; //SO_ItemList登记过所有Item
-
- protected override void Awake()
- {
- base.Awake();
-
- CreateInventoryLists();
-
- CreateItemDetailsDictionary();
- }
-
- private void CreateInventoryLists()
- {
- inventoryLists = new List
[(int)InventoryLocation.count];//我们有0号背包系统的链表和1号背包系统的链表 -
- for (int i = 0; i < (int)InventoryLocation.count; i++)
- {
- inventoryLists[i] = new List
(); - }
-
- //出事背包容量列表
- inventoryListInCapcityInArray = new int[(int)InventoryLocation.count];
-
- //初始化玩家背包(0号背包)容量
- inventoryListInCapcityInArray[(int)InventoryLocation.player] = Settings.playerIntialInventoryCapcity;
- }
- public void AddItem(InventoryLocation inventoryLocation, Item item,GameObject gameObjectToDelete)
- {
- AddItem(inventoryLocation, item);
-
- Destroy(gameObjectToDelete);
- }
- ///
- /// 添加物品
- ///
- ///
- ///
- public void AddItem(InventoryLocation inventoryLocation,Item item)
- {
- int itemCode = item.ItemCode;
- List
inventoryList = inventoryLists[(int)inventoryLocation]; -
- int itemPositon = FindItemInventory(inventoryLocation, itemCode);
-
- if(itemPositon != -1)
- {
- AddItemAtPosition(inventoryList, itemCode, itemPositon);//如果找到物品就数量++
- }
- else
- {
- AddItemAtPosition(inventoryList, itemCode); //找不到就在空白处新添加物品
- }
-
- EventHandler.CallInventoryUpdateEvent(inventoryLocation, inventoryLists[(int)inventoryLocation]);
- }
- ///
- /// 交换物品顺序
- ///
- ///
- ///
- ///
- public void SwapInventoryItems(InventoryLocation inventoryLocation, int fromSlotNumber, int toSlotNumber)
- {
- if(fromSlotNumber < inventoryLists[(int)inventoryLocation].Count && toSlotNumber < inventoryLists[(int)inventoryLocation].Count &&
- fromSlotNumber != toSlotNumber && toSlotNumber >= 0)
- {
- InventoryItem fromSlotItem = inventoryLists[(int)inventoryLocation][fromSlotNumber];
- InventoryItem toSlotItem = inventoryLists[(int)inventoryLocation][toSlotNumber];
-
- inventoryLists[(int)inventoryLocation][toSlotNumber] = fromSlotItem;
- inventoryLists[(int)inventoryLocation][fromSlotNumber] = toSlotItem;
-
- EventHandler.CallInventoryUpdateEvent(inventoryLocation, inventoryLists[(int)inventoryLocation]);
-
- }
- }
-
- ///
- /// 将物品添加到背包的位置
- ///
- ///
- ///
-
- private void AddItemAtPosition(List
inventoryList, int itemCode ) - {
- InventoryItem inventoryItem = new InventoryItem();
-
- inventoryItem.itemCode = itemCode;
- inventoryItem.itemQuantity = 1;
-
- inventoryList.Add(inventoryItem);
- }
-
- ///
- /// 对于背包中已经有的物品就加数量
- ///
- ///
- ///
- ///
-
- private void AddItemAtPosition(List
inventoryList, int itemCode, int positon ) - {
- InventoryItem inventoryItem = new InventoryItem();
-
- int quantity = inventoryList[positon].itemQuantity + 1;
- inventoryItem.itemCode = itemCode;
- inventoryItem.itemQuantity = quantity;
- inventoryList[positon] = inventoryItem;
-
- Debug.ClearDeveloperConsole();
- }
-
- internal void RemoveItem(InventoryLocation inventoryLocation, int itemCode)
- {
- List
inventoryList = inventoryLists[(int)inventoryLocation]; - int itemPosition = FindItemInventory(inventoryLocation, itemCode);
-
- if (itemPosition != -1)
- {
- RemoveItemAtPosition(inventoryList,itemCode,itemPosition);
- }
- EventHandler.CallInventoryUpdateEvent(inventoryLocation, inventoryLists[(int)inventoryLocation]);
- }
-
- private void RemoveItemAtPosition(List
inventoryList, int itemCode, int position ) - {
- InventoryItem inventoryItem = new InventoryItem();
-
- int quantity = inventoryList[position].itemQuantity - 1;
-
- if(quantity > 0)
- {
- inventoryItem.itemQuantity = quantity;
- inventoryItem.itemCode = itemCode;
- inventoryList[position] = inventoryItem;
- }
- else
- {
- inventoryList.RemoveAt(position);
- }
- }
-
- ///
- /// 判断物品是否在背包里面,找不到就return -1,找到的话就返回发现物品的位置
- ///
- ///
- ///
- ///
- private int FindItemInventory(InventoryLocation inventoryLocation,int itemCode)
- {
- List
inventoryList = inventoryLists[(int)inventoryLocation]; -
- for (int i = 0; i < inventoryList.Count; i++)
- {
- if(inventoryList[i].itemCode == itemCode)
- {
- return i;
- }
- }
-
- return -1;
- }
-
- ///
- /// 初始化创建的字典
- ///
-
- private void CreateItemDetailsDictionary()
- {
- itemDetailsDictionary = new Dictionary<int, ItemDetails>();
-
- foreach (var itemDetails in itemLists.itemDetails)
- {
- itemDetailsDictionary.Add(itemDetails.itemCode,itemDetails);
- }
- }
-
- ///
- /// 在背包中找ItemDetails
- ///
- ///
- ///
- public ItemDetails GetItemDetails(int itemCode)
- {
- ItemDetails itemDetails;
-
- if(itemDetailsDictionary.TryGetValue(itemCode,out itemDetails))
- {
- return itemDetails;
- }
- else
- {
- return null;
- }
- }
-
- ///
- /// 吃到物品用的调试
- ///
- ///
- private void DebugPrintInventoryList(List
inventoryLists ) - {
- foreach (var inventoyItem in inventoryLists)
- {
- Debug.Log("Item Description:" + InventoryManager.Instance.GetItemDetails(inventoyItem.itemCode).itemDescription +
- " Item Quantity:" + inventoyItem.itemQuantity);
- }
- }
- }
回到PickUp脚本,我们就可以直接添加了
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class ItemPickUp : MonoBehaviour
- {
- private void OnTriggerEnter2D(Collider2D collision)
- {
- if(collision.TryGetComponent
- (out Item item))
- {
- ItemDetails itemDetails = InventoryManager.Instance.GetItemDetails(item.ItemCode);
-
- if (itemDetails.canBePickUp)
- {
- InventoryManager.Instance.AddItem(InventoryLocation.player, item, collision.gameObject);
- }
- }
- }
- }
一定要注意这个Slot的两个子对象的Raycast Target要取消勾选,不然会导致后面拖拽的时候出现问题。
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class UIInventoryBar : MonoBehaviour
- {
- [SerializeField] private PlayerController2D playerController2D;
- [SerializeField] private Sprite blank16Sprite = null;
- [SerializeField] private UIInventorySlot[] inventorySlots = null;
- public GameObject inventoryBarDragItem;
-
- private RectTransform rectTransform;
-
- private bool isInventoryBarPositionBottom = true; //判断背包条是否在视角下方
-
- public bool IsInventoryBarPositionBottom
- {
- get
- {
- return isInventoryBarPositionBottom;
- }
- set
- {
- isInventoryBarPositionBottom = value;
- }
- }
-
- private void Awake()
- {
- rectTransform = GetComponent
(); - }
-
- private void Update()
- {
- SwitchInventoryBarPosition();
- }
-
- private void OnEnable()
- {
- EventHandler.InventoryUpdateEvent += InventoryUpdate;
- }
-
- private void OnDisable()
- {
- EventHandler.InventoryUpdateEvent -= InventoryUpdate;
- }
-
- private void InventoryUpdate(InventoryLocation inventoryLocation, List
inventoryList ) - {
- if(inventoryLocation == InventoryLocation.player)
- {
- CLearInventorySlots(); //先清空InventroyBar里面所有的InvnetorSlot
- if(inventoryList.Count >0 && inventorySlots.Length > 0) //再遍历一遍inventoryList和inventorySlots重新添加回bar里
- {
- for (int i = 0; i < inventorySlots.Length; i++)
- {
- if (i < inventoryList.Count)
- {
- int itemCode = inventoryList[i].itemCode;
-
- ItemDetails itemDetails = InventoryManager.Instance.GetItemDetails(itemCode);
-
- if (itemDetails != null)
- {
- inventorySlots[i].inventorySlotImage.sprite = itemDetails.itemSprite;
- inventorySlots[i].textMeshProUGUI.text = inventoryList[i].itemQuantity.ToString();
- inventorySlots[i].itemDetails = itemDetails;
- inventorySlots[i].itemQuantity = inventoryList[i].itemQuantity;
- }
- }
- else
- {
- break;
- }
-
- }
- }
- }
- }
-
- private void CLearInventorySlots()
- {
- if(inventorySlots.Length > 0)
- {
- for (int i = 0; i < inventorySlots.Length; i++)
- {
- inventorySlots[i].inventorySlotImage.sprite = blank16Sprite;
- inventorySlots[i].textMeshProUGUI.text = "";
- inventorySlots[i].itemDetails = null;
- inventorySlots[i].itemQuantity = 0;
- }
- }
- }
-
- ///
- /// 切换InventoryBar
- ///
- private void SwitchInventoryBarPosition()
- {
- Vector3 playerViewportPosition = playerController2D.GetPlayerVierportPosition();
-
- if (playerViewportPosition.y > 0.3f && !IsInventoryBarPositionBottom)
- {
- rectTransform.pivot = new Vector2(0.5f, 0f);
- rectTransform.anchorMin = new Vector2(0.5f, 0f);
- rectTransform.anchorMax = new Vector2(0.5f, 0f);
- rectTransform.anchoredPosition = new Vector2(0f, 2.5f);
-
- isInventoryBarPositionBottom = true;
- }
-
- else if(playerViewportPosition.y <= 0.3f && IsInventoryBarPositionBottom)
- {
-
- rectTransform.pivot = new Vector2(0.5f, 1f);
- rectTransform.anchorMin = new Vector2(0.5f, 1f);
- rectTransform.anchorMax = new Vector2(0.5f, 1f);
- rectTransform.anchoredPosition = new Vector2(0f, -2.5f);
-
- isInventoryBarPositionBottom = false;
- }
- }
- }
InventorySlot的脚本如下
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.EventSystems;
- using TMPro;
- using UnityEngine.UI;
- using System;
-
- public class UIInventorySlot : MonoBehaviour,IBeginDragHandler,IDragHandler,IEndDragHandler
- {
- private Camera mainCamera;
- private GameObject draggedItem;
- private Transform itemParent;
-
- public Image inventorySlotHighlight;
- public Image inventorySlotImage;
- public TextMeshProUGUI textMeshProUGUI;
-
- [SerializeField] private UIInventoryBar inventoryBar = null;
- [HideInInspector] public ItemDetails itemDetails;
- [SerializeField] private GameObject itemPrefab = null;
- [HideInInspector] public int itemQuantity;
- [SerializeField] private int slotNumber = 0;
-
- private void Start()
- {
- mainCamera = Camera.main;
- itemParent = GameObject.FindGameObjectWithTag(Tags.ItemsParentTransform).transform;
- }
-
- public void OnBeginDrag(PointerEventData eventData)
- {
- if(itemDetails != null)
- {
- //PlayerController.Instance.DisablePlayerInputAndResetMovement();
-
- draggedItem = Instantiate(inventoryBar.inventoryBarDragItem, inventoryBar.transform);
-
- Image draggedItemImage = draggedItem.GetComponentInChildren
(); - draggedItemImage.sprite = inventorySlotImage.sprite;
- Debug.Log("draggedItemImage.sprite" + draggedItemImage.sprite);
- }
- }
-
- public void OnDrag(PointerEventData eventData)
- {
- if(draggedItem != null)
- {
- draggedItem.transform.position = Input.mousePosition;
- }
- }
-
- public void OnEndDrag(PointerEventData eventData)
- {
- if(draggedItem != null)
- {
- Destroy(draggedItem);
-
- if(eventData.pointerCurrentRaycast.gameObject != null && eventData.pointerCurrentRaycast.gameObject.GetComponent
() != null) - {
- int toSlotNumber = eventData.pointerCurrentRaycast.gameObject.GetComponent
().slotNumber; -
- InventoryManager.Instance.SwapInventoryItems(InventoryLocation.player,slotNumber,toSlotNumber);
- }
- else
- {
- if (itemDetails.canBeDropped)
- {
- DropSelectedItemMousePosition();
- }
- }
-
- //PlayerController.Instance.EnablePlayerInput();
- }
- }
-
- private void DropSelectedItemMousePosition()
- {
- if(itemDetails != null)
- {
- Vector3 worldPosition = mainCamera.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, -mainCamera.transform.position.z));
-
- GameObject itemGameobject = Instantiate(itemPrefab, worldPosition, Quaternion.identity, itemParent);
- Item item = itemGameobject.GetComponent
- ();
- item.ItemCode = itemDetails.itemCode;
-
- InventoryManager.Instance.RemoveItem(InventoryLocation.player, item.ItemCode);
- }
- }
- }
依次添加
对应的SlotNumer
.....
我们需要创建一个名字叫UIInventoryDraggedItem的预制体,用来处理拖拽出来的图像显示
完成以后我们可以把物品放到场景中试玩一下,可以
我们来做最后的交换位置,在我们之前写的InventoryManager加上这个函数即可
- ///
- /// 交换物品顺序
- ///
- ///
- ///
- ///
- public void SwapInventoryItems(InventoryLocation inventoryLocation, int fromSlotNumber, int toSlotNumber)
- {
- if(fromSlotNumber < inventoryLists[(int)inventoryLocation].Count && toSlotNumber < inventoryLists[(int)inventoryLocation].Count &&
- fromSlotNumber != toSlotNumber && toSlotNumber >= 0)
- {
- InventoryItem fromSlotItem = inventoryLists[(int)inventoryLocation][fromSlotNumber];
- InventoryItem toSlotItem = inventoryLists[(int)inventoryLocation][toSlotNumber];
-
- inventoryLists[(int)inventoryLocation][toSlotNumber] = fromSlotItem;
- inventoryLists[(int)inventoryLocation][fromSlotNumber] = toSlotItem;
-
- EventHandler.CallInventoryUpdateEvent(inventoryLocation, inventoryLists[(int)inventoryLocation]);
-
- }
- }
回到OnEndDrag的函数
- public void OnEndDrag(PointerEventData eventData)
- {
- if(draggedItem != null)
- {
- Destroy(draggedItem);
-
- if(eventData.pointerCurrentRaycast.gameObject != null && eventData.pointerCurrentRaycast.gameObject.GetComponent
() != null) - {
- int toSlotNumber = eventData.pointerCurrentRaycast.gameObject.GetComponent
().slotNumber; -
- InventoryManager.Instance.SwapInventoryItems(InventoryLocation.player,slotNumber,toSlotNumber);
- }
- else
- {
- if (itemDetails.canBeDropped)
- {
- DropSelectedItemMousePosition();
- }
- }
-
- //PlayerController.Instance.EnablePlayerInput();
- }
- }
1
由于时间有限(要去恰午饭了)展示就不展示了,总之我们先做到通过这些来实现玩家有关物体UI的效果,下次更新可能是比赛完以后,我先走啦,拜拜。