Unity3D RPG实现 6

目录

实现切换武器

可使用的物品

显示Player相关信息

切换动画控制器

物品信息显示栏 

掉落物品

完成背包 


实现切换武器

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即可。

这样就不会被遮挡。

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

解决方法在此处添加:

 效果:

猜你喜欢

转载自blog.csdn.net/weixin_43757333/article/details/123236538