25. 制作血条的 UI Document

UI Toolkit

本项目使用 UI Toolkit 进行

HealthBar

通过 Create -> UI Toolkit -> UI Document 创建一个 HealthBar

在 HealthBar 里面,我们可以添加一个 Progress Bar 用于表示血条,然后将 ProgressBar 改成下面的样子,Anchors 向左 150 像素,向上 20 像素,宽度 300 像素

Panel Settings

Create -> UI Toolkit -> Panel Setting Asset,起名叫 Panel Settings

然后我们让它的 Scale Mode 为 Scale With Screen Size,分辨率改为 1920 x 1080,Match 改为 0.5

Player 添加插件

在 Player 上面,添加 UI Document 插件,其中 Panel Settings 和 Source Asset 是之前 UI Tookit 里创建好的资源

然后在 Player 下面添加一个子节点,用于表示血条的位置

最后在 Player 上面添加 HealthBarController 组件

HealthBarController 组件的代码如下

using UnityEngine;
using UnityEngine.UIElements;

public class HealthBarController : MonoBehaviour
{
    [Header("Elements")]
    public Transform healthBarTransform;
    private UIDocument healthBarDocument;
    private ProgressBar healthBar;

    private void Awake() 
    {
        healthBarDocument = GetComponent<UIDocument>();
        healthBar = healthBarDocument.rootVisualElement.Q<ProgressBar>("HealthBar");
        Debug.Log($"{healthBarTransform.position}");
        MoveToWorldPosition(healthBar, healthBarTransform.position, Vector2.zero);
    }

    private void OnEnable() 
    {
        healthBarDocument = GetComponent<UIDocument>();
        healthBar = healthBarDocument.rootVisualElement.Q<ProgressBar>("HealthBar");
        Debug.Log($"{healthBarTransform.position}");
        MoveToWorldPosition(healthBar, healthBarTransform.position, Vector2.zero);
    }

    private void MoveToWorldPosition(VisualElement element, Vector3 worldPosition, Vector2 size)
    {
        Rect rect = RuntimePanelUtils.CameraTransformWorldToPanelRect(element.panel, worldPosition, size, Camera.main);
        Debug.Log($"{rect.position}");
        element.transform.position = rect.position;
    }

    [ContextMenu("Get UI Position")]
    public void Test()
    {
        healthBarDocument = GetComponent<UIDocument>();
        healthBar = healthBarDocument.rootVisualElement.Q<ProgressBar>("HealthBar");
        Debug.Log($"{healthBarTransform.position}");
        MoveToWorldPosition(healthBar, healthBarTransform.position, Vector2.zero);
    }
}

这段代码中

在 Awake 的时候,获取 UIDocument 里面的 HealthBar,然后把它移动到 HealthBarTransform 所在的位置

为了方便调试,我们增加了 Test 方法,这样可以在没有运行的时候,也能在 HealthBarController 组件上面右键选择 Get UI Position 来显示血条的位置

但是这个方法好像有问题,群里的小伙伴都说 Awake 时的血条位置和 Test 时的血条位置不一致。老师让我在 OnEnable 里试试,我发现把 Player Disable 再 Enable 之后,血条位置也是不一样的。暂时无解

项目相关代码

代码仓库:https://gitee.com/nbda1121440/DreamOfTheKingdom.git

标签:20240305_2244

posted @ 2024-03-05 23:33  hellozjf  阅读(51)  评论(0编辑  收藏  举报