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

来源:互联网 发布:天之痕java版 编辑:程序博客网 时间:2024/05/18 20:12

本人游戏策划一枚,爱好游戏设计开发

今天没有做太多内容,只是在昨天的基础上增加了战斗伤害数值的显示及动画,因为又涉及到了之前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);    }}
以上

阅读全文
1 0