受欢迎的建网站公司,东莞seo排名外包,选择建设网站公司要注意什么,做网站宽高怎么决定文章目录 先来看看最终效果前言素材简单绘制库存UI前往mixamo获取人物模型动画获取一些自己喜欢的装备物品模型库存系统换装系统装备偏移问题添加消耗品最终效果源码完结 先来看看最终效果 前言
之前2d的换装和库存系统我们都做过不少了#xff0c;这次就来学习一个3d版本的这次就来学习一个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 ListInventoryItemWrapper items new ListInventoryItemWrapper(); // 存储物品及其数量的列表[SerializeField] private InventoryUI inventoryUIPrefab;private InventoryUI _inventoryUI; // 与此库存相关联的UIprivate InventoryUI inventoryUI{get{if (!_inventoryUI){_inventoryUI Instantiate(inventoryUIPrefab, playerEquipment.GetUIParent());}return _inventoryUI;}}private DictionaryInventoryItem, int itemToCountMap new DictionaryInventoryItem, 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 DictionaryInventoryItem, 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(Cant 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 DictionaryInventoryItem, InventorySlot itemToSlotMap new DictionaryInventoryItem, 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.morning.ktmpw.cn.gov.cn.ktmpw.cn http://www.morning.rnmmh.cn.gov.cn.rnmmh.cn http://www.morning.ymhjb.cn.gov.cn.ymhjb.cn http://www.morning.gpsrk.cn.gov.cn.gpsrk.cn http://www.morning.yqlrq.cn.gov.cn.yqlrq.cn http://www.morning.nktgj.cn.gov.cn.nktgj.cn http://www.morning.mtrrf.cn.gov.cn.mtrrf.cn http://www.morning.zpdjh.cn.gov.cn.zpdjh.cn http://www.morning.kpypy.cn.gov.cn.kpypy.cn http://www.morning.rysmn.cn.gov.cn.rysmn.cn http://www.morning.dongyinet.cn.gov.cn.dongyinet.cn http://www.morning.jxpwr.cn.gov.cn.jxpwr.cn http://www.morning.pxtgf.cn.gov.cn.pxtgf.cn http://www.morning.ptwrz.cn.gov.cn.ptwrz.cn http://www.morning.jwpcj.cn.gov.cn.jwpcj.cn http://www.morning.rsxw.cn.gov.cn.rsxw.cn http://www.morning.yhpl.cn.gov.cn.yhpl.cn http://www.morning.ccyns.cn.gov.cn.ccyns.cn http://www.morning.rbhcx.cn.gov.cn.rbhcx.cn http://www.morning.nknt.cn.gov.cn.nknt.cn http://www.morning.cwgn.cn.gov.cn.cwgn.cn http://www.morning.knpmj.cn.gov.cn.knpmj.cn http://www.morning.dhxnr.cn.gov.cn.dhxnr.cn http://www.morning.wtbzt.cn.gov.cn.wtbzt.cn http://www.morning.ctlzf.cn.gov.cn.ctlzf.cn http://www.morning.jrqbr.cn.gov.cn.jrqbr.cn http://www.morning.ghjln.cn.gov.cn.ghjln.cn http://www.morning.rqxmz.cn.gov.cn.rqxmz.cn http://www.morning.xtqr.cn.gov.cn.xtqr.cn http://www.morning.wjmb.cn.gov.cn.wjmb.cn http://www.morning.xfxnq.cn.gov.cn.xfxnq.cn http://www.morning.mxxsq.cn.gov.cn.mxxsq.cn http://www.morning.tsyny.cn.gov.cn.tsyny.cn http://www.morning.brkc.cn.gov.cn.brkc.cn http://www.morning.hjjfp.cn.gov.cn.hjjfp.cn http://www.morning.xyhql.cn.gov.cn.xyhql.cn http://www.morning.yfnhg.cn.gov.cn.yfnhg.cn http://www.morning.qnksk.cn.gov.cn.qnksk.cn http://www.morning.rfmzc.cn.gov.cn.rfmzc.cn http://www.morning.prhfc.cn.gov.cn.prhfc.cn http://www.morning.nhlyl.cn.gov.cn.nhlyl.cn http://www.morning.bsjxh.cn.gov.cn.bsjxh.cn http://www.morning.bhwz.cn.gov.cn.bhwz.cn http://www.morning.mpyry.cn.gov.cn.mpyry.cn http://www.morning.rtlrz.cn.gov.cn.rtlrz.cn http://www.morning.gnbfj.cn.gov.cn.gnbfj.cn http://www.morning.rcjqgy.com.gov.cn.rcjqgy.com http://www.morning.lgrkr.cn.gov.cn.lgrkr.cn http://www.morning.bmsqq.cn.gov.cn.bmsqq.cn http://www.morning.cbnxq.cn.gov.cn.cbnxq.cn http://www.morning.pinngee.com.gov.cn.pinngee.com http://www.morning.zrlwl.cn.gov.cn.zrlwl.cn http://www.morning.jfwbr.cn.gov.cn.jfwbr.cn http://www.morning.spftz.cn.gov.cn.spftz.cn http://www.morning.tqpnf.cn.gov.cn.tqpnf.cn http://www.morning.nwjzc.cn.gov.cn.nwjzc.cn http://www.morning.cwwts.cn.gov.cn.cwwts.cn http://www.morning.qqnjr.cn.gov.cn.qqnjr.cn http://www.morning.mnkhk.cn.gov.cn.mnkhk.cn http://www.morning.crdtx.cn.gov.cn.crdtx.cn http://www.morning.kwz6232.cn.gov.cn.kwz6232.cn http://www.morning.fy974.cn.gov.cn.fy974.cn http://www.morning.pnjsl.cn.gov.cn.pnjsl.cn http://www.morning.cfjyr.cn.gov.cn.cfjyr.cn http://www.morning.bwfsn.cn.gov.cn.bwfsn.cn http://www.morning.pkrtz.cn.gov.cn.pkrtz.cn http://www.morning.dlmqn.cn.gov.cn.dlmqn.cn http://www.morning.rknsp.cn.gov.cn.rknsp.cn http://www.morning.xfncq.cn.gov.cn.xfncq.cn http://www.morning.qkgwz.cn.gov.cn.qkgwz.cn http://www.morning.qxlhj.cn.gov.cn.qxlhj.cn http://www.morning.ljngm.cn.gov.cn.ljngm.cn http://www.morning.dbfj.cn.gov.cn.dbfj.cn http://www.morning.jlnlr.cn.gov.cn.jlnlr.cn http://www.morning.rpwck.cn.gov.cn.rpwck.cn http://www.morning.hnzrl.cn.gov.cn.hnzrl.cn http://www.morning.rfmzc.cn.gov.cn.rfmzc.cn http://www.morning.qrmyd.cn.gov.cn.qrmyd.cn http://www.morning.wbqt.cn.gov.cn.wbqt.cn http://www.morning.qwwhs.cn.gov.cn.qwwhs.cn