需求:创建一个血条UI,在角色受击时扣血。
思路:创建画布,按顺序创建BaseUI>HP>TEXT,编写HP.cs,并且初始化当前值HealthCurrent和最大值(原始值)HealthMax两个变量,并且从PlayerController里取得角色原始值health变量进行赋值。
代码(HP.cs):
...
// 初始化数显
public Text healthText;
// 定义静态变量当前血量
public static int HealthCurrent;
// 定义静态变量原始血量
public static int HealthMax;
private Image healthBar;
// Start is called before the first frame update
void Start()
{
healthBar = GetComponent<Image>();
HealthCurrent = HealthMax;
}
// Update is called once per frame
void Update()
{
healthBar.fillAmount = (float)HealthCurrent / (float)HealthMax;
healthText.text = HealthCurrent.ToString() + "/" +HealthMax.ToString();
}
代码(PlayerController.cs):
...
// 定义角色血量
public int health;
// Start is called before the first frame update
private void Start()
{
...
HealthUI.HealthMax = health;
}
...
跑一下看看:
出现了一个BUG:运行之后HP没有进行初始化,或者说初始化失败,他没有显示满血状态 。
挨打之后,恢复正常,代表Update函数运行成功,能够改变血量条的变化和比值。
我寻思这是一个逻辑问题,首先,血量UI应该时依附于player的,Player这个角色和脚本在游戏开始时就应该初始化完成,当他初始化完成后,血量UI以及其他附属组件就应该可以去拿player里的值和组件了,而现在通过运行得知player初始化完成并且把血量给到了HP的静态变量中,但可以说UI的Start可能和player的是同一时间进行初始化的(因为都是第一帧,姑且这么认为),在第一帧就完成了,所以UI初始化时,HealthCurrent = HealthMax;拿到的其实是默认值,int变量默认值为0,所以我点击运行时他显示0/100,当受击后,他才调用到了player给的值,恢复了正常。
暴力解决办法:把player的优先级提高,让他提前完成初始化,把值给Hp,然后hp再进行初始化,这样就能解决,将player里的Start改成Awake即可。
推荐解决办法:不改变代码,点击脚本文件,打开项目设置,点击脚本执行顺序,将需要按照顺序执行的脚本都拖入这个框里,他的值越小就越快执行。
方法1解释:unity是个单线程作业的,所谓协程是一个类似多线程的,但他其实还是单线程执行,unity 脚本自带函数执行顺序如下:
Awake>OnEable>Start>FixedUpdate>Update>LateUpdate>OnGUI>Reset>OnDisable>OnDestroy
方法2截图:
BUG已修复。