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

北京海淀区派出所西安seo服务公司排名

北京海淀区派出所,西安seo服务公司排名,环境设计公司排名,有哪些做兼职的网站文章目录 先来看看最终效果前言素材简单绘制库存UI前往mixamo获取人物模型动画获取一些自己喜欢的装备物品模型库存系统换装系统装备偏移问题添加消耗品最终效果源码完结 先来看看最终效果 前言 之前2d的换装和库存系统我们都做过不少了,这次就来学习一个3d版本的&…

文章目录

  • 先来看看最终效果
  • 前言
  • 素材
  • 简单绘制库存UI
  • 前往mixamo获取人物模型动画
  • 获取一些自己喜欢的装备物品模型
  • 库存系统
  • 换装系统
  • 装备偏移问题
  • 添加消耗品
  • 最终效果
  • 源码
  • 完结

先来看看最终效果

在这里插入图片描述

前言

之前2d的换装和库存系统我们都做过不少了,这次就来学习一个3d版本的,其实逻辑和思维都是共通的,但是也会有些细节不同,毕竟3d多了一个轴,废话少说,我们一起开始吧!

素材

https://assetstore.unity.com/packages/2d/gui/fantasy-wooden-gui-free-103811
在这里插入图片描述

简单绘制库存UI

在这里插入图片描述

前往mixamo获取人物模型动画

mixamo网站我之前也推荐过:免费获取游戏素材、工具、国内宝藏游戏博主分享

地址:https://www.mixamo.com/
下载自己喜欢的人物动作模型
在这里插入图片描述
拖入角色
在这里插入图片描述

获取一些自己喜欢的装备物品模型

https://sketchfab.com/Trueform/collections/downloadable-8e49931974d24a8f9b5f77d94328540b在这里插入图片描述

导入模型的材质可能丢失
在这里插入图片描述
手动创建一个材质
在这里插入图片描述

配置对应纹理
在这里插入图片描述

挂载材质
在这里插入图片描述

同样的方法,配置其他不同类型的装备物品
在这里插入图片描述

库存系统

新增脚本InventoryItem

[CreateAssetMenu(menuName = "ScriptableObjects/库存系统/物品")]
public class InventoryItem : ScriptableObject
{[SerializeField] private GameObject itemPrefab;  // 存储物品的预制体[SerializeField] private Sprite itemSprite;      // 存储物品的精灵[SerializeField] private string itemName;        // 存储物品的名称[SerializeField] private Vector3 itemLocalPosition;  // 存储物品的局部位置[SerializeField] private Vector3 itemLocalRotation;  // 存储物品的局部旋转// 返回存储的物品精灵public Sprite GetSprite(){return itemSprite;}// 返回存储的物品名称public string GetName(){return itemName;}// 返回存储的物品预制体public GameObject GetPrefab(){return itemPrefab;}// 返回存储的物品局部位置public Vector3 GetLocalPosition(){return itemLocalPosition;}// 返回存储的物品局部旋转(以四元数表示)public Quaternion GetLocalRotation(){return Quaternion.Euler(itemLocalRotation);}
}

配置不同物品信息
在这里插入图片描述

新增InventoryItemWrapper

// 使用[System.Serializable]属性将该类标记为可序列化,以便在Unity编辑器中进行序列化
[System.Serializable]
public class InventoryItemWrapper
{[SerializeField] private InventoryItem item;  // 存储物品信息的对象[SerializeField] private int count;           // 存储物品数量// 返回存储的物品信息public InventoryItem GetItem(){return item;}// 返回存储的物品数量public int GetItemCount(){return count;}
}

新增Inventory

[CreateAssetMenu(menuName = "ScriptableObjects/库存系统/库存")]
public class Inventory : ScriptableObject
{[SerializeField] private List<InventoryItemWrapper> items = new List<InventoryItemWrapper>();  // 存储物品及其数量的列表[SerializeField] private InventoryUI inventoryUIPrefab;private InventoryUI _inventoryUI;  // 与此库存相关联的UIprivate InventoryUI inventoryUI{get{if (!_inventoryUI){_inventoryUI = Instantiate(inventoryUIPrefab, playerEquipment.GetUIParent());}return _inventoryUI;}}private Dictionary<InventoryItem, int> itemToCountMap = new Dictionary<InventoryItem, int>();  // 将物品映射到数量的字典private PlayerEquipmentController playerEquipment;// 初始化库存,将物品及其数量添加到映射中public void InitInventory(PlayerEquipmentController playerEquipment){this.playerEquipment = playerEquipment;for (int i = 0; i < items.Count; i++){itemToCountMap.Add(items[i].GetItem(), items[i].GetItemCount());}}//开启背包public void OpenInventoryUI(){inventoryUI.gameObject.SetActive(true);inventoryUI.InitInventoryUI(this);}// 分配物品给玩家public void AssignItem(InventoryItem item){Debug.Log("点击了物品:" + item.GetName());}// 返回所有物品及其数量的映射public Dictionary<InventoryItem, int> GetAllItemsMap(){return itemToCountMap;}// 添加物品到库存中,并更新UIpublic void AddItem(InventoryItem item, int count){int currentItemCount;if (itemToCountMap.TryGetValue(item, out currentItemCount)){itemToCountMap[item] = currentItemCount + count;}else{itemToCountMap.Add(item, count);}inventoryUI.CreateOrUpdateSlot(this, item, count);}// 从库存中移除物品,并更新UIpublic void RemoveItem(InventoryItem item, int count){int currentItemCount;if (itemToCountMap.TryGetValue(item, out currentItemCount)){itemToCountMap[item] = currentItemCount - count;if (currentItemCount - count <= 0){inventoryUI.DestroySlot(item);}else{inventoryUI.UpdateSlot(item, currentItemCount - count);}}else{Debug.Log("Can't remove item");}}
}

配置库存信息
在这里插入图片描述
新增InventorySlot,控制物品插槽信息显示

public class InventorySlot : MonoBehaviour
{[SerializeField] private Image itemImage;  // 物品图像[SerializeField] private TextMeshProUGUI itemNameText;  // 物品名称文本[SerializeField] private TextMeshProUGUI itemCountText;  // 物品数量文本[SerializeField] private Button slotButton;  // 插槽按钮// 初始化插槽的可视化表示public void InitSlotVisualisation(Sprite itemSprite, string itemName, int itemCount){itemImage.sprite = itemSprite;itemNameText.text = itemName;UpdateSlotCount(itemCount);}// 更新插槽中物品的数量显示public void UpdateSlotCount(int itemCount){itemCountText.text = itemCount.ToString();}// 分配插槽按钮的回调函数public void AssignSlotButtonCallback(System.Action onClickCallback){slotButton.onClick.AddListener(() => onClickCallback());}
}

挂载脚本并配置信息
在这里插入图片描述
新增InventoryUI,控制显示背包插槽信息

public class InventoryUI : MonoBehaviour
{[SerializeField] private Transform slotsParent;  // 插槽的父级对象[SerializeField] private InventorySlot slotPrefab;  // 插槽的预制体private Dictionary<InventoryItem, InventorySlot> itemToSlotMap = new Dictionary<InventoryItem, InventorySlot>();  // 将物品映射到插槽的字典// 初始化库存UIpublic void InitInventoryUI(Inventory inventory){var itemsMap = inventory.GetAllItemsMap();foreach (var kvp in itemsMap){CreateOrUpdateSlot(inventory, kvp.Key, kvp.Value);}}// 创建或更新物品插槽public void CreateOrUpdateSlot(Inventory inventory, InventoryItem item, int itemCount){if (!itemToSlotMap.ContainsKey(item)){var slot = CreateSlot(inventory, item, itemCount);itemToSlotMap.Add(item, slot);}else{UpdateSlot(item, itemCount);}}// 更新已存在的物品插槽public void UpdateSlot(InventoryItem item, int itemCount){itemToSlotMap[item].UpdateSlotCount(itemCount);}// 创建物品插槽private InventorySlot CreateSlot(Inventory inventory, InventoryItem item, int itemCount){var slot = Instantiate(slotPrefab, slotsParent);slot.InitSlotVisualisation(item.GetSprite(), item.GetName(), itemCount);slot.AssignSlotButtonCallback(() => inventory.AssignItem(item));return slot;}// 销毁物品插槽public void DestroySlot(InventoryItem item){Destroy(itemToSlotMap[item].gameObject);itemToSlotMap.Remove(item);}
}

挂载脚本配置信息
在这里插入图片描述
新增PlayerEquipmentController,初始化库存

public class PlayerEquipmentController : MonoBehaviour
{[SerializeField] private Inventory inventory;  // 玩家的库存[SerializeField] private Transform inventoryUIParent;  // 库存UI的父级对象private void Start(){inventory.InitInventory(this);  // 初始化玩家库存inventory.OpenInventoryUI();  // 打开库存UI}// 获取UI父级对象public Transform GetUIParent(){return inventoryUIParent;}
}

挂载脚本,并配置信息
在这里插入图片描述
效果
在这里插入图片描述

换装系统

修改InventoryItem,将InventoryItem 定义为所有物品的抽象父类,AssignItemToPlayer方法声明为抽象方法。这意味着所有继承自InventoryItem的子类都必须实现这个方法。这样可以确保每个具体的物品类在被分配给玩家时都有自己特定的行为

public abstract class InventoryItem : ScriptableObject
{    //。。。//将物品分配给玩家public abstract void AssignItemToPlayer(PlayerEquipmentController playerEquipment);
}

修改Inventory,调用AssignItemToPlayer方法

// 分配物品给玩家
public void AssignItem(InventoryItem item)
{// Debug.Log("点击了物品:" + item.GetName());//将物品分配给玩家item.AssignItemToPlayer(playerEquipment);
}

新增HelmetInventoryItem,定义头盔物品类

[CreateAssetMenu(menuName = "ScriptableObjects/库存系统/物品/头盔")]
public class HelmetInventoryItem : InventoryItem
{// 将物品分配给玩家public override void AssignItemToPlayer(PlayerEquipmentController playerEquipment)  {playerEquipment.AssignHelmetItem(this);}
}

新增HandInventoryItem,定义手部物品类

public enum Hand
{LEFT,  // 左手RIGHT  // 右手
}[CreateAssetMenu(menuName = "ScriptableObjects/库存系统/物品/手部物品")]
public class HandInventoryItem : InventoryItem
{public Hand hand;  // 物品所属的手部类型,左手或右手// 将物品分配给玩家public override void AssignItemToPlayer(PlayerEquipmentController playerEquipment)  {playerEquipment.AssignHandItem(this);}
}

新增ArmorInventoryItem,定义护甲物品类

[CreateAssetMenu(menuName = "ScriptableObjects/库存系统/物品/护甲")]
public class ArmorInventoryItem : InventoryItem
{// 将物品分配给玩家public override void AssignItemToPlayer(PlayerEquipmentController playerEquipment){playerEquipment.AssignArmorItem(this);}
}

修改PlayerEquipmentController,定义不同部位物品数据处理逻辑

[SerializeField] private Transform helmetAnchor;  // 头盔装备点
[SerializeField] private Transform leftAnchor;  // 左手装备点
[SerializeField] private Transform rightAnchor;  // 右手装备点
[SerializeField] private Transform armorAnchor;  // 盔甲装备点
private GameObject currentHelmetObj;  // 当前头盔对象
private GameObject currentLeftHandObj;  // 当前左手对象
private GameObject currentRightHandObj;  // 当前右手对象
private GameObject currentArmorObj;  // 当前盔甲对象// 分配头盔物品给玩家
public void AssignHelmetItem(HelmetInventoryItem item)
{DestroyIfNotNull(currentHelmetObj);  // 如果当前有头盔对象,则销毁currentHelmetObj = CreateNewItemInstance(item, helmetAnchor);  // 创建新的头盔实例并赋值给当前头盔对象
}// 创建新的装备实例
private GameObject CreateNewItemInstance(InventoryItem item, Transform anchor)
{var itemInstance = Instantiate(item.GetPrefab(), anchor);  // 实例化物品的预制体,并放置在指定的装备点itemInstance.transform.localPosition = item.GetLocalPosition();  // 设置物品相对于装备点的本地坐标itemInstance.transform.localRotation = item.GetLocalRotation();  // 设置物品相对于装备点的本地旋转return itemInstance;  // 返回创建的物品实例
}// 销毁物体,如果不为空
private void DestroyIfNotNull(GameObject obj)
{if (obj != null){Destroy(obj);}
}// 分配手部物品给玩家
public void AssignHandItem(HandInventoryItem item)
{switch (item.hand){case Hand.LEFT:DestroyIfNotNull(currentLeftHandObj);currentLeftHandObj = CreateNewItemInstance(item, leftAnchor);break;case Hand.RIGHT:DestroyIfNotNull(currentRightHandObj);currentRightHandObj = CreateNewItemInstance(item, rightAnchor);break;default:break;}
}// 分配盔甲物品给玩家
public void AssignArmorItem(ArmorInventoryItem item)
{DestroyIfNotNull(currentArmorObj);  // 如果当前有盔甲对象,则销毁currentArmorObj = CreateNewItemInstance(item, armorAnchor);  // 创建新的盔甲实例并赋值给当前盔甲对象
}

配置
在这里插入图片描述

添加新的库存物品配置,删除旧的
在这里插入图片描述
在这里插入图片描述

运行效果
在这里插入图片描述

装备偏移问题

可以看到装备物品存在偏移,运行修改装备到合适位置,复制装备位置和旋转进对应装备的偏移参数
在这里插入图片描述
效果
在这里插入图片描述

添加消耗品

新增HealthPotionInventoryItem,定义生命药水物品类

[CreateAssetMenu(menuName = "ScriptableObjects/库存系统/物品/生命药水")]
public class HealthPotionInventoryItem : InventoryItem
{[SerializeField] private int healthPoints;  // 生命药水的恢复生命值public override void AssignItemToPlayer(PlayerEquipmentController playerEquipment){playerEquipment.AssingHealthPotionItem(this);}public int GetHealthPoints()  // 获取生命药水的恢复生命值{return healthPoints;}
}

修改PlayerEquipmentController

private int playerHealth = 0;// 分配生命药水物品给玩家
public void AssingHealthPotionItem(HealthPotionInventoryItem item)
{inventory.RemoveItem(item, 1);// 消耗物品playerHealth += item.GetHealthPoints();//加血Debug.Log("玩家现在生命值" + playerHealth);
}

创建生命药水物品,这里我就用苹果和饮料代替,配置对应的恢复生命值
在这里插入图片描述
加入库存
在这里插入图片描述

运行效果
在这里插入图片描述

最终效果

在这里插入图片描述

源码

整理好会放上来

完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,以便我第一时间收到反馈,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇,https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,出于兴趣爱好,于是最近才开始自习unity。如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我可能也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~
在这里插入图片描述

http://www.ds6.com.cn/news/76122.html

相关文章:

  • 怎样建网站步骤产品推广介绍怎么写
  • 四川网站建设平台百度seo推广优化
  • 湖南网站建站系统平台东莞免费网站建设网络营销
  • 网站做建筑三维图培训网登录入口
  • crm系统的作用seo查询在线
  • 怎么进行网站诊断seo整站优化新站快速排名
  • 怎么做代购彩票网站百度搜索引擎竞价排名
  • 如何让百度收录中文域名网站网络软文范文
  • 济南做门户网站开发公司google搜索免费入口
  • 自己做网站创业关键词检测
  • 网站建设标语1个百度指数代表多少搜索
  • 网站管理系统安装 -网络营销的原理
  • 互联网网站开发广州seo技术优化网站seo
  • 北京公司网站怎么制作58精准推广点击器
  • wordpress搭建wifi登陆抖音seo排名系统
  • 电子商务主要干什么seo如何挖掘关键词
  • 如何给网站做备份谷歌推广代理
  • 网站模仿算侵权吗seo网络营销是什么意思
  • 公司注册核名在哪个网站免费建网站的步骤
  • 汕头论坛建站模板网推项目接单平台
  • 超能力联盟网站免费的企业黄页网站
  • 购物型网站线上营销推广方式有哪些
  • 江苏省工程建设招标网站百度推广一年要多少钱
  • 动态网站与静态网站区别谷歌收录查询工具
  • 东莞信科网站建设广告营销包括哪些方面
  • 网站建设的实验报告上海比较大的优化公司
  • 福建闽东建设网站淘宝运营培训课程
  • 管理咨询公司是做什么福州seo网站排名
  • 零基础 网站济南网站建设哪家便宜
  • asp做网站优点云搜索下载