IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity3D RPG实现 6 -> 正文阅读

[游戏开发]Unity3D RPG实现 6

实现切换武器

DragItem 中添加物品属性和 SlotType 的匹配

对于非背包里的物品我们也可以交换但是要加以限制。

在 SlotHolder 中切换所属背包的数据库?

当我们将Slot Holder放在不同的地方时,此时也要更改其所属的背包对应的数据库:

这样即可实现不同栏间的物品交换,并且数据库也会因此更新。

鼠标点击会使得人物移动的问题

?

?换武器的方法

在characterStats中补充卸下武器的代码:

    public void UnEquipWeapon()
    {
        if (weaponSlot.transform.childCount != 0)
        {
            for(int i = 0; i < weaponSlot.transform.childCount; i++)
            {
                Destroy(weaponSlot.transform.GetChild(i).gameObject);
            }
        }
    }

卸下武器前就要还原成原来的攻击数据,因此需要有一个变量来记录初始时没武器的数据:

代码如下:

    public void UnEquipWeapon()
    {
        if (weaponSlot.transform.childCount != 0)
        {
            for(int i = 0; i < weaponSlot.transform.childCount; i++)
            {
                Destroy(weaponSlot.transform.GetChild(i).gameObject);
            }
        }
        attackData.ApplyWeanponData(baseAttackData);//卸下武器后还原之前的攻击力
        //TODO:切换动画

    }

    public void ChangeWeapon(ItemData_SO weapon)
    {
        UnEquipWeapon();
        EquipWeapon(weapon);
    }

然后在SlotHolder更新一栏中更改武器:

?

可使用的物品

  • 创建大蘑菇 并添加必要的组件

  • 创建 UseableItemData_SO 制作可使用物品的属性模版

  • 利用 IPointerClickHandler 接口实现双击使用物品

  • 在 CharacterStats 中添加 ApplyHealth 实现血量变化

参考代码手册:

创建一个蘑菇的变量:

创建useable类型的SO:

然后在itemData中加入这种类型:?

?创建useable类型的SO:

并赋值:(为useable Item赋值)

然后在场景中创建一个mushroom并添加这些组件:

?

之后即可实现拾取蘑菇并且在格子和快捷栏里自由移动。

?

接下来实现使用物品的功能:

先在itemUI中写一个根据对应UI获取对应物品的方法:

在characterStats中书写一个函数:

??使用需要实现一个接口,?

?在SlotHolder里实现该接口

    public void OnPointerClick(PointerEventData eventData)
    {
        if (eventData.clickCount % 2 == 0)//代表是双击的话
        {
            UseItem();
        }
    }
    public void UseItem()
    {
        if (itemUI.GetItem().itemType == ItemType.Useable&&itemUI.Bag.items[itemUI.Index].amount>0)
        {
            GameManager.Instance.playerStats.ApplyHealth(itemUI.GetItem().useableData.healthPoint);
            itemUI.Bag.items[itemUI.Index].amount -= 1;
        }
        UpdateItem();
    }

别忘了要进行数量减一,更新UI的操作。

但是之后发现一个bug,当蘑菇用完时图片仍然存在:

?

解决方法:

显示Player相关信息

设定一个相机让它观察player,并设定好各类信息:

创建texture然后放进去

然后将renderTexture给Stats里面创建的RawImage

?记得将相机的设置放入prefab里面??

然后可以显示:

接下来实现血量和伤害的显示:?

然后在装备武器时进行信息的更新:

也可以在manager中更新:

随后即可实现血量和攻击的更新了:升级时也会改变

切换动画控制器

  • 使用更多动画来创建 Animator override controller

  • ItemData_SO 中添加武器配套动画控制器

  • 在 EquipWeapon 和 UnEquipment 中添加代码切换武器伴随动画

参考素材:

?这两个作者的素材很好,有很多动作素材

下载这个只保留animation即可:

创建一个没武器的override controller:并导入动画

然后即可实现无武器的运行。

但是会有两个报错,是因为动画自带两个事件。删除即可。

我们希望给武器自己加上一个animation controller:

?

在此处更换装备。

初始时获取初始动画控制器:

?卸武器时候还原:

?

这样就可以自由切换了。

有个问题在于人物的武器不能在属性中显示,将sword的预制体的layer设置为player即可。?

物品信息显示栏?

创建一个image,调整大小:

然后设定为了能根据不同的设置出不同的大小,添加这个组件

添加这个:

给信息一栏也添加Fitter:

这样就可以实现UI的信息的多少会随着栏的信息而改变:

?创建代码,实现控制:

鼠标的悬停希望实现的接口:

让SlotHolder实现这两个接口:

    public void OnPointerEnter(PointerEventData eventData)
    {
        if (itemUI.GetItem())
        {
            InventoryManager.Instance.tooltip.SetupTooltip(itemUI.GetItem());
            InventoryManager.Instance.tooltip.gameObject.SetActive(true);
        }
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        InventoryManager.Instance.tooltip.gameObject.SetActive(false);
    }

?这样就可以实现悬停时出现。

接下来希望悬停时出现的位置是鼠标的位置:

效果:

但是出现的位置是在鼠标中心,并且还会闪烁。

是因为锚点是出现在中心:

?修改方法:

?代码如下:

public class ItemToolTip : MonoBehaviour
{
    public Text itemNameText;
    public Text itemInfoText;
    RectTransform rectTransform;

    private void Awake()
    {
        rectTransform = GetComponent<RectTransform>();
    }
    public void SetupTooltip(ItemData_SO item)
    {
        itemNameText.text = item.itemName;
        itemInfoText.text = item.description;
    }

    void OnEnable()
    {
        //开始时会闪烁是因为没有定位好坐标,开始时先更新一下即可避免这种效果
        UpdatePosition();

    }
    private void Update()
    {
        UpdatePosition();
    }
    public void UpdatePosition()
    {
        Vector3 mousePos = Input.mousePosition;
        rectTransform.position = mousePos;

        Vector3[] corners = new Vector3[4];
        rectTransform.GetWorldCorners(corners);

        float width = corners[3].x - corners[0].x;
        float height = corners[1].y - corners[0].y;

        if (mousePos.y < height)
            rectTransform.position = mousePos + Vector3.up * height * 0.6f;
        else if (Screen.width - mousePos.x > width)
            rectTransform.position = mousePos + Vector3.right * width * 0.6f;
        else
            rectTransform.position = mousePos + Vector3.left * width * 0.6f;

    }

}

还有个问题在于当你背包关闭时,信息仍然有显示,解决方法:

掉落物品

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LootSpawner : MonoBehaviour
{
    [System.Serializable]
    public class LootItem
    {
        public GameObject item;
        [Range(0, 1)]
        public float weight;
    }

    public LootItem[] lootItems; 

    public void Spawnloot()
    {
        float currentValue = Random.value;

        for(int i = 0; i < lootItems.Length; i++)
        {
            if (currentValue <= lootItems[i].weight)
            {
                GameObject obj = Instantiate(lootItems[i].item);
                obj.transform.position = transform.position + Vector3.up * 2;
            }
        }
    }
}

给怪物添加以上代码?

当敌人死亡时调用掉落:

这样即可实现掉落?

完成背包?

创建模板

保存加载数据:

开始时加载数据:

?

?

然后在inventory manager的inspector中修改:


?

如果我们需要在第二个场景中也使用背包系统,就将其作为预制体在第二个场景中载入:

?

并且记得添加eventSystem、

?

?

?这样即可实现场景切换时保存的效果。

?

实现拖拽面板

?给两个背包面板添加这个代码:

public class DragPanel : MonoBehaviour,IDragHandler
{
    RectTransform rectTransform;

    void Awake()
    {
        rectTransform = GetComponent<RectTransform>();
    }
    public void OnDrag(PointerEventData eventData)
    {
        rectTransform.anchoredPosition += eventData.delta;//让其锚点的位置的改变量和鼠标的改变量相同即可
    }
}

即可实现拖拽。

但是有一点问题在于如果鼠标处于背包的边边部分进行拖拽时,此时面板的位移增量就比鼠标的位移增量要大了。

是因为面板中这个组件的存在:

?????????

?方法:

?

但是移动背包时会被另外一个背包挡住:

?

?观察可发现是因为顺序在下的被后渲染,后渲染的就会显示在前方

?

使用这个方法将其放在索引的最下方。

但是有一点,不能将其放在drag canvas索引的下方。要保证drag canvas始终在下方:

?

所以需要使用获取索引的方法。

将其索引设置在2即可。

?

这样就不会被遮挡。

但是此处又出现了一个新的问题,问题在于将物品拖拽放回原处的时候,背包里就看不见了。

解决方法在此处添加:

?效果:

?

?

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-03-06 13:29:43  更:2022-03-06 13:31:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 16:25:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码