一、重新设置物品栏
1、打开Scripts-Inventory文件新建 ItemSlotData.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
//单独的类
public class ItemSlotData
{
public ItemData itemData;//ItemData对象(收获的物品)
public int quantity;//数量
//构造函数:用于创建 ItemSlotData 实例
public ItemSlotData(ItemData itemData, int quantity)
{
this.itemData = itemData;
this.quantity = quantity;
ValidateQuantity();
}
// 重载的构造函数:用于创建 ItemSlotData 实例,数量默认为1
public ItemSlotData(ItemData itemData)
{
this.itemData = itemData;
quantity = 1;
ValidateQuantity();
}
// 增加数量,默认增加1
public void AddQuantity()
{
AddQuantity(1);
}
//堆叠物品(根据传入的参数增加数量)
public void AddQuantity(int amountToAdd)
{
quantity += amountToAdd;
}
//消耗物品:移除一个物品,将物品槽中的物品数-1
public void Remove()
{
quantity--;
ValidateQuantity();
}
// 检查数量是否小于等于0或物品数据是否为空,如果是则清空物品槽
private void ValidateQuantity()
{
if (quantity <= 0 || itemData == null)
{
Empty();
}
}
//直接清空物品槽,将物品数据和数量重置为默认值
public void Empty()
{
itemData = null;
quantity = 0;
}
}
2、编辑InventoryManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static InventorySlot;
public class InventoryManager : MonoBehaviour
{
public static InventoryManager Instance { get; private set; }
private void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(this);
}
else
{
Instance = this;
}
}
[Header("Tools")]
//将ItemData类型更改为ItemSlots
//重命名tools为toolSlots,重命名equippedTool为equippedToolSlot
//将public更改为 private
private ItemSlotData[] toolSlots = new ItemSlotData[8];
private ItemSlotData equippedToolSlot = null;
[Header("Items")]
//将ItemData类型更改为ItemSlots
//重命名items为itemSlots,equippedItem为equippedItemSlot
private ItemSlotData[] itemSlots = new ItemSlotData[8];
private ItemSlotData equippedItemSlot = null;
public Transform handPoint;
public void InventoryToHand(int slotIndex, InventorySlot.InventoryType inventoryType)
{
/*注释这个方法
if (inventoryType == InventorySlot.InventoryType.Item)
{
ItemData itemToEquip = itemSlots[slotIndex];
itemSlots[slotIndex] = equippedItemSlots;
equippedItemSlots = itemToEquip;
//调用收割作物的方法
RenderHand();
}
else
{
ItemData toolToEquip = toolSlots[slotIndex];
toolSlots[slotIndex] = equippedToolSlot;
equippedToolSlot = toolToEquip;
}
UIManager.Instance.RenderInventory();
*/
}
public void HandToInventory(InventorySlot.InventoryType inventoryType)
{
/*注释这个方法
if (inventoryType == InventorySlot.InventoryType.Item)
{
for (int i = 0; i < itemSlots.Length; i++)
{
if (itemSlots[i] == null)
{
itemSlots[i] = equippedItemSlot;
equippedItemSlot = null;
break;
}
}
RenderHand();
}
else
{
for(int i = 0;i < toolSlots.Length; i++)
{
if(toolSlots[i] == null)
{
toolSlots[i] = equippedToolSlot;
equippedToolSlot = null;
break;
}
}
}
UIManager.Instance.RenderInventory();*/
}
public void RenderHand()
{
if(handPoint.childCount>0)
{
Destroy(handPoint.GetChild(0).gameObject);
}
if(equippedItemSlot != null)
{
//更改调用的方法
Instantiate(GetEquippedSlotItem(InventorySlot.InventoryType.Item).gameModel, handPoint);
}
}
//
public ItemData GetEquippedSlotItem(InventorySlot.InventoryType inventoryType)
{
if(inventoryType == InventorySlot.InventoryType.Item)
{
return equippedItemSlot.itemData;
}
return equippedToolSlot.itemData;
}
//
public ItemSlotData GetEquippedSlot(InventorySlot.InventoryType inventoryType)
{
if(inventoryType == InventorySlot.InventoryType.Item)
{
return equippedItemSlot;
}
return equippedToolSlot;
}
//
public ItemSlotData[] GetInventorySlots(InventorySlot.InventoryType inventoryType)
{
if (inventoryType == InventorySlot.InventoryType.Item)
{
return itemSlots;
}
return toolSlots;
}
}
3、编辑InventorySlot.cs
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class InventorySlot : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler,IPointerClickHandler
{
ItemData itemToDisplay;
//显示数量
int quantity;
public Image itemDisplayImage;
public enum InventoryType
{
Item, Tool
}
public InventoryType inventoryType;
int slotIndex;
//更改参数类型
public void Display(ItemSlotData itemSlot)
{
//增加变量和数量
itemToDisplay = itemSlot.itemData;
quantity = itemSlot.quantity;
if (itemToDisplay != null && itemToDisplay.thumbnail != null)
{
itemDisplayImage.sprite = itemToDisplay.thumbnail;
//删除this.itemToDisplay = itemToDisplay;
itemDisplayImage.gameObject.SetActive(true);
return;
}
itemDisplayImage.gameObject.SetActive(false);
this.itemToDisplay = null;
}
public void AssignIndex(int slotIndex)
{
this.slotIndex = slotIndex;
}
public void OnPointerEnter(PointerEventData eventData)
{
UIManager.Instance.DisplayItemInfo(itemToDisplay);
}
public void OnPointerExit(PointerEventData eventData)
{
UIManager.Instance.DisplayItemInfo(null);
}
public virtual void OnPointerClick(PointerEventData eventData)
{
InventoryManager.Instance.InventoryToHand(slotIndex,inventoryType);
}
}
4、编辑UIManager.cs,
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UIManager : MonoBehaviour, ITimeTracker
{
public static UIManager Instance { get; private set; }
private void Awake()
{
if (Instance != null && Instance != this) { Destroy(this); }
else { Instance = this; }
}
[Header("Startas Bar")]
public Image toolEquipSlotImage;
public Text timeText;
public Text dateText;
[Header("Inventory System")]
public GameObject inventoryPanel;
public HandInventorySlot toolHandSlot;
public InventorySlot[] toolSlots;
public HandInventorySlot itemHandSlot;
public InventorySlot[] itemSlots;
public Text itemNameText;
public Text itemDescriptionText;
private void Start()
{
RenderInventory();
AssignSlotIndex();
TimeManager.Instance.RegisterTracker(this);
}
public void AssignSlotIndex()
{
for (int i = 0; i < toolSlots.Length; i++)
{
toolSlots[i].AssignIndex(i);
itemSlots[i].AssignIndex(i);
}
}
//更改参数
public void RenderInventory(ItemSlotData[] inventoryToolSlot,ItemSlotData[] inventoryItemSlots)
{
//ItemSlotData[] inventoryToolSlots = InventoryManager.Instance.GetInventorySlots(InventorySlot.InventoryType.Tool);
RenderInventoryPanel(inventoryToolSlot, toolSlots);
RenderInventoryPanel(inventoryItemSlots, itemSlots);
//
toolHandSlot.Display(InventoryManager.Instance.GetEquippedSlot(InventorySlot.InventoryType.Tool));
itemHandSlot.Display(InventoryManager.Instance.GetEquippedSlot(InventorySlot.InventoryType.Item));
ItemData equippedTool = InventoryManager.Instance.GetEquippedSlotItem(InventorySlot.InventoryType.Tool);
if (equippedTool != null)
{
toolEquipSlotImage.sprite = equippedTool.thumbnail;
toolEquipSlotImage.gameObject.SetActive(true);
return;
}
toolEquipSlotImage.gameObject.SetActive(false);
}
//更改参数类型
void RenderInventoryPanel(ItemSlotData[] slots, InventorySlot[] uiSlots)
{
for (int i = 0; i < uiSlots.Length; i++)
{
uiSlots[i].Display(slots[i]);
}
}
public void ToggleInventoryPanel()
{
inventoryPanel.SetActive(!inventoryPanel.activeSelf);
RenderInventory();
}
public void DisplayItemInfo(ItemData data)
{
if (data == null)
{
itemNameText.text = "";
itemDescriptionText.text = "";
return;
}
itemNameText.text = data.name;
itemDescriptionText.text = data.description;
}
public void ClockUpdate(GameTimestamp timestamp)
{
int hours = timestamp.hour;
int minutes = timestamp.minute;
string prefix = "AM ";
if (hours > 12)
{
prefix = "PM ";
hours -= 12;
}
timeText.text = prefix + hours + ":" + minutes.ToString("00");
int day = timestamp.day;
string season = timestamp.season.ToString();
string dayOfTheWeek = timestamp.GetDayOfTheWeek().ToString();
dateText.text = season + " " + day + " (" + dayOfTheWeek +")";
}
}
5、编辑InventoryManager.cs,增加一个新的ItemSlotData对象组
public ItemSlotData[] GetInventorySlots(InventorySlot.InventoryType inventoryType)
{
if (inventoryType == InventorySlot.InventoryType.Item)
{
return itemSlots;
}
return toolSlots;
}
6、编辑UIManager.cs,
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UIManager : MonoBehaviour, ITimeTracker
{
public static UIManager Instance { get; private set; }
private void Awake()
{
if (Instance != null && Instance != this) { Destroy(this); }
else { Instance = this; }
}
[Header("Startas Bar")]
public Image toolEquipSlotImage;
public Text timeText;
public Text dateText;
[Header("Inventory System")]
public GameObject inventoryPanel;
public HandInventorySlot toolHandSlot;
public InventorySlot[] toolSlots;
public HandInventorySlot itemHandSlot;
public InventorySlot[] itemSlots;
public Text itemNameText;
public Text itemDescriptionText;
private void Start()
{
RenderInventory();
AssignSlotIndex();
TimeManager.Instance.RegisterTracker(this);
}
public void AssignSlotIndex()
{
for (int i = 0; i < toolSlots.Length; i++)
{
toolSlots[i].AssignIndex(i);
itemSlots[i].AssignIndex(i);
}
}
//删除参数
public void RenderInventory()
{
//新增
ItemSlotData[] inventoryToolSlots = InventoryManager.Instance.GetInventorySlots(InventorySlot.InventoryType.Tool);
ItemSlotData[] inventoryItemSlots = InventoryManager.Instance.GetInventorySlots(InventorySlot.InventoryType.Item);
RenderInventoryPanel(inventoryToolSlots, toolSlots);
RenderInventoryPanel(inventoryItemSlots, itemSlots);
toolHandSlot.Display(InventoryManager.Instance.GetEquippedSlot(InventorySlot.InventoryType.Tool));
itemHandSlot.Display(InventoryManager.Instance.GetEquippedSlot(InventorySlot.InventoryType.Item));
ItemData equippedTool = InventoryManager.Instance.GetEquippedSlotItem(InventorySlot.InventoryType.Tool);
if (equippedTool != null)
{
toolEquipSlotImage.sprite = equippedTool.thumbnail;
toolEquipSlotImage.gameObject.SetActive(true);
return;
}
toolEquipSlotImage.gameObject.SetActive(false);
}
//更改参数类型
void RenderInventoryPanel(ItemSlotData[] slots, InventorySlot[] uiSlots)
{
for (int i = 0; i < uiSlots.Length; i++)
{
uiSlots[i].Display(slots[i]);
}
}
public void ToggleInventoryPanel()
{
inventoryPanel.SetActive(!inventoryPanel.activeSelf);
RenderInventory();
}
public void DisplayItemInfo(ItemData data)
{
if (data == null)
{
itemNameText.text = "";
itemDescriptionText.text = "";
return;
}
itemNameText.text = data.name;
itemDescriptionText.text = data.description;
}
public void ClockUpdate(GameTimestamp timestamp)
{
int hours = timestamp.hour;
int minutes = timestamp.minute;
string prefix = "AM ";
if (hours > 12)
{
prefix = "PM ";
hours -= 12;
}
timeText.text = prefix + hours + ":" + minutes.ToString("00");
int day = timestamp.day;
string season = timestamp.season.ToString();
string dayOfTheWeek = timestamp.GetDayOfTheWeek().ToString();
dateText.text = season + " " + day + " (" + dayOfTheWeek +")";
}
}
7、编辑InventoryManager.cs
public ItemSlotData[] GetInventorySlots(InventorySlot.InventoryType inventoryType)
{
if (inventoryType == InventorySlot.InventoryType.Item)
{
return itemSlots;
}
return toolSlots;
}
//新增方法
public bool SlotEquipped(InventorySlot.InventoryType inventoryType)
{
if (inventoryType == InventorySlot.InventoryType.Item)
{
return equippedItemSlot != null;
}
return equippedToolSlot != null;
}
8、编辑PlayerInteractor.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerInteractor : MonoBehaviour
{
PlayerController playerController;
Land selectLand = null;
InteractableObject selectedInteractable = null;
void Start()
{
playerController = transform.parent.GetComponent<PlayerController>();
}
void Update()
{
RaycastHit hit;
if (Physics.Raycast(transform.position, Vector3.down, out hit, 1))
{
OnInteractableHit(hit);
}
}
void OnInteractableHit(RaycastHit hit)
{
Collider other = hit.collider;
if (other != null && other.CompareTag("Land"))
{
Land land = other.GetComponent<Land>();
if (land != null)
{
SelectLand(land);
return;
}
}
//
if (other.CompareTag("Item"))
{
selectedInteractable = other.GetComponent<InteractableObject>();
return;
}
if(selectedInteractable != null)
{
selectedInteractable = null;
}
if (selectLand != null)
{
selectLand.Select(false);
selectLand = null;
}
}
void SelectLand(Land land)
{
if (land == null)
{
Debug.Log("你没有选择田地!");
return;
}
if (selectLand != null)
{
selectLand.Select(false);
}
selectLand = land;
land.Select(true);
}
public void Interact()
{
//更改条件
if(InventoryManager.Instance.SlotEquipped(InventorySlot.InventoryType.Item))
{
return;
}
if(selectLand != null)
{
selectLand.Interact();
return;
}
Debug.Log("没站在田地里");
}
public void ItemInteract()
{
//更改条件
if (InventoryManager.Instance.SlotEquipped(InventorySlot.InventoryType.Item))
{
InventoryManager.Instance.HandToInventory(InventorySlot.InventoryType.Item);
return;
}
if(selectedInteractable != null)
{
selectedInteractable.Pickup();
}
}
}
9、编辑Land.cs
public void Interact()
{
//更改
ItemData toolSlot = InventoryManager.Instance.GetEquippedSlotItem(InventorySlot.InventoryType.Tool);
if(toolSlot == null)
{
return;
}
EquipmentData equipmentTool = toolSlot as EquipmentData;
if (equipmentTool != null)
{
EquipmentData.ToolType toolType = equipmentTool.toolType;
switch (toolType)
{
case EquipmentData.ToolType.Hoe:
SwitchLandStatus(LandStatus.Farmland); break;
case EquipmentData.ToolType.WateringCan:
SwitchLandStatus(LandStatus.Watered); break;
//铲除作物
case EquipmentData.ToolType.Shovel:
if(cropPlanted != null)
{
Destroy(cropPlanted.gameObject);
}
break;
}
return;
}
SeedData seedTool = toolSlot as SeedData;
if (seedTool != null && landStatus !=LandStatus.Soil && cropPlanted==null)
{
GameObject cropObject =Instantiate(cropPrefab ,transform);
cropObject.transform.position = new Vector3(transform.position.x,0f,transform.position.z);
cropPlanted = cropObject.GetComponent<CropBehaviour>();
cropPlanted.Plant(seedTool);
}
}
10、编辑InventoryManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static InventorySlot;
public class InventoryManager : MonoBehaviour
{
public static InventoryManager Instance { get; private set; }
private void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(this);
}
else
{
Instance = this;
}
}
[Header("Tools")]
//将ItemData类型更改为ItemSlots
//重命名tools为toolSlots,重命名equippedTool为equippedToolSlot
//将public更改为 private
private ItemSlotData[] toolSlots = new ItemSlotData[8];
private ItemSlotData equippedToolSlot = null;
[Header("Items")]
//将ItemData类型更改为ItemSlots
//重命名items为itemSlots,equippedItem为equippedItemSlot
private ItemSlotData[] itemSlots = new ItemSlotData[8];
private ItemSlotData equippedItemSlot = null;
public Transform handPoint;
public void InventoryToHand(int slotIndex, InventorySlot.InventoryType inventoryType)
{
/*注释这个方法
if (inventoryType == InventorySlot.InventoryType.Item)
{
ItemData itemToEquip = itemSlots[slotIndex];
itemSlots[slotIndex] = equippedItemSlots;
equippedItemSlots = itemToEquip;
//调用收割作物的方法
RenderHand();
}
else
{
ItemData toolToEquip = toolSlots[slotIndex];
toolSlots[slotIndex] = equippedToolSlot;
equippedToolSlot = toolToEquip;
}
UIManager.Instance.RenderInventory();
*/
}
public void HandToInventory(InventorySlot.InventoryType inventoryType)
{
/*注释这个方法
if (inventoryType == InventorySlot.InventoryType.Item)
{
for (int i = 0; i < itemSlots.Length; i++)
{
if (itemSlots[i] == null)
{
itemSlots[i] = equippedItemSlot;
equippedItemSlot = null;
break;
}
}
RenderHand();
}
else
{
for(int i = 0;i < toolSlots.Length; i++)
{
if(toolSlots[i] == null)
{
toolSlots[i] = equippedToolSlot;
equippedToolSlot = null;
break;
}
}
}
UIManager.Instance.RenderInventory();*/
}
public void RenderHand()
{
if(handPoint.childCount>0)
{
Destroy(handPoint.GetChild(0).gameObject);
}
if(equippedItemSlot != null)
{
Instantiate(GetEquippedSlotItem(InventorySlot.InventoryType.Item).gameModel, handPoint);
}
}
//新增判断
public bool IsTool(ItemData item)
{
EquipmentData equipment = item as EquipmentData;
if(equipment != null)
{
return true;
}
SeedData seed = item as SeedData;
return seed != null;
}
//组织代码
#region Gets and Checks
//
public ItemData GetEquippedSlotItem(InventorySlot.InventoryType inventoryType)
{
if(inventoryType == InventorySlot.InventoryType.Item)
{
return equippedItemSlot.itemData;
}
return equippedToolSlot.itemData;
}
//
public ItemSlotData GetEquippedSlot(InventorySlot.InventoryType inventoryType)
{
if(inventoryType == InventorySlot.InventoryType.Item)
{
return equippedItemSlot;
}
return equippedToolSlot;
}
//新增
public ItemSlotData[] GetInventorySlots(InventorySlot.InventoryType inventoryType)
{
if (inventoryType == InventorySlot.InventoryType.Item)
{
return itemSlots;
}
return toolSlots;
}
//新增方法
public bool SlotEquipped(InventorySlot.InventoryType inventoryType)
{
if (inventoryType == InventorySlot.InventoryType.Item)
{
return equippedItemSlot != null;
}
return equippedToolSlot != null;
}
#endregion
//新增方法
public void EquipEmptySlot(ItemData item)
{
if(IsTool(item))
{
equippedToolSlot = new ItemSlotData(item);
}
else
{
equippedItemSlot = new ItemSlotData(item);
}
}
}
11、编辑InteractableObject.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InteractableObject : MonoBehaviour
{
public ItemData item;
//增加virtual以便重写
public virtual void Pickup()
{
InventoryManager.Instance.EquipEmptySlot(item);
InventoryManager.Instance.RenderHand();
Destroy(gameObject);
}
}
12、编辑RegrowableHarvestBehaviour.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RegrowableHarvestBehaviour : InteractableObject
{
CropBehaviour parentCrop;
public void SetParent(CropBehaviour parentCrop)
{
this.parentCrop = parentCrop;
}
public override void Pickup()
{
//更改
InventoryManager.Instance.EquipEmptySlot(item);
InventoryManager.Instance.RenderHand();
parentCrop.Regrow();
}
}
二、设置物品数量
1、编辑InventoryManager.cs,序列化
[Header("Tools")]
//每一行增加[SerializeField]
[SerializeField] private ItemSlotData[] toolSlots = new ItemSlotData[8];
[SerializeField] private ItemSlotData equippedToolSlot = null;
[Header("Items")]
[SerializeField] private ItemSlotData[] itemSlots = new ItemSlotData[8];
[SerializeField] private ItemSlotData equippedItemSlot = null;
2、编辑InventoryManager.cs
//新增方法
public void OnValidate()
{
ValidateInventorySlots(equippedToolSlot);
ValidateInventorySlots(equippedItemSlot);
ValidateInventorySlots(itemSlots);
ValidateInventorySlots(toolSlots);
}
//新增方法
void ValidateInventorySlots(ItemSlotData slot)
{
if(slot.itemData != null &&slot.quantity == 0)
{
slot.quantity = 1;
}
}
//新增方法
void ValidateInventorySlots(ItemSlotData[] array)
{
foreach(ItemSlotData slot in array)
{
ValidateInventorySlots(slot);
}
}
3、赋值
选中Manager,找到Inspector上的InventoryManager.cs组件,赋值
4、添加物品数量文本
(1) 以HandSlot为父物体,UI-Text,重命名为QuantityText。
(2) 设置它的Rect Transform和Text
(3) 复制QuantityText,设置它的Rect Transform和Text
(4) 同样的方法,添加InventorySlot的子物体(文本)
(5) Apply预制体InventorySlot的更改
(6) 同样的方法,添加HandSlot的子物体(文本)
(7) 编辑InventorySlot.cs
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class InventorySlot : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler,IPointerClickHandler
{
ItemData itemToDisplay;
int quantity;
//数量文本
public Image itemDisplayImage;
public Text quantityText;
public enum InventoryType
{
Item, Tool
}
public InventoryType inventoryType;
int slotIndex;
public void Display(ItemSlotData itemSlot)
{
itemToDisplay = itemSlot.itemData;
quantity = itemSlot.quantity;
//显示数量文本
quantityText.text = "";
if (itemToDisplay != null && itemToDisplay.thumbnail != null)
{
itemDisplayImage.sprite = itemToDisplay.thumbnail;
//显示数量文本
if (quantity > 1)
{
quantityText.text = quantity.ToString();
}
itemDisplayImage.gameObject.SetActive(true);
return;
}
itemDisplayImage.gameObject.SetActive(false);
this.itemToDisplay = null;
}
public void AssignIndex(int slotIndex)
{
this.slotIndex = slotIndex;
}
public void OnPointerEnter(PointerEventData eventData)
{
UIManager.Instance.DisplayItemInfo(itemToDisplay);
}
public void OnPointerExit(PointerEventData eventData)
{
UIManager.Instance.DisplayItemInfo(null);
}
public virtual void OnPointerClick(PointerEventData eventData)
{
InventoryManager.Instance.InventoryToHand(slotIndex,inventoryType);
}
}
(8) 赋值(预制体InventorySlot中)
(9) 赋值
三、
1、编辑ItemSlotData.cs
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
[System.Serializable]
public class ItemSlotData
{
public ItemData itemData;
public int quantity;
public ItemSlotData(ItemData itemData, int quantity)
{
this.itemData = itemData;
this.quantity = quantity;
ValidateQuantity();
}
public ItemSlotData(ItemData itemData)
{
this.itemData = itemData;
quantity = 1;
ValidateQuantity();
}
//复制ItemSlotData对象
public ItemSlotData(ItemSlotData slotToClone)
{
itemData = slotToClone.itemData;
quantity = slotToClone.quantity;
}
public void AddQuantity()
{
AddQuantity(1);
}
public void AddQuantity(int amountToAdd)
{
quantity += amountToAdd;
}
public void Remove()
{
quantity--;
ValidateQuantity();
}
//新增方法
public bool Stackable(ItemSlotData slotToCompare)
{
return slotToCompare.itemData == itemData;
}
private void ValidateQuantity()
{
if (quantity <= 0 || itemData == null)
{
Empty();
}
}
public void Empty()
{
itemData = null;
quantity = 0;
}
//新增方法
public bool IsEmpty()
{
return itemData == null;
}
}
2、编辑InventoryManager.cs(这里有一个报错)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static InventorySlot;
public class InventoryManager : MonoBehaviour
{
public static InventoryManager Instance { get; private set; }
private void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(this);
}
else
{
Instance = this;
}
}
[Header("Tools")]
[SerializeField] private ItemSlotData[] toolSlots = new ItemSlotData[8];
[SerializeField] private ItemSlotData equippedToolSlot = null;
[Header("Items")]
[SerializeField] private ItemSlotData[] itemSlots = new ItemSlotData[8];
[SerializeField] private ItemSlotData equippedItemSlot = null;
public Transform handPoint;
public void InventoryToHand(int slotIndex, InventorySlot.InventoryType inventoryType)
{
//临时变量
ItemSlotData handToEquip = equippedToolSlot;
ItemSlotData[] inventoryToAlter = toolSlots;
//装备物品槽
if(inventoryType == InventorySlot.InventoryType.Item)
{
handToEquip = equippedItemSlot;
inventoryToAlter = itemSlots;
}
//检查是否可以堆叠
if (handToEquip.Stackable(inventoryToAlter[slotIndex]))
{
ItemSlotData slotToAlter = inventoryToAlter[slotIndex];
handToEquip.AddQuantity(slotToAlter.quantity);
slotToAlter.Empty();
}
else
{
ItemSlotData slotToEquip = new ItemSlotData(inventoryToAlter[slotIndex]);
inventoryToAlter[slotIndex] = new ItemSlotData(handToEquip);
EquipEmptySlot(slotToEquip);
}
if(inventoryType == InventorySlot.InventoryType.Item)
{
RenderHand();
}
//渲染
UIManager.Instance.RenderInventory();
}
public void HandToInventory(InventorySlot.InventoryType inventoryType)
{
//临时变量
ItemSlotData handSlot = equippedToolSlot;
ItemSlotData[] inventoryToAlter = toolSlots;
//装备
if(inventoryType == InventorySlot.InventoryType.Item)
{
handSlot = equippedItemSlot;
inventoryToAlter = itemSlots;
}
if(!StackItemToInventory(handSlot, inventoryToAlter))
{
for(int i = 0; i < inventoryToAlter.Length; i++)
{
if(inventoryToAlter[i] == null)
{
inventoryToAlter[i] = new ItemSlotData(handSlot);
handSlot.Empty();
break;
}
}
}
if(inventoryType == InventorySlot.InventoryType.Item)
{
RenderHand();
}
UIManager.Instance.RenderInventory();
}
//新建方法
public bool StackItemToInventory(ItemSlotData itemSlot, ItemSlotData[] inventoryArray)
{
for(int i = 0; i < inventoryArray.Length; i++)
{
if (inventoryArray[i].Stackable(itemSlot))
{
inventoryArray[i].AddQuantity(itemSlot.quantity);
itemSlot.Empty();
return true;
}
}
return false;
}
public void RenderHand()
{
if(handPoint.childCount>0)
{
Destroy(handPoint.GetChild(0).gameObject);
}
//更改条件
if(SlotEquipped(InventorySlot.InventoryType.Item))
{
Instantiate(GetEquippedSlotItem(InventorySlot.InventoryType.Item).gameModel, handPoint);
}
}
#region Gets and Checks
public ItemData GetEquippedSlotItem(InventorySlot.InventoryType inventoryType)
{
if(inventoryType == InventorySlot.InventoryType.Item)
{
return equippedItemSlot.itemData;
}
return equippedToolSlot.itemData;
}
//
public ItemSlotData GetEquippedSlot(InventorySlot.InventoryType inventoryType)
{
if(inventoryType == InventorySlot.InventoryType.Item)
{
return equippedItemSlot;
}
return equippedToolSlot;
}
public ItemSlotData[] GetInventorySlots(InventorySlot.InventoryType inventoryType)
{
if (inventoryType == InventorySlot.InventoryType.Item)
{
return itemSlots;
}
return toolSlots;
}
public bool SlotEquipped(InventorySlot.InventoryType inventoryType)
{
if (inventoryType == InventorySlot.InventoryType.Item)
{
//更改
return !equippedItemSlot.IsEmpty();
}
//更改
return !equippedToolSlot.IsEmpty();
}
public bool IsTool(ItemData item)
{
EquipmentData equipment = item as EquipmentData;
if (equipment != null)
{
return true;
}
SeedData seed = item as SeedData;
return seed != null;
}
#endregion
public void EquipEmptySlot(ItemData item)
{
if(IsTool(item))
{
equippedToolSlot = new ItemSlotData(item);
}
else
{
equippedItemSlot = new ItemSlotData(item);
}
}
//组织
#region Inventory Slot validation
public void OnValidate()
{
ValidateInventorySlots(equippedToolSlot);
ValidateInventorySlots(equippedItemSlot);
ValidateInventorySlots(itemSlots);
ValidateInventorySlots(toolSlots);
}
void ValidateInventorySlots(ItemSlotData slot)
{
if(slot.itemData != null &&slot.quantity == 0)
{
slot.quantity = 1;
}
}
void ValidateInventorySlots(ItemSlotData[] array)
{
foreach(ItemSlotData slot in array)
{
ValidateInventorySlots(slot);
}
}
#endregion
}
3、编辑InventoryManager.cs,处理报错
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static InventorySlot;
public class InventoryManager : MonoBehaviour
{
public static InventoryManager Instance { get; private set; }
private void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(this);
}
else
{
Instance = this;
}
}
[Header("Tools")]
[SerializeField] private ItemSlotData[] toolSlots = new ItemSlotData[8];
[SerializeField] private ItemSlotData equippedToolSlot = null;
[Header("Items")]
[SerializeField] private ItemSlotData[] itemSlots = new ItemSlotData[8];
[SerializeField] private ItemSlotData equippedItemSlot = null;
public Transform handPoint;
public void InventoryToHand(int slotIndex, InventorySlot.InventoryType inventoryType)
{
ItemSlotData handToEquip = equippedToolSlot;
ItemSlotData[] inventoryToAlter = toolSlots;
if (inventoryType == InventorySlot.InventoryType.Item)
{
handToEquip = equippedItemSlot;
inventoryToAlter = itemSlots;
}
if (handToEquip.Stackable(inventoryToAlter[slotIndex]))
{
ItemSlotData slotToAlter = inventoryToAlter[slotIndex];
handToEquip.AddQuantity(slotToAlter.quantity);
slotToAlter.Empty();
}
else
{
ItemSlotData slotToEquip = new ItemSlotData(inventoryToAlter[slotIndex]);
inventoryToAlter[slotIndex] = new ItemSlotData(handToEquip);
EquipHandSlot(slotToEquip);
}
if (inventoryType == InventorySlot.InventoryType.Item)
{
RenderHand();
}
UIManager.Instance.RenderInventory();
}
public void HandToInventory(InventorySlot.InventoryType inventoryType)
{
ItemSlotData handSlot = equippedToolSlot;
ItemSlotData[] inventoryToAlter = toolSlots;
if (inventoryType == InventorySlot.InventoryType.Item)
{
handSlot = equippedItemSlot;
inventoryToAlter = itemSlots;
}
if (!StackItemToInventory(handSlot, inventoryToAlter))
{
for (int i = 0; i < inventoryToAlter.Length; i++)
{
if (inventoryToAlter[i].IsEmpty())
{
inventoryToAlter[i] = new ItemSlotData(handSlot);
handSlot.Empty();
break;
}
}
}
if (inventoryType == InventorySlot.InventoryType.Item)
{
RenderHand();
}
UIManager.Instance.RenderInventory();
}
public bool StackItemToInventory(ItemSlotData itemSlot, ItemSlotData[] inventoryArray)
{
for (int i = 0; i < inventoryArray.Length; i++)
{
if (inventoryArray[i].Stackable(itemSlot))
{
inventoryArray[i].AddQuantity(itemSlot.quantity);
itemSlot.Empty();
return true;
}
}
return false;
}
public void RenderHand()
{
if (handPoint.childCount > 0)
{
Destroy(handPoint.GetChild(0).gameObject);
}
if (SlotEquipped(InventorySlot.InventoryType.Item))
{
Instantiate(GetEquippedSlotItem(InventorySlot.InventoryType.Item).gameModel, handPoint);
}
}
#region Gets and Checks
public ItemData GetEquippedSlotItem(InventorySlot.InventoryType inventoryType)
{
if (inventoryType == InventorySlot.InventoryType.Item)
{
return equippedItemSlot.itemData;
}
return equippedToolSlot.itemData;
}
public ItemSlotData GetEquippedSlot(InventorySlot.InventoryType inventoryType)
{
if (inventoryType == InventorySlot.InventoryType.Item)
{
return equippedItemSlot;
}
return equippedToolSlot;
}
public ItemSlotData[] GetInventorySlots(InventorySlot.InventoryType inventoryType)
{
if (inventoryType == InventorySlot.InventoryType.Item)
{
return itemSlots;
}
return toolSlots;
}
public bool SlotEquipped(InventorySlot.InventoryType inventoryType)
{
if (inventoryType == InventorySlot.InventoryType.Item)
{
return !equippedItemSlot.IsEmpty();
}
return !equippedToolSlot.IsEmpty();
}
public bool IsTool(ItemData item)
{
EquipmentData equipment = item as EquipmentData;
if (equipment != null)
{
return true;
}
SeedData seed = item as SeedData;
return seed != null;
}
#endregion
public void EquipHandSlot(ItemData item)
{
if (IsTool(item))
{
equippedToolSlot = new ItemSlotData(item);
}
else
{
equippedItemSlot = new ItemSlotData(item);
}
}
//新建方法,重载
public void EquipHandSlot(ItemSlotData itemSlot)
{
ItemData item = itemSlot.itemData;
if (IsTool(item))
{
equippedToolSlot = new ItemSlotData(itemSlot);
}
else
{
equippedItemSlot = new ItemSlotData(itemSlot);
}
}
#region Inventory Slot validation
public void OnValidate()
{
ValidateInventorySlots(equippedToolSlot);
ValidateInventorySlots(equippedItemSlot);
ValidateInventorySlots(itemSlots);
ValidateInventorySlots(toolSlots);
}
void ValidateInventorySlots(ItemSlotData slot)
{
if (slot.itemData != null && slot.quantity == 0)
{
slot.quantity = 1;
}
}
void ValidateInventorySlots(ItemSlotData[] array)
{
foreach (ItemSlotData slot in array)
{
ValidateInventorySlots(slot);
}
}
#endregion
}
4、编辑InventoryManager.cs,
//新建方法
public void ConsumeItem(ItemSlotData itemSlot)
{
if (itemSlot.IsEmpty())
{
Debug.LogError("没有种子了");
return;
}
itemSlot.Remove();
RenderHand();
UIManager.Instance.RenderInventory();
}
5、编辑Land.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Land : MonoBehaviour, ITimeTracker
{
public enum LandStatus { Soil, Farmland, Watered }
public LandStatus landStatus;
public Material soilMat, farmlandMat, wateredMat;
new Renderer renderer;
public GameObject select;
GameTimestamp timeWatered;
[Header("Crops")]
public GameObject cropPrefab;
CropBehaviour cropPlanted = null;
void Start()
{
renderer = GetComponent<Renderer>();
SwitchLandStatus(LandStatus.Soil);
//select.SetActive(false);
Select(false);
TimeManager.Instance.RegisterTracker(this);
}
public void SwitchLandStatus(LandStatus statusToSwitch)
{
landStatus = statusToSwitch;
Material materialToSwitch = soilMat;
switch (statusToSwitch)
{
case LandStatus.Soil: materialToSwitch = soilMat; break;
case LandStatus.Farmland: materialToSwitch = farmlandMat; break;
case LandStatus.Watered:
materialToSwitch = wateredMat;
timeWatered = TimeManager.Instance.GetGameTimestamp();
break;
}
renderer.material = materialToSwitch;
}
public void Select(bool toggle)
{
select.SetActive(toggle);
}
public void Interact()
{
ItemData toolSlot = InventoryManager.Instance.GetEquippedSlotItem(InventorySlot.InventoryType.Tool);
//更改条件
if(!InventoryManager.Instance.SlotEquipped(InventorySlot.InventoryType.Tool))
{
return;
}
EquipmentData equipmentTool = toolSlot as EquipmentData;
if (equipmentTool != null)
{
EquipmentData.ToolType toolType = equipmentTool.toolType;
switch (toolType)
{
case EquipmentData.ToolType.Hoe:
SwitchLandStatus(LandStatus.Farmland); break;
case EquipmentData.ToolType.WateringCan:
SwitchLandStatus(LandStatus.Watered); break;
case EquipmentData.ToolType.Shovel:
if(cropPlanted != null)
{
Destroy(cropPlanted.gameObject);
}
break;
}
return;
}
SeedData seedTool = toolSlot as SeedData;
if (seedTool != null && landStatus !=LandStatus.Soil && cropPlanted==null)
{
GameObject cropObject =Instantiate(cropPrefab ,transform);
cropObject.transform.position = new Vector3(transform.position.x,0f,transform.position.z);
cropPlanted = cropObject.GetComponent<CropBehaviour>();
cropPlanted.Plant(seedTool);
//被使用后消失
InventoryManager.Instance.ConsumeItem(InventoryManager.Instance.GetEquippedSlot(InventorySlot.InventoryType.Tool));
}
}
public void ClockUpdate(GameTimestamp timestamp)
{
if (landStatus == LandStatus.Watered)
{
int hoursElapsed = GameTimestamp.CompareTimestamp(timeWatered, timestamp);
if(cropPlanted != null)
{
cropPlanted.Grow();
}
if (hoursElapsed > 24)
{
SwitchLandStatus(LandStatus.Farmland);
}
}
if(landStatus != LandStatus.Watered && cropPlanted != null)
{
if(cropPlanted.cropState != CropBehaviour.CropState.Seed)
{
cropPlanted.Wilter();
}
}
}
}
6、编辑UIManager.cs,添加StatusBar下显示数量的文本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UIManager : MonoBehaviour, ITimeTracker
{
public static UIManager Instance { get; private set; }
private void Awake()
{
if (Instance != null && Instance != this) { Destroy(this); }
else { Instance = this; }
}
[Header("Startas Bar")]
public Image toolEquipSlotImage;
public Text toolQuantityText;
public Text timeText;
public Text dateText;
[Header("Inventory System")]
public GameObject inventoryPanel;
public HandInventorySlot toolHandSlot;
public InventorySlot[] toolSlots;
public HandInventorySlot itemHandSlot;
public InventorySlot[] itemSlots;
public Text itemNameText;
public Text itemDescriptionText;
private void Start()
{
RenderInventory();
AssignSlotIndex();
TimeManager.Instance.RegisterTracker(this);
}
public void AssignSlotIndex()
{
for (int i = 0; i < toolSlots.Length; i++)
{
toolSlots[i].AssignIndex(i);
itemSlots[i].AssignIndex(i);
}
}
public void RenderInventory()
{
ItemSlotData[] inventoryToolSlots = InventoryManager.Instance.GetInventorySlots(InventorySlot.InventoryType.Tool);
ItemSlotData[] inventoryItemSlots = InventoryManager.Instance.GetInventorySlots(InventorySlot.InventoryType.Item);
RenderInventoryPanel(inventoryToolSlots, toolSlots);
RenderInventoryPanel(inventoryItemSlots, itemSlots);
toolHandSlot.Display(InventoryManager.Instance.GetEquippedSlot(InventorySlot.InventoryType.Tool));
itemHandSlot.Display(InventoryManager.Instance.GetEquippedSlot(InventorySlot.InventoryType.Item));
ItemData equippedTool = InventoryManager.Instance.GetEquippedSlotItem(InventorySlot.InventoryType.Tool);
//数量文本
toolQuantityText.text = "";
if (equippedTool != null)
{
toolEquipSlotImage.sprite = equippedTool.thumbnail;
toolEquipSlotImage.gameObject.SetActive(true);
//数量文本
int quantity = InventoryManager.Instance.GetEquippedSlot(InventorySlot.InventoryType.Tool).quantity;
if (quantity > 1)
{
toolQuantityText.text = quantity.ToString();
}
return;
}
toolEquipSlotImage.gameObject.SetActive(false);
}
void RenderInventoryPanel(ItemSlotData[] slots, InventorySlot[] uiSlots)
{
for (int i = 0; i < uiSlots.Length; i++)
{
uiSlots[i].Display(slots[i]);
}
}
public void ToggleInventoryPanel()
{
inventoryPanel.SetActive(!inventoryPanel.activeSelf);
RenderInventory();
}
public void DisplayItemInfo(ItemData data)
{
if (data == null)
{
itemNameText.text = "";
itemDescriptionText.text = "";
return;
}
itemNameText.text = data.name;
itemDescriptionText.text = data.description;
}
public void ClockUpdate(GameTimestamp timestamp)
{
int hours = timestamp.hour;
int minutes = timestamp.minute;
string prefix = "AM ";
if (hours > 12)
{
prefix = "PM ";
hours -= 12;
}
timeText.text = prefix + hours + ":" + minutes.ToString("00");
int day = timestamp.day;
string season = timestamp.season.ToString();
string dayOfTheWeek = timestamp.GetDayOfTheWeek().ToString();
dateText.text = season + " " + day + " (" + dayOfTheWeek + ")";
}
}
7、赋值