游戏开发之Unity学习(九)——IMGUI和UGUI实现血条

两种方式实现血条

分析两种实现的优缺点

IMGUI

官方提供的是OnGUI函数来开发UI界面,当然问题也比较多,首先不支持可视化开发,其次UI始终位于所有3D对象的上方,无法实现在UI上添加3D模型的效果。

IMGUI开发简单,仅需几行代码,但是IMGUI需要在将3D位置映射到屏幕位置后,如果对结果进行加减,会使得血条位置偏移过多。

UGUI

优点:
1. 首先,5.2版本之后,Unity逐渐将一部分UGUI的计算放到子线程去做,以此来缓解主线程的压力;
2. UGUI有锚点,更方便屏幕自适应。
UGUI尚未成熟,但毕竟是官方的,新出的unity5使用了全新的ab打包方式,看上去要封杀ngui的样子。
缺点:
1. UGUI如果人物过多,需要太多的canvas

一、使用IMGUI实现血条

IMGUI实现

将下面的脚本挂载在游戏对象上就行了

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

public class IMGUI : MonoBehaviour {
    public float healthPanelOffset = 2f;
    private void OnGUI()
    {
        Vector3 worldPos = new Vector3(transform.position.x, transform.position.y, transform.position.z);
        Vector2 screenPos = Camera.main.WorldToScreenPoint(worldPos);
        Rect rect = new Rect(screenPos.x -50,screenPos.y,100,100);
        GUI.HorizontalScrollbar(rect, 0, 75, 0, 100);
    }
}

UGUI实现

  1. 首先,通过菜单 Assets -> Import Package -> Characters 导入资源
  2. 在层次视图,Context 菜单 -> 3D Object -> Plane 添加 Plane 对象
  3. 资源视图展开 Standard Assets :: Charactors :: ThirdPersonCharater :: Prefab
  4. 将 ThirdPersonController 预制拖放放入场景,改名为 Ethan
  5. 检查以下属性
    1. Plane 的 Transform 的 Position = (0,0,0)
    2. Ethan 的 Transform 的 Position = (0,0,0)
    3. Main Camera 的 Transform 的 Position = (0,1,-10)
  6. 选择 Ethan 用上下文菜单 -> UI -> Canvas, 添加画布子对象
    这里写图片描述
  7. 选择 Ethan 的 Canvas,用上下文菜单 -> UI -> Slider 添加滑条作为血条子对象
  8. 选择 Ethan 的 Canvas,在 Inspector 视图
  9. 展开 Slider
    1. 选择 Handle Slider Area,禁灰(disable)该元素
    2. 选择 Background,禁灰(disable)该元素
    3. 选择 Fill Area 的 Fill,修改 Image 组件的 Color 为 红色
  10. 选择 Slider 的 Slider 组件
    1. 设置 MaxValue 为 100
    2. 设置 Value 为 75

将下面的脚本挂载在ethen上

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

public class UIScript : MonoBehaviour {
    public Canvas canvas;
    public GameObject healthPrefab;

    public float healthPanelOffset = 2f;
    public GameObject healthPanel;
    private Slider healthSlider;

    // Use this for initialization
    void Start () {
        healthPanel = Instantiate(healthPrefab) as GameObject;
        healthPanel.transform.SetParent(canvas.transform, false);
        healthSlider = healthPanel.GetComponentInChildren<Slider>();
        Vector3 worldPos = new Vector3(transform.position.x, transform.position.y + healthPanelOffset, transform.position.z);
        Vector3 screenPos = Camera.main.WorldToScreenPoint(worldPos);
        healthPanel.transform.position = new Vector3(screenPos.x, screenPos.y, screenPos.z);
    }

    // Update is called once per frame
    void Update () {
        Vector3 worldPos = new Vector3(transform.position.x, transform.position.y + healthPanelOffset, transform.position.z);
        Vector3 screenPos = Camera.main.WorldToScreenPoint(worldPos);
        healthPanel.transform.position = new Vector3(screenPos.x, screenPos.y, screenPos.z);
    }
}

两种方法的实现效果及代码包地址

这里写图片描述

视频演示地址:演示视频
更多代码请戳:传送门

猜你喜欢

转载自blog.csdn.net/JC2474223242/article/details/80584980