赞
踩
血条(Health Bar)的预制设计。具体要求如下
using System.Collections; using System.Collections.Generic; using UnityEngine; public class HealthBar : MonoBehaviour { public float healthUpperLimit; // 生命值上限 private float healthValue; // 当前的生命值 public bool restart; // 按R键让血量恢复原状 void Start() { healthUpperLimit = 4000.0F; healthValue = healthUpperLimit; restart = false; } void Update() { if(restart){ // 恢复原状 healthUpperLimit = 4000.0F; healthValue = healthUpperLimit; restart = false; } } public void Hurt(float h) { // 造成 h 点伤害 healthValue -= h; if(healthValue <= 0){ healthValue = 0; } } public void Heal(float h) { // 治疗 h 点 if(healthValue > 0){ healthValue += h; if(healthValue >= healthUpperLimit) { healthValue = healthUpperLimit; } } } void OnGUI() { GUIStyle healthTextStyle = new GUIStyle(); healthTextStyle.fontSize = 20; healthTextStyle.alignment = TextAnchor.MiddleCenter; if(healthValue < healthUpperLimit * 0.3) { GUI.color = Color.red; // 当血量少于上限的30%时,血条为红色 } else if(healthValue < healthUpperLimit * 0.6) { GUI.color = Color.yellow; // 当血量少于上限的60%时,血条为黄色 } else { GUI.color = Color.green; // “健康状况下”,血条为绿色 } // 用横向滚动条实现血条 GUI.HorizontalScrollbar(new Rect(30, 30, Screen.width - 60, 30), 0.0F, healthValue, 0.0F, healthUpperLimit); // 显示当前血量 GUI.Label(new Rect(30, 50, Screen.width - 60, 20), healthValue.ToString() + " / " + healthUpperLimit.ToString(), healthTextStyle); } }
UGUI代码:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class HealthBar2 : MonoBehaviour { public Slider slider; // 血条UGUI对象 public bool restart; void Start() { slider.maxValue = 4000.0F; // 血条对象血量上限 slider.minValue = 0F; // 血条对象血量下限 slider.value = slider.maxValue; // 当前血量 restart = false; } void Update() { // 面向摄像机,此时血条会发生抖动 // slider.direction = Slider.Direction.RightToLeft; // slider.transform.LookAt(Camera.main.transform.position); // 不是面向摄像机,而是面向游戏屏幕 slider.direction = Slider.Direction.LeftToRight; slider.transform.rotation = Camera.main.transform.rotation; if(restart){ // 重启 slider.maxValue = 4000.0F; slider.value = slider.maxValue; restart = false; } if(slider.value <= 0.3 * slider.maxValue) // 当血量少于上限的30%时,血条为红色 slider.fillRect.transform.GetComponent<Image>().color = Color.red; else if(slider.value <= 0.6 * slider.maxValue) // 当血量少于上限的60%时,血条为黄色 slider.fillRect.transform.GetComponent<Image>().color = Color.yellow; else // “健康情况”下,血条为绿色 slider.fillRect.transform.GetComponent<Image>().color = Color.green; } public void Hurt(float h) { //造成h点伤害 slider.value -= h; if(slider.value <= 0) slider.value = 0; } public void Heal(float h) { // 给予h点治疗 if(slider.value > 0){ slider.value += h; if(slider.value >= slider.maxValue) slider.value = slider.maxValue; } } }
其他控制代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public interface IUserAction {
void Restart();
void Hurt();
void Heal();
}
using System.Collections; using System.Collections.Generic; using UnityEngine; public class FirstController : MonoBehaviour, IUserAction { public HealthBar healthBar; public HealthBar2 healthBar2; // UGUI血条对象 public float hurt = 250F; public float heal = 1000F; void Start() { gameObject.AddComponent<HealthBar>(); healthBar = Singleton<HealthBar>.Instance; } void Update() { if(Input.GetKeyDown("f")) Hurt(); if(Input.GetKeyDown("h")) Heal(); if(Input.GetKeyDown("r")) Restart(); } public void Hurt() { healthBar.Hurt(hurt); healthBar2.Hurt(hurt); } public void Heal() { healthBar.Heal(heal); healthBar2.Heal(heal); } public void Restart() { healthBar.restart = true; healthBar2.restart = true; } }
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Singleton<T> : MonoBehaviour where T : MonoBehaviour { protected static T instance; public static T Instance { get { if (instance == null) { instance = (T)FindObjectOfType (typeof(T)); if (instance == null) { Debug.LogError ("An instance of " + typeof(T) + " is needed in the scene, but there is none."); } } return instance; } } }
在设计中,如果血条对象始终面向摄像机,此时血条会发生抖动,代码如下:
slider.direction = Slider.Direction.RightToLeft;
slider.transform.LookAt(Camera.main.transform.position);
实际上,血条对象不应该面向摄像机,而是面向游戏屏幕,这样才不会发生抖动。在下面代码中,如果下面设置血条 rotaion 与摄像机 rotation 一致,血条回翻转,我们看到的是血条的背面,所以血条变化应该自左向右。
slider.direction = Slider.Direction.LeftToRight;
slider.transform.rotation = Camera.main.transform.rotation;
不同的效果如下图所示:
面向摄像头 | 面向屏幕 |
---|---|
![]() |
创建空对象并挂在脚本 FirstController
创建一个Cube作为Boss(目的是让UGUI血条成为它的子对象),可以为Cube加上一个动画(CubeMove)模拟Boss的移动,同时设置一下摄像头的位置。
Cube | Main Camera |
---|
为Cube对象上添加一个UI对象 - Slider,改名为 HealthBarSlider。
设置 Canvas 的属性:包括Render Mode、Event Camera、Rect Transform(不设置 RenderMode 为 World Space 模式则 Rect Transform 无法修改)
修改 HealthBarSlider 的子对象 Background 和 FillArea,这样可以让 Slider 充满整个 Background。而子对象 Handle Slider Area 用不到,取消勾选它。
Background | FillArea |
---|
IMGUI
优点:
缺点:
样式比较单调,不能通过交互界面设计血条,布局比较麻烦。
每一帧都需要重算布局重新渲染UI组件,性能较低。
UGUI
优点:
缺点:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。