Sample project to showcase the use of UI Toolkit for Runtime based on the Unity Royale project.
您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

91 行
3.5 KiB

using System;
using UnityEngine;
using UnityEngine.UIElements;
namespace UnityRoyale
{
[RequireComponent(typeof(UIDocument))]
public class HealthBar : MonoBehaviour
{
private const string HiddenHealthBarStyleClass = "health-bar--hidden";
// Prefab properties
[SerializeField] private Vector3 unitAnchorPosition = new Vector3(0f, 3f, 0f);
[SerializeField] private Vector3 nonUnitAnchorPosition = new Vector3(1.8f, 2f, 0f);
[SerializeField] private Vector2 worldSize = new Vector2(1.2f, 0.6f);
[SerializeField] private Color red = new Color32(252, 35, 13, 255);
[SerializeField] private Color blue = new Color32(31, 132, 255, 255);
[SerializeField] private bool isHidden = true;
[HideInInspector] public float originalHealth;
[HideInInspector] public float currentHealth;
[HideInInspector] public Vector3 anchorPosition;
[HideInInspector] public Color barColor;
[HideInInspector] public Transform transformToFollow;
private VisualElement bar;
private VisualElement wholeWidget;
public void Initialize(ThinkingPlaceable p)
{
currentHealth = originalHealth = p.hitPoints;
anchorPosition = p.pType == Placeable.PlaceableType.Unit ? unitAnchorPosition : nonUnitAnchorPosition;
barColor = p.faction == Placeable.Faction.Player ? red : blue;
transformToFollow = p.transform;
}
void OnEnable()
{
var rootVisualElement = GetComponent<UIDocument>().rootVisualElement;
bar = rootVisualElement.Q("Bar");
wholeWidget = rootVisualElement.Q("HealthBar");
}
private void Start()
{
bar.style.unityBackgroundImageTintColor = barColor;
SetHealth(currentHealth);
}
public void SetHealth(float newHealth)
{
currentHealth = newHealth;
isHidden = newHealth >= originalHealth;
float ratio = newHealth > 0f ? newHealth / originalHealth : 1e-5f;
bar.transform.scale = new Vector3(ratio, 1, 1);
// Hide the health bar after the position is set, otherwise it won't hide.
wholeWidget.EnableInClassList(HiddenHealthBarStyleClass, isHidden);
}
private void Update()
{
wholeWidget.EnableInClassList(HiddenHealthBarStyleClass, isHidden);
}
// Wait for LateUpdate 1) to allow tracked object to move and
// 2) to leave time for wholeWidget.layout to be refreshed
private void LateUpdate()
{
if (!isHidden && transformToFollow != null)
{
MoveAndScaleToWorldPosition(wholeWidget, transformToFollow.position + anchorPosition, worldSize);
}
}
static void MoveAndScaleToWorldPosition(VisualElement element, Vector3 worldPosition, Vector2 worldSize)
{
Rect rect = RuntimePanelUtils.CameraTransformWorldToPanelRect(element.panel, worldPosition, worldSize, Camera.main);
Vector2 layoutSize = element.layout.size;
// Don't set scale to 0 or a negative number.
Vector2 scale = layoutSize.x > 0 && layoutSize.y > 0 ? rect.size / layoutSize : Vector2.one * 1e-5f;
element.transform.position = rect.position;
element.transform.scale = new Vector3(scale.x, scale.y, 1);
}
}
}