Unity 回合制战斗系统(中级篇)-血条和伤害数值

项目文件找出来了,老版本的脚本有报错,我在新版2019.4.21f1c1下解决了报错,战斗场景可以正常跑的。

需要的同学点下面地址下载(关注就行啦不用积分),祝大家都早日学成

项目包下载

————————————————————————​​​​​​​

今天没有做太多内容,只是在昨天的基础上增加了战斗伤害数值的显示及动画,因为又涉及到了之前UI控制相关的脚本,就顺便把这一块做了优化,效果请看Gif

接下来就是本文主要内容:集中介绍血条及伤害数值的实现及脚本

1. 血条

首先是制作一个血条的预制体,由底图、血条图和文本组成,其中文本用来显示单位名字,如下图,其中血条图片的Image Type设置成Filled

之前是用一个BattleUIManager完成了血条的所有操作,内容比较乱,这边做了优化,只用它来负责实例化脚本,并给脚本设置好“主人”,之后的血条状态由它自身的BloodUpdate函数根据主人的状态来更新。

新的BattleUIManager如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class BattleUIManager : MonoBehaviour {

    //把做好的预制体赋给这个变量
    public GameObject bloodBar;

    //玩家和怪物的数组
    private GameObject[] playerUnits;
    private GameObject[] enemyUnits;

    //统一调整血条的偏移量
    public float bloodXOffeset;
    public float bloodYOffeset;
    public float bloodZOffeset;

    void Start ()
    {
        //搜索所有参战的玩家对象,逐个创建血条
        playerUnits = GameObject.FindGameObjectsWithTag("PlayerUnit");
        foreach (GameObject playerUnit in playerUnits)
        {
            GameObject playerBloodBar = Instantiate(bloodBar) as GameObject;
            //实例化后设置到正确的画布分组里,便于管理也保证能正常显示
            playerBloodBar.transform.SetParent(GameObject.Find("BloodBarGroup").transform, false);

            //设置血条的主人,BloodUpdate将根据这个主人的状态来更新血条
            playerBloodBar.GetComponent<BloodUpdate>().owner = playerUnit;
        }

        //搜索所有参战的怪物对象,逐个创建血条
        enemyUnits = GameObject.FindGameObjectsWithTag("EnemyUnit");
        foreach (GameObject enemyUnit in enemyUnits)
        {
            GameObject enemyBloodBar = Instantiate(bloodBar) as GameObject;
            enemyBloodBar.transform.SetParent(GameObject.Find("BloodBarGroup").transform, false);

            //设置血条的主人,BloodUpdate将根据这个主人的状态来更新血条
            enemyBloodBar.GetComponent<BloodUpdate>().owner = enemyUnit;
        }
    }

    //供按钮调用的函数,此处可忽略
    public void GoToScene(string name)
    {
        SceneManager.LoadScene(name);
    }

}


血条预制体上挂的BloodUpdate脚本如下:

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

public class BloodUpdate : MonoBehaviour {

    //血条的主人,在创建时会通过BattleUIManager赋值
    public GameObject owner;

    //血条的长度数值,1为满格
    private Image ownerBloodFill;

    //获取UI控制脚本的引用,要从它那里获取统一的偏移量
    private BattleUIManager uiManager;

    //主人的3D空间位置
    private Vector3 playerBlood3DPosition;
    //将主人的3D位置映射到屏幕之后的2D位置
    private Vector2 playerBlood2DPosition;

    void Start()
    {
        //显示血条主人的名字
        Text ownerText = gameObject.transform.Find("OwnerName").GetComponent<Text>();
        ownerText.text = owner.name;
        
        //获取UI控制脚本的引用
        uiManager = GameObject.Find("BattleUIManager").GetComponent<BattleUIManager>();
    }

    void Update()
    {
        if (owner.tag=="PlayerUnit" || owner.tag == "EnemyUnit")
        {
            //更新血条长度
            ownerBloodFill = gameObject.transform.Find("BloodFill").GetComponent<Image>();
            ownerBloodFill.fillAmount = owner.GetComponent<UnitStats>().bloodPercent;           //bloodPercent在每个单位的UnitStats脚本中存储

            //更新血条位置
            //获取当前主人的空间位置,然后转换为2D屏幕位置
            playerBlood3DPosition = owner.transform.position + new Vector3(uiManager.bloodXOffeset, uiManager.bloodYOffeset, uiManager.bloodZOffeset);
            playerBlood2DPosition = Camera.main.WorldToScreenPoint(playerBlood3DPosition);
            gameObject.GetComponent<RectTransform>().position = playerBlood2DPosition;
        }

        //如果主人死了,则设置为未激活状态
        if (owner.GetComponent<UnitStats>().IsDead())
        {
            gameObject.SetActive(false);
        }
    }

}

这样血条的生成、跟随和更新就全部实现了。

2. 伤害数值

伤害值的实现跟血条类似,也是先完成预制体,然后我给伤害文本制作了一个放大出现,并渐变消失的过程动画,字体的移动是通过脚本来实现的。

伤害值的生成直接放到了回合控制脚本中,在执行ReceiveDamage之后立即生成;

//被攻击者承受伤害
        currentActUnitTarget.GetComponent<UnitStats>().ReceiveDamage(attackData);

        //实例化伤害字体并设置到画布上(字体位置和内容的控制放在它自身的脚本中)
        GameObject thisText = Instantiate(bloodText) as GameObject;
        thisText.transform.SetParent(GameObject.Find("BloodTextGroup").transform, false);

还是跟血条一样的管理,生成后立即设置到正确的画布分组中;

以下是挂在伤害值预制体上的DamageFloatUp脚本:

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

public class DamageFloatUp : MonoBehaviour {
    
    private BattleTurnSystem turnScript;            //回合控脚本的引用

    //受到伤害单位的位置
    private Vector3 takeDamageUnit3DPosition;
    private Vector2 takeDamageUnit2DPosition;

    void Start ()
    {
        turnScript = GameObject.Find("BattleManager").GetComponent<BattleTurnSystem>();         //查找引用

        //计算伤害者的3D位置并转化为屏幕2D位置
        takeDamageUnit3DPosition = turnScript.currentActUnitTarget.transform.position + new Vector3(0,1,0);         //适当上移修正位置
        takeDamageUnit2DPosition = Camera.main.WorldToScreenPoint(takeDamageUnit3DPosition);
        gameObject.GetComponent<RectTransform>().position = takeDamageUnit2DPosition;

        //设置数字内容
        gameObject.GetComponent<Text>().text = "-"+ turnScript.attackData;

        //延迟销毁自身
        StartCoroutine("WaitAndDestory");
    }

	void Update () {
        //向上漂浮控制
        gameObject.GetComponent<RectTransform>().anchoredPosition = gameObject.GetComponent<RectTransform>().anchoredPosition + new Vector2(0, 1);
    }

    //延迟销毁
    IEnumerator WaitAndDestory()
    {
        yield return new WaitForSeconds(1.5f);
        Destroy(gameObject);
    }
}

以上

猜你喜欢

转载自blog.csdn.net/c252270036/article/details/77203557