当前位置: 首页 > news >正文

四川省建设人才网站2018手机网站建设网站

四川省建设人才网站2018,手机网站建设网站,深圳设计周2021时间,私人网站建设方案书框架栏目本人能力有限#xff0c;如有不足还请斧正#xff0c;理论分析链接如下#xff1a; Unity2D初级背包设计前篇 理论分析-CSDN博客 目录 1.M层#xff1a;数据存储 物品 仓库容器 加载方式 2.M层#xff1a;逻辑撰写 InventoryManager 仓库的管理 SlotData 物品的增…          本人能力有限如有不足还请斧正理论分析链接如下         Unity2D初级背包设计前篇 理论分析-CSDN博客 目录 1.M层数据存储   物品 仓库容器 加载方式 2.M层逻辑撰写 InventoryManager 仓库的管理 SlotData 物品的增删查改*(逻辑层) 3.V层搭建UI 1.SlotUI 将物品绘制到格子上 2.三个类 BarUI工具栏的选中与数字切换 BarSoltUI格子高亮  BagUI 将格子数据绘制到界面上 4.C层玩家控制类 ItemMoveHandler 物品的增删查改*表现层 Plyaer 拾取与丢弃 1.M层数据存储   物品 一个2D的物品必不可少的就是类型图标物体这个指Gameobjcet和其名字堆叠数量 拓展思路稀有度,价值耐久,描述重量 using UnityEngine; /// summary /// 不同的物品可以有不同的类型 以用作其他逻辑的判断 /// 举例食物可以吃但通常不能打人 /// 武器通常不能吃但可以打人 /// /summary public enum ItemType{a,b,c,d } /// summary /// /// /summary [CreateAssetMenu()] public class ItemData:ScriptableObject {public ItemType itmeType;public Sprite itemSprite;public GameObject itemPrefab;public int maxCount 1;//最大堆叠数量默认1 }另外可能需要一个外部类去定义其属性比如可拾取的不可拾取的 这个的作用体现在玩家拾取方面需要提前知道一下 public class Pickable : MonoBehaviour {public ItemType thisItemType; }so对象举例 仓库容器 先认识一个单词Inventory仓库库存 在本文中特指背包类 之所以要对Inventory写为So是因为游戏中可能存在许多的仓库在玩家手中叫做背包物品栏在NPC手中就可能叫做商店锻造了因此 using System.Collections.Generic; using UnityEngine; [CreateAssetMenu()] public class InventoryData :ScriptableObject{//TODO :拓展 仓库名称最大容量,自动扩容public ListSlotData slotList; }创建两个 可以看到其容量是我们自定义的也就是写死的没有自动扩容功能 因此在今后的拓展之中可以优化 加载方式 2.M层逻辑撰写 InventoryManager 仓库的管理 我们需要一个仓库管理器去管理所有的背包所以用到了InventoryData 对象 另外管理所有物品的时候也应需要一个容器去预加载所以用到了字典 可以先不看这一行我们需要为外部提供提供向背包添加物品的方法所以用到了单例模式 using System.Collections.Generic; using UnityEngine;public class InventoryManager : MonoBehaviour {private static InventoryManager instance;public static InventoryManager Instance instance;public InventoryData BagInventory;public InventoryData ToolBarInventory;public DictionaryItemType, ItemData itemDataDict new DictionaryItemType, ItemData();private void Awake() {if (instance null) {instance this;}else {Destroy(this);}InitInventoryData();}private void Start() {}/// summary/// 加载本地物品和已有的背包数据/// /summaryprivate void InitInventoryData() {ItemData[] itemDatas Resources.LoadAllItemData(Itmes);foreach (var singleItem in itemDatas) {itemDataDict.Add(singleItem.itmeType, singleItem);}BagInventory Resources.LoadInventoryData(Inventorys/MyInventory);ToolBarInventory Resources.LoadInventoryData(Inventorys/ToolBarInventory);}/// summary/// 通过指定的物品类型从字典中获取物品数据/// /summary/// param nametype物品类型/param/// returns如果找到则返回物品数据否则返回null/returnsprivate ItemData GetItem(ItemType type) {if (itemDataDict.TryGetValue(type, out var item))return item;else {Debug.LogError(未找到指定物品);return null;}}/// summary/// 向背包中添加物品/// /summary/// param nameitemType要添加的物品类型/parampublic void AddItemToInventory(ItemType itemType) {ItemData aItem GetItem(itemType);// 情况1字典中有该物品且格子未满 如果格子满了将会走情况2foreach (var slot in BagInventory.slotList) {if (slot.item aItem slot.CanAddItem()) {slot.Add();return;}}// 情况2格子为空添加物品foreach (var slot in BagInventory.slotList) {if (slot.count 0) {slot.AddItem(aItem);return;}}// 情况3背包已满Debug.LogWarning($未能成功添加物品 {aItem.name} 因为 {BagInventory.name} 已经满了);} }SlotData 物品的增删查改*(逻辑层) 这个类将目光聚焦于背包中的格子因为它才是背包的最小单位 格子需要持有物品类并且有一个当前数量的变量 每次修改格子物品信息的时候需要给到其通知(也就是M层-----V层这一步)所以需要做发布者发布一个委托让V层去监听   using System; using System.Collections; using System.Collections.Generic; using UnityEngine;[Serializable] public class SlotData {public ItemData item;public int currentCount 0; // 物品数量private Action OnChange;#region 增Add// 添加物品到槽位public void Add(int numToAdd 1) {this.currentCount numToAdd;OnChange?.Invoke();}// 设置槽位的物品和数量public void AddItem(ItemData item, int count 1) {this.item item;this.currentCount count;OnChange?.Invoke();}#endregion#region 删Remove// 减少槽位中的物品数量public void Reduce(int numToReduce 1) {currentCount - numToReduce;if (currentCount 0) {Clear();}else {OnChange?.Invoke();}}// 清空槽位public void Clear() {item null;currentCount 0;OnChange?.Invoke();}#endregion#region 查Check// 检查槽位是否为空public bool IsEmpty() {return currentCount 0;}// 检查槽位是否可以添加物品public bool CanAddItem() {return currentCount item.maxCount;}// 获取槽位的空余空间public int GetFreeSpace() {return item.maxCount - currentCount;}#endregion#region 改Update// 移动槽位数据public void MoveSlot(SlotData data) {this.item data.item;this.currentCount data.currentCount;OnChange?.Invoke();}// 添加监听器public void AddListener(Action OnChange) {this.OnChange OnChange;}#endregion }就这么点东西至此M层就算是写完辣 3.V层搭建UI 1.SlotUI 将物品绘制到格子上 自然其应持有SlotData类,并订阅其发布的委托回调函数就是ChangeUI方法 SetData实现的就是C----M层GetData是V----C层 using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI;public class SlotUI : MonoBehaviour,IPointerClickHandler {protected SlotData slotData;protected Image icon;protected TextMeshProUGUI num;private void Start() {icon transform.Find(icon).GetComponentImage();num transform.Find(num).GetComponentTextMeshProUGUI();}public SlotData GetData(){ return slotData;}/// summary/// 为该脚本上的对象赋值一个SlotData/// /summarypublic void SetData(SlotData slotData) { this.slotData slotData;//事件监听 - 订阅者slotData.AddListener(UpdateUI2Slot);UpdateUI2Slot();}/ summary/ 监听对象/ /summary//public void ChangeUI(){// UpdateUI2Slot();//}private void UpdateUI2Slot(){if (slotDatanull || slotData.item null || slotData.currentCount 0) {icon.enabled false;num.enabled false;}else {icon.enabled true;num.enabled true;icon.sprite slotData.item.itemSprite;num.text slotData.currentCount.ToString();}}public void OnPointerClick(PointerEventData eventData) {Debug.Log(发生了点击);ItemMoveHandler.Instance.OnSlotClick(this);} } 选中后将物品依附到鼠标上面  2.三个类 BarUI工具栏的选中与数字切换 using System.Collections.Generic; using UnityEngine;public class BarUI : MonoBehaviour {//工具栏ui列表 先给这个列表对应好ui格子之后将数据列表粘贴到ui列表中 并更新UI即完成可视化[SerializeField]private ListBarSlotUI barSlotUIList;[SerializeField] private GameObject ContentList;[SerializeField] private BarSlotUI curSelectBarSlotUI;//当前选中的工具栏的格子// Start is called once before the first execution of Update after the MonoBehaviour is createdvoid Start(){barSlotUIList new ListBarSlotUI();ContentList transform.Find(Bar/ContentList).gameObject;InitSlotUI();}private void Update() {SelectBarSlot();}/// summary/// 默认curSelectBarSlotUI为空所以首次不会进入第二个if/// 当第二次选中格子时curSelectBarSlotUI指向第一个格子所以不为空就高亮第一个格子/// /summarypublic void SelectBarSlot(){for (int i (int)KeyCode.Alpha1; i (int)KeyCode.Alpha9 1; i) {if (Input.GetKeyDown((KeyCode)i)) {if (curSelectBarSlotUI ! null) {curSelectBarSlotUI.BarSlotLight();}int index i - (int)KeyCode.Alpha1;curSelectBarSlotUI barSlotUIList[index];curSelectBarSlotUI.BarSlotDark();}}}public void InitSlotUI() {if (ContentList ! null) {foreach (BarSlotUI barSlotUI in ContentList.GetComponentsInChildrenSlotUI()) {barSlotUIList.Add(barSlotUI);}}UpdataUI();}public void UpdataUI() {for (int i 0; i InventoryManager.Instance.ToolBarInventory.slotList.Count; i) {barSlotUIList[i].SetData(InventoryManager.Instance.ToolBarInventory.slotList[i]);}}}BarSoltUI格子高亮  using TMPro; using UnityEngine; using UnityEngine.UI;public class BarSlotUI : SlotUI {[SerializeField] private Sprite slotLight;[SerializeField] private Sprite slotDark;[SerializeField]private Image thisImage;// Start is called once before the first execution of Update after the MonoBehaviour is createdvoid Start(){InitBar_Slot();}public void InitBar_Slot(){this.icon transform.Find(Bar_icon).GetComponentImage();this.num transform.Find(Bar_num).GetComponentTextMeshProUGUI();thisImage GetComponentImage();slotLight Resources.LoadSprite(SlotUI/slotLight);slotDark Resources.LoadSprite(SlotUI/slotDark);}public void BarSlotLight(){thisImage.sprite slotLight;}public void BarSlotDark() {thisImage.sprite slotDark;} }BagUI 将格子数据绘制到界面上 using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;public class BagUI : MonoBehaviour {[SerializeField] private Button close;[SerializeField] private GameObject BG;[SerializeField] private GameObject slotGrid;[SerializeField] private ListSlotUI soltuiList new ListSlotUI();// Start is called once before the first execution of Update after the MonoBehaviour is createdvoid Start() {InitElement();InitSlotUI();}// Update is called once per framevoid Update() {ColseBag();}public void InitElement() {BG transform.Find(BG).gameObject;close transform.Find(BG/BgElement/Close).GetComponentButton();slotGrid transform.Find(BG/SlotGrid).gameObject;if (close ! null) {close.onClick.AddListener(() {if (BG ! null)BG.SetActive(!BG.activeSelf);else {Debug.LogWarning(没找到BG对象);return;}});}elseDebug.LogWarning(没有加载到close按钮);}public void UpdataUI() {for (int i 0; i InventoryManager.Instance.BagInventory.slotList.Count; i) {soltuiList[i].SetData(InventoryManager.Instance.BagInventory.slotList[i]);}}public void InitSlotUI() {if (slotGrid ! null) {foreach (SlotUI slotUi in slotGrid.GetComponentsInChildrenSlotUI()) {soltuiList.Add(slotUi);}}UpdataUI();}public void ColseBag() {if (Input.GetKeyDown(KeyCode.Tab))BG.SetActive(!BG.activeSelf);} }4.C层玩家控制类 ItemMoveHandler 物品的增删查改*表现层 这个类其实应该好好讲一讲但是笔者写了一个多小时雀氏有点累了反正都是一些常见的逻辑 所以用ai给到注释如果前面的代码都理解了那么这里一点也不难 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI;public class ItemMoveHandler : MonoBehaviour {// 单例模式的实例public static ItemMoveHandler Instance {get; private set;}// 图标private Image icon;// 选中的槽数据private SlotData selectedSlotData;// 玩家对象private Player player;// 控制键是否按下private bool isCtrlDown false;// Awake方法在脚本实例化时调用private void Awake() {Instance this;icon GetComponentInChildrenImage();HideIcon();player GameObject.FindAnyObjectByTypePlayer();}// Update方法在每帧调用private void Update() {// 如果图标启用更新图标位置if (icon.enabled) {Vector2 position;RectTransformUtility.ScreenPointToLocalPointInRectangle(GetComponentRectTransform(), Input.mousePosition,null,out position);icon.GetComponentRectTransform().anchoredPosition position;}// 左键点击时如果没有点击UI元素丢弃物品if (Input.GetMouseButtonDown(0)) {if (EventSystem.current.IsPointerOverGameObject() false) {ThrowItem();}}// 检测Ctrl键按下和松开if (Input.GetKeyDown(KeyCode.LeftControl)) {isCtrlDown true;}if (Input.GetKeyUp(KeyCode.LeftControl)) {isCtrlDown false;}// 右键点击时强制清空手上的物品if (Input.GetMouseButtonDown(1)) {ClearHandForced();}}// 槽点击事件处理public void OnSlotClick(SlotUI slotui) {// 判断手上是否有物品if (selectedSlotData ! null) {// 手上有物品if (slotui.GetData().IsEmpty()) {// 当前点击了一个空格子MoveToEmptySlot(selectedSlotData, slotui.GetData());}else {// 当前点击了一个非空格子if (selectedSlotData slotui.GetData())return;else {// 点击了别的格子 且 两个格子的物品相同if (selectedSlotData.item slotui.GetData().item) {MoveToNotEmptySlot(selectedSlotData, slotui.GetData());}else {SwitchData(selectedSlotData, slotui.GetData());}}}}else {// 手上没有物品if (slotui.GetData().IsEmpty())return;selectedSlotData slotui.GetData();ShowIcon(selectedSlotData.item.itemSprite);}}// 隐藏图标void HideIcon() {icon.enabled false;}// 显示图标void ShowIcon(Sprite sprite) {icon.sprite sprite;icon.enabled true;}// 清空手上的物品void ClearHand() {if (selectedSlotData.IsEmpty()) {HideIcon();selectedSlotData null;}}// 强制清空手上的物品void ClearHandForced() {HideIcon();selectedSlotData null;}// 丢弃物品private void ThrowItem() {if (selectedSlotData ! null) {GameObject prefab selectedSlotData.item.itemPrefab;int count selectedSlotData.currentCount;if (isCtrlDown) {player.ThrowItem2Creat(prefab, 1);selectedSlotData.Reduce();}else {player.ThrowItem2Creat(prefab, count);selectedSlotData.Clear();}ClearHand();}}// 移动物品到空槽private void MoveToEmptySlot(SlotData fromData, SlotData toData) {if (isCtrlDown) {toData.AddItem(fromData.item);fromData.Reduce();}else {toData.MoveSlot(fromData);fromData.Clear();}ClearHand();}// 移动物品到非空槽private void MoveToNotEmptySlot(SlotData fromData, SlotData toData) {if (isCtrlDown) {if (toData.CanAddItem()) {toData.Add();fromData.Reduce();}}else {int freespace toData.GetFreeSpace();if (fromData.currentCount freespace) {toData.Add(freespace);fromData.Reduce(freespace);}else {toData.Add(fromData.currentCount);fromData.Clear();}}ClearHand();}// 交换槽数据private void SwitchData(SlotData data1, SlotData data2) {ItemData item data1.item;int count data1.currentCount;data1.MoveSlot(data2);data2.AddItem(item, count);ClearHandForced();} }Plyaer 拾取与丢弃 using UnityEngine;public class Player : MonoBehaviour {private void OnTriggerEnter2D(Collider2D collision) {Debug.Log(进入了触发检测);if (collision.CompareTag(Item)){Debug.Log(检测到了物品);InventoryManager.Instance.AddItemToInventory(collision.GetComponentPickable().thisItemType);Destroy(collision.gameObject);}}/// summary/// 丢弃背包的物品 并在场景中实例化出来/// /summary/// param nameitemPrefab丢弃对象/param/// param namecount丢弃数量/parampublic void ThrowItem2Creat(GameObject itemPrefab,int count){ for(int i 0; i count; i){GameObject go Instantiate(itemPrefab);Vector2 dir Random.insideUnitCircle.normalized * 0.8f;go.transform.position new Vector3(dir.x,dir.y,0);} } }
http://www.pierceye.com/news/368197/

相关文章:

  • vscode网站开发昆明做网站找启搜网络
  • 如何评估网站虚拟商品交易网站建设
  • 太原网站优化教程pycharm做网站
  • 哪些网站做英语比较好免费下载模板ppt
  • 网站建设运营计划书wordpress 维护页面
  • 襄阳定制型网站开发前端网页设计招聘
  • 网站备案报价深圳市住房和建设局官网首页
  • 宁波江北区网站推广联系方式做一个论坛网站要多少钱
  • 网站制作无锡台州建设工程网站
  • 云网站 制作如何做一个网页
  • 微信免费建站新建网站站点的
  • 云网站制作的流程世界500强企业排名
  • 巨久科技网站建设做出个人网站什么水平
  • 做外贸网站怎么做做网站3个月
  • 县局网站建设招标网站建设人文类
  • 网站开发亿玛酷给力5上海logo在线制作
  • 网站重新备案搞个网站需要多少钱
  • 海南微信网站制作平台网络计划的优化
  • 域名的正确书写格式自动seo优化
  • 怎样在网站做友情链接网页什么设计
  • 做seo网站营销推广南宁建设职业技术学院招聘信息网站
  • 网站建设全网推广小程序手机网站怎么优化
  • wordpress 网站logowin系统没有wordpress
  • 玉山电商网站建设东莞市建设规划局网站
  • 网站建设运营公司企业特色c2c的代表性的电商平台
  • 上海网站建设,分类广告软件公司简介
  • 网站虚拟主机被国家禁止访问的网站怎么打开
  • wordpress手机加载不出来优化官网咨询
  • 平台网站建设预算表如何来做网站
  • 温州网站制作企业东莞网络推广公司电话