3D遊戲程式設計作業第九章 UI系統

Ares_Xy發表於2020-12-27

使用 UGUI 實現血條

使用UGUI時,血條是遊戲物件的一個子元素。

過程

  1. 先新建一個plane,gameobject->3Dobject->plane

  2. 匯入資源包Standard Assets中的Characters部分

  3. 將 ThirdPersonController 預製拖入場景,屬性為:
    Plane 的 Transform 的 Position = (0,0,0)
    ThirdPersonController 的 Transform 的 Position = (0,0,0),Rotation = (0,180,0)
    ThirdPersonController 的 Scale(2,2,2),
    Main Camera 的 Transform 的 Position = (0,3,-10)

  4. 選擇 ThirdPersonController 用上下文選單(滑鼠右鍵) -> UI -> Canvas,新增畫布子物件

  5. 選擇 ThirdPersonController 的 Canvas,用上下文選單 -> UI -> Slider,新增滑條作為血條子物件

  6. 選擇 Ethan 的 Canvas,在 Inspector 檢視設定屬性:
    設定 Canvas 元件 Render Mode 為 World Space
    設定 Rect Transform 元件的 (PosX, PosY, Width, Height) 為 (0,2,2,1)
    設定 Rect Transform 元件的 Scale(x, y)為 (0.5,0.5)

  7. 展開 Slider
    選擇 Background,修改 Image 元件的 Color 為 紅色
    選擇Handle Slide Area,在 Inspector 檢視把勾勾取消掉

  8. 選擇Slider,在 Inspector 檢視
    設定 Rect Transform 元件的Rotation = (0,180,0)
    設定 Rect Transform元件的Pos(x,y,z,width,height)=(0,0,0,160,20)
    設定Slider 元件的 MaxValue 為 1
    設定normal color為紅色

  9. 執行檢查結果,發現人物運動時(用方向鍵控制),血條會跟著人物旋轉,沒有面對主攝像機。
    在這裡插入圖片描述

  10. 故需要給 Canvas 新增以下指令碼 LookAtCamera.cs

using UnityEngine;

public class LookAtCamera : MonoBehaviour
{
    void Update()
    {
        this.transform.LookAt(Camera.main.transform.position);
    }
}
  1. 將指令碼拖入Canvas物件,執行,這個時候血條就會一直面向主攝像機了。
    在這裡插入圖片描述

使用 IMGUI 實現血條

程式碼如下

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class bloodBar_script : MonoBehaviour {
    public float curBlood = 10f;
    private float targetBlood = 10f;
    private Rect bloodBarArea;
    private Rect addButton;
    private Rect minusButton;
    private Rect num1;
    private Rect num2;
    private Rect num3;
    private bool status;
 
    void Start () {
        bloodBarArea = new Rect(Screen.width - 220, 20, 200, 50);
        addButton = new Rect(Screen.width - 220, 50, 40, 20);
        minusButton = new Rect(Screen.width - 60, 50, 40, 20);
        num1 = new Rect(Screen.width - 220, 80, 40, 20);
        num2 = new Rect(Screen.width - 140, 80, 40, 20);
        num3 = new Rect(Screen.width - 60, 80, 40, 20);
	}
 
    public void addBlood(float num) {
        targetBlood = targetBlood + num > 10f? 10f : targetBlood + num;
    }
 
    public void minusBlood(float num) {
        targetBlood = targetBlood - num < 0f? 0f : targetBlood - num;
    }
 
    private void OnGUI() {
        if (GUI.Button(addButton, " + ")) status = true;
        if (GUI.Button(minusButton, " - ")) status = false;
        if (status) {
            if (GUI.Button(num1, " 1 ")) addBlood(1);
            if (GUI.Button(num2, " 2 ")) addBlood(2);
            if (GUI.Button(num3, " 3 ")) addBlood(3);
        }
        else {
            if (GUI.Button(num1, " 1 ")) minusBlood(1);
            if (GUI.Button(num2, " 2 ")) minusBlood(2);
            if (GUI.Button(num3, " 3 ")) minusBlood(3);
        }
        curBlood = Mathf.Lerp(curBlood, targetBlood, 0.1f);
        GUI.HorizontalScrollbar(bloodBarArea, 0f, curBlood, 0f, 10f);
    }
}

建立一個空物件,將程式碼掛到空物件上執行即可。
在這裡插入圖片描述

分析兩種實現的優缺點

UGUI

優點
視覺化,所見即所得(WYSIWYG)設計工具,設計師也能參與程式開發,支援多模式、多攝像機渲染,UI 元素與遊戲場景融為一體的互動,UGUI的控制元件是以“遊戲物件”的形式存在與遊戲場景中,這樣直觀易於使用,直接可以在Scene檢視中編輯大小、位置、旋轉角度、縮放等等,不需要手動寫任何程式碼。

IMGUI

優點
實現簡單,比如繪製一個控制元件,只需要GUI.Lable()、GUI.Button()這樣即可,不需要使用UI元件,很容易上手。IMGUI的存在符合遊戲程式設計的傳統,在修改模型,渲染模型這樣的經典遊戲迴圈程式設計模式中,在渲染階段之後,繪製 UI 介面無可挑剔。避免了 UI 元素保持在螢幕最前端,又有最佳的執行效率,一切控制掌握在程式設計師手中,這對早期計算和儲存資源貧乏的遊戲裝置來說,更是彌足珍貴。

缺點:
IMGUI系統通常不打算用於玩家可能使用並與之互動的普通遊戲內使用者介面,不利於佈局,在協調物件之間的位置關係的時候會很麻煩,這樣維護起來也會很困難。傳統程式碼驅動的 UI 面臨效率低下。

預製的使用方法

  1. 在Project視窗新建資料夾Resources,在Resources裡面新建資料夾Prefabs。
  2. 然後將Ethan裡面的Canvas物件拖曳到Prefabs裡面製作成預製體,重新命名為UGUI_HealthBar,將IMGUI_HealthBar也拖曳下來。
  3. 使用Prefabs裡面的UGUI_HealthBar預製體制作血條:給Ethan新增LoadResources.cs指令碼
using UnityEngine;

public class LoadResources : MonoBehaviour {
    private void OnEnable()
    {
        if(gameObject.name == "Ethan")
        {
            Canvas canvas = Instantiate(Resources.Load("Prefabs/UGUI_HealthBar", typeof(Canvas)), Vector3.zero, Quaternion.identity, null) as Canvas;
            canvas.gameObject.SetActive(true);
            canvas.gameObject.transform.SetParent(this.transform);
        }
        else
        {
            GameObject gameObject = Instantiate(Resources.Load("Prefabs/IMGUI_HealthBar", typeof(GameObject)), Vector3.zero, Quaternion.identity, null) as GameObject;
            gameObject.SetActive(true);
        }
    }
}
  1. 使用Prefabs裡面的IMGUI_HealthBar預製體制作血條:在Hierachy視窗新增一個空物件Main,新增指令碼LoadResources.cs。

相關文章