我的UI上有很多元素。我想改变整个UI的颜色。基本上就像一个新的"皮肤"我的HUD/菜单在游戏中。最好的方法是什么?在UIBuilder中,我可以选择一个选择器类并改变颜色,它适用于所有元素。我如何在运行时做到这一点?我已经研究了USS变量,但它看起来不像我可以在运行时使用c#编辑那些。
我看到的最简单的答案是创建一个UIManager
类并将其放置在场景中。
你的UI管理器将有一个实例,从而使它成为一个单例,这里是代码,应该在你的UI管理器
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
public class UIManager : MonoBehaviour
{
public static Singleton Instance { get; private set; }
public Color[] skinColours;
private void Awake()
{
// If there is an instance, and it's not me, delete myself.
if (Instance != null && Instance != this)
{
Destroy(this);
}
else
{
Instance = this;
}
}
public void ReskinUI(int skinIndex)
{
// Repeat this for RawImages, Buttons etc.
foreach (Image image in GameObject.FindObjectsOfType<Image>())
{
image.color = skinColours[skinIndex];
}
}
}
在你定义了你的UIManager
之后,你可以像这样在你的代码中使用它。
UIManager.Instance.ReskinUI(1);
这里的"1",对应皮肤指数
如果有帮助请告诉我
不确定你在UI上放置了什么,但通常只有两种,原始图像和图像。
步骤1。创建一个脚本来收集图像和/或原始图像,并存储指向它们的链接步骤2。改变这些图像的颜色。步骤3。确保其他东西可以抓取你的代码来改变颜色
步骤1:
/// <summary>
/// Gets all the images attached
/// </summary>
private void GetAllImagesInChildren()
{
allGraphics = new List<Graphic>();
foreach (Transform child in transform)
{
var image = child.gameObject.GetComponent<Image>();
if (image)
{
allGraphics.Add(image);
}
else
{
var rawImage = child.gameObject.GetComponent<RawImage>();
if (rawImage)
{
allGraphics.Add(rawImage);
}
}
}
}
Image和Raw Image都是"图形"类型,它们都有颜色属性。接下来只需使用GetComponent。尽可能少地使用GetComponent也是一个很好的实践因此存储该值。如果您只使用RawImages,请随意切换顺序。
步骤2:
/// <summary>
/// All raw images and images.
/// </summary>
private List<Graphic> allGraphics;
// Start is called before the first frame update
void Awake()
{
GetAllImagesInChildren();
}
/// <summary>
/// Sets the Color of all the UI elements attached
/// </summary>
/// <param name="newColor">New color</param>
public void SetUIColor(Color newColor)
{
foreach(Graphic graphic in allGraphics)
{
graphic.color = newColor;
}
}
让我们将第一步中的方法附加到一个新脚本中,私下存储图形并在awake时调用它。然后,因为图形现在是私有的,创建一个简单的公共方法,它只使用我们存储的值。你可以很容易地用Color32重载它,只需复制并粘贴方法。
所有在一起:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UIColourChanger : MonoBehaviour
{
/// <summary>
/// All raw images and images.
/// </summary>
private List<Graphic> allGraphics;
// Start is called before the first frame update
void Awake()
{
GetAllImagesInChildren();
}
/// <summary>
/// Sets the Color of all the UI elements attached
/// </summary>
/// <param name="newColor">New color</param>
public void SetUIColor(Color newColor)
{
foreach(Graphic graphic in allGraphics)
{
graphic.color = newColor;
}
}
/// <summary>
/// Gets all the images attached
/// </summary>
private void GetAllImagesInChildren()
{
allGraphics = new List<Graphic>();
foreach (Transform child in transform)
{
var image = child.gameObject.GetComponent<Image>();
if (image)
{
allGraphics.Add(image);
}
else
{
var rawImage = child.gameObject.GetComponent<RawImage>();
if (rawImage)
{
allGraphics.Add(rawImage);
}
}
}
}
}
然后存储附加到该脚本的对象的子对象。然后加上:
public UIColourChanger ColorChanger;
或
[SerializeField]
private UIColourChanger colorChanger
到任何其他脚本,并将此脚本拖到其中以获得对该公共方法的访问权。