当前位置:   article > 正文

Unity模拟经营类游戏Demo部分代码及技术总结_unity模拟经营教程

unity模拟经营教程

7月份自己做了一个模拟经营类的游戏Demo,在此总结UI、库存系统、交易系统、游戏循环等相关内容的代码和实现。

实现效果预览

目录

UI

库存系统

交易系统

游戏循环


UI

本项目的UI通过Unity自家的UGUI实现,所有面板的父对象皆为Canvas,各面板为一个实例化的单例对象,其数据由自己进行存储和更新。

面板基础逻辑 

IPanel接口:

  1. interface IPanel
  2. {
  3. public void ShowPanel();
  4. public void HidePanel();
  5. }

以商店面板为例:

(通过给面板添加CanvasGroup组件,并更改其参数实现面板的显隐)

  1. public class ShopPanel : MonoBehaviour, IPanel
  2. {
  3. //单例
  4. private static ShopPanel instance;
  5. public static ShopPanel Instance
  6. {
  7. get
  8. {
  9. return instance;
  10. }
  11. }
  12. //获取商店面板信息
  13. public TMP_Text txtTime;
  14. public TMP_Text txtDays;
  15. public TMP_Text txtShopMoney;
  16. public KnapsackPanel knapsack1Panel;
  17. public KnapsackPanel knapsack2Panel;
  18. public KnapsackPanel knapsack3Panel;
  19. public RolePanel role1Panel;
  20. public RolePanel role2Panel;
  21. public RolePanel role3Panel;
  22. private CanvasGroup canvasGroup;
  23. private int money = 100;
  24. public int Money
  25. {
  26. get { return money; }
  27. set
  28. {
  29. money = value;
  30. txtShopMoney.text = money.ToString();
  31. }
  32. }
  33. public Button btnStorage;
  34. public Button btnCreate;
  35. public static bool storageVisible = false;
  36. public static bool createVisible = false;
  37. private void Awake()
  38. {
  39. //实例化单例
  40. instance = this;
  41. }
  42. // Start is called before the first frame update
  43. void Start()
  44. {
  45. canvasGroup = gameObject.GetComponent<CanvasGroup>();
  46. HidePanel();
  47. btnStorage.onClick.AddListener(() =>
  48. {
  49. //提示面板清空
  50. NoticePanel.Instance.HideNotice();
  51. //仓库按钮按下的逻辑
  52. if (!storageVisible)
  53. {
  54. storageVisible = true;
  55. StoragePanel.Instance.ShowPanel();
  56. createVisible = false;
  57. CreatePanel.Instance.HidePanel();
  58. }
  59. else
  60. {
  61. storageVisible = false;
  62. StoragePanel.Instance.HidePanel();
  63. }
  64. });
  65. btnCreate.onClick.AddListener(() =>
  66. {
  67. //提示面板清空
  68. NoticePanel.Instance.HideNotice();
  69. //制造按钮按下的逻辑
  70. if (!createVisible)
  71. {
  72. createVisible = true;
  73. CreatePanel.Instance.ShowPanel();
  74. storageVisible = false;
  75. StoragePanel.Instance.HidePanel();
  76. }
  77. else
  78. {
  79. createVisible = false;
  80. CreatePanel.Instance.HidePanel();
  81. }
  82. });
  83. txtShopMoney.text = money.ToString();
  84. }
  85. //实现接口IPanel
  86. public void ShowPanel()
  87. {
  88. canvasGroup.alpha = 1;
  89. canvasGroup.interactable = true;
  90. canvasGroup.blocksRaycasts = true;
  91. }
  92. public void HidePanel()
  93. {
  94. canvasGroup.alpha = 0;
  95. canvasGroup.interactable = false;
  96. canvasGroup.blocksRaycasts = false;
  97. }
  98. /// <summary>
  99. /// 花费金钱
  100. /// </summary>
  101. public bool ConsumeMoney(int amount)
  102. {
  103. if (money < amount)
  104. {
  105. NoticePanel.Instance.ShowNotice("金钱不足!");
  106. return false;
  107. }
  108. money -= amount;
  109. txtShopMoney.text = money.ToString();
  110. NoticePanel.Instance.ShowNotice("交易成功!");
  111. return true;
  112. }
  113. /// <summary>
  114. /// 赚取金钱
  115. /// </summary>
  116. public void EarnMoney(int amount)
  117. {
  118. money += amount;
  119. txtShopMoney.text = money.ToString();
  120. }
  121. }

库存系统

库存系统由Inventory、InventoryManager、Slot、ItemUI等类实现。

Inventory类:

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using UnityEngine;
  5. using UnityEngine.UI;
  6. using TMPro;
  7. public class Inventory : MonoBehaviour
  8. {
  9. protected Slot[] slots;
  10. public Slot[] Slots
  11. {
  12. get
  13. {
  14. return slots;
  15. }
  16. set
  17. {
  18. slots = value;
  19. }
  20. }
  21. // Start is called before the first frame update
  22. public virtual void Start()
  23. {
  24. slots = GetComponentsInChildren<Slot>();
  25. }
  26. /// <summary>
  27. /// 通过ID存储物品
  28. /// </summary>
  29. /// <param name="id"></param>
  30. /// <returns></returns>
  31. public bool StoreItem(int id)
  32. {
  33. Item item = InventoryManager.Instance.GetItemID(id);
  34. return StoreItem(item);
  35. }
  36. /// <summary>
  37. /// 是否存储成功
  38. /// </summary>
  39. /// <param name="item"></param>
  40. /// <returns></returns>
  41. public bool StoreItem(Item item)
  42. {
  43. if (item == null)
  44. return false;
  45. if (item.capacity == 1)
  46. {
  47. Slot slot = FindEmptySlot();
  48. if (slot == null)
  49. {
  50. NoticePanel.Instance.ShowNotice("没空的物品槽!");
  51. return false;
  52. }
  53. else
  54. {
  55. slot.CreateItem(item);
  56. }
  57. }
  58. else
  59. {
  60. Slot slot = FindSameIDSlot(item);
  61. if (slot != null)
  62. {
  63. slot.CreateItem(item);
  64. }
  65. else //找新的空物品槽
  66. {
  67. Slot slot2 = FindEmptySlot();
  68. if (slot2 != null)
  69. slot2.CreateItem(item);
  70. else
  71. {
  72. NoticePanel.Instance.ShowNotice("没空的物品槽!");
  73. return false;
  74. }
  75. }
  76. }
  77. return true;
  78. }
  79. /// <summary>
  80. /// 减少物品数量
  81. /// </summary>
  82. /// <param name="targetItem"></param>
  83. /// <param name="total"></param>
  84. /// <param name="amount"></param>
  85. /// <returns></returns>
  86. public bool ReduceItem(Item targetItem, int total, int amount = 1)
  87. {
  88. if (amount > total)
  89. return false;
  90. foreach (Slot slot in slots)
  91. {
  92. if (slot.transform.childCount != 0)
  93. {
  94. GameObject items = slot.transform.GetChild(0).GetComponent<ItemUI>().gameObject;
  95. if (items.GetComponent<ItemUI>().Item.id == targetItem.id)
  96. {
  97. int currentAmount = int.Parse(items.transform.GetChild(0).gameObject.GetComponent<TMP_Text>().text);
  98. if (amount >= currentAmount)
  99. {
  100. amount -= currentAmount;
  101. total -= currentAmount;
  102. items.transform.GetChild(0).gameObject.GetComponent<TMP_Text>().text = 0.ToString();
  103. DestroyImmediate(items);
  104. items = null;
  105. if (total == 0)
  106. {
  107. BuyPanel.CancelBuy();
  108. return true;
  109. }
  110. }
  111. else
  112. {
  113. currentAmount -= amount;
  114. total -= amount;
  115. items.GetComponent<ItemUI>().Amount = currentAmount;
  116. items.transform.GetChild(0).gameObject.GetComponent<TMP_Text>().text = currentAmount.ToString();
  117. amount = 0;
  118. }
  119. }
  120. if (amount == 0)
  121. {
  122. return true;
  123. }
  124. }
  125. }
  126. return false;
  127. }
  128. /// <summary>
  129. /// 找空的物品槽
  130. /// </summary>
  131. /// <returns></returns>
  132. private Slot FindEmptySlot()
  133. {
  134. foreach (Slot slot in slots)
  135. {
  136. if (slot.transform.childCount == 0)
  137. return slot;
  138. }
  139. return null;
  140. }
  141. /// <summary>
  142. /// 找相同ID的物品槽
  143. /// </summary>
  144. /// <returns></returns>
  145. private Slot FindSameIDSlot(Item item)
  146. {
  147. foreach (Slot slot in slots)
  148. {
  149. if (slot.transform.childCount >= 1 && slot.GetItemID() == item.id && slot.IsFull() == false)
  150. return slot;
  151. }
  152. return null;
  153. }
  154. /// <summary>
  155. /// 统计相同ID物品的总数量
  156. /// </summary>
  157. /// <param name="item"></param>
  158. /// <returns></returns>
  159. public int CountSameIDSlot(Item item)
  160. {
  161. int count = 0;
  162. foreach (Slot slot in slots)
  163. {
  164. if (slot.transform.childCount >= 1 && slot.GetItemID() == item.id)
  165. count += int.Parse(slot.transform.GetChild(0).transform.GetChild(0).GetComponent<TMP_Text>().text);
  166. }
  167. return count;
  168. }
  169. /// <summary>
  170. /// 背包整理(空格收纳、物品排序、材料收纳)
  171. /// </summary>
  172. public void InventoryClear()
  173. {
  174. EmptyClear();
  175. Sort();
  176. Combine();
  177. }
  178. /// <summary>
  179. /// 空格收纳
  180. /// </summary>
  181. public void EmptyClear()
  182. {
  183. int itemCount = 0;
  184. foreach(Slot slot in slots)
  185. {
  186. if (slot.transform.childCount != 0)
  187. itemCount++;
  188. }
  189. for (int i = 0; i < slots.Length; i++)
  190. {
  191. if (slots[i].transform.childCount == 0)
  192. {
  193. OneEmptyClear(i);
  194. i = -1;
  195. }
  196. if (i + 1 == itemCount)
  197. return;
  198. }
  199. }
  200. /// <summary>
  201. /// 单个空格收纳
  202. /// </summary>
  203. /// <param name="index"></param>
  204. public void OneEmptyClear(int index)
  205. {
  206. for (int i = index + 1; i < slots.Length; i++)
  207. {
  208. if (slots[i].transform.childCount != 0)
  209. {
  210. GameObject go1 = slots[i].transform.Find("Items(Clone)").gameObject;
  211. go1.transform.SetParent(slots[i - 1].transform);
  212. go1.transform.localPosition = Vector3.zero;
  213. }
  214. }
  215. }
  216. /// <summary>
  217. /// 物品排序
  218. /// </summary>
  219. public void Sort()
  220. {
  221. //整体排序
  222. int i, j;
  223. for (i = 0; i < slots.Length - 1; i++)
  224. {
  225. if (slots[i].transform.childCount == 0)
  226. break;
  227. for (j = i + 1; j < slots.Length; j++)
  228. {
  229. if (slots[j].transform.childCount == 0)
  230. break;
  231. if (slots[i].transform.GetChild(0).GetComponent<ItemUI>().Item.id < slots[j].transform.GetChild(0).GetComponent<ItemUI>().Item.id)
  232. {
  233. Swap(i, j);
  234. }
  235. }
  236. }
  237. int l = 0;
  238. int k = l;
  239. //装备耐久度排序(优先低耐久度)
  240. while (slots[l].transform.childCount != 0 && slots[l].transform.GetChild(0).GetComponent<ItemUI>().Item.type == Item.ItemType.Equipment)
  241. {
  242. while (slots[k].transform.childCount != 0 && slots[k].transform.GetChild(0).GetComponent<ItemUI>().Item.id == slots[l].transform.GetChild(0).GetComponent<ItemUI>().Item.id)
  243. k++;
  244. for (i = l; i < k - 1; i++)
  245. {
  246. for (j = i + 1; j < k; j++)
  247. {
  248. if (slots[i].transform.GetChild(0).GetComponent<ItemUI>().durability > slots[j].transform.GetChild(0).GetComponent<ItemUI>().durability)
  249. {
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/146260?site
推荐阅读
相关标签
  

闽ICP备14008679号