更改数组中按下按钮的纹理 - Unity c#
Changing texture of pressed button in array - Unity c#
我正在创建一个按钮数组,我想创建一个按钮,这样当我单击一个按钮时,按钮的纹理就会发生变化。当我单击任何按钮时,我的代码会更改所有按钮的纹理。
有没有办法对其进行编码,以便在我单击一个按钮时该按钮的纹理从 texA 变为 texB 而其余按钮保持为 texA?
public Texture texA;
public Texture texB;
static Vector2[] loc = new Vector2[25];
bool visited = false;
void Start () {
int i = 0;
while (i < loc.Length){
loc [i] = new Vector2 (Random.Range (Screen.width * 0.1f, Screen.width * 0.9f), Random.Range(Screen.height * 0.1f, Screen.height * 0.9f));
i = i + 1;
}
}
void OnGUI(){
for (int i = 0; i < loc.Length; i++) {
if (GUI.Button (new Rect (loc [i].x, loc [i].y, Screen.width * 0.025f, Screen.height * 0.05f), visited ? texA:texB, "")) {
visited = !visited;
}
}
}
您应该避免使用 OnGUI,正如 Unity 团队自己所说,而是依赖新的 UI。
要解决您的问题,您应该这样做:
- 创建一个 Canvas,并附加脚本 CreateButtons;
- 在 Canvas 中创建一个按钮,将脚本 ChangeButtonSprite 附加到它上面,并在检查器字段中为其指定适当的 A 和 B 精灵。
- 在按钮上创建一个 OnClick 事件,将脚本 ChangeButtonSprite 传递给它,select
ChangeSprite()
方法,select 按钮本身的 Image
组件作为参数
- 将此按钮设为预制件,然后将其从层次结构中删除;
- 在Canvas的
Button Prefab
字段中,放置Button prefab
- 就是这样,您可能想 change/expand 了解如何生成位置、按钮的起始图像等,因为这只是一个关于如何使用 Unity UI OnClick 嵌入式事件(您甚至可以使用
onClick.AddListener
) 直接从脚本 ofc 拦截 OnClick 事件
CreateButtons.cs
using UnityEngine;
public class CreateButtons : MonoBehaviour {
public GameObject ButtonPrefab;
public int NumberOfButtons;
void Start () {
for (int i=0; i<NumberOfButtons; i++) {
Vector3 buttonPos = new Vector3 (Random.Range(0f, Screen.width), Random.Range(0f, Screen.height), 0);
GameObject buttonSpawned = Instantiate(ButtonPrefab, buttonPos, Quaternion.identity, gameObject.transform) as GameObject;
}
}
}
ChangeButtonSprite
using UnityEngine;
using UnityEngine.UI;
public class ChangeButtonSprite : MonoBehaviour {
public Sprite TexA,TexB;
void Start(){
GetComponent<Image>().sprite = TexA;
}
public void ChangeSprite(Image image){
if (image.sprite == TexA) {
image.sprite = TexB;
return;
}
image.sprite = TexA;
}
}
有很多方法可以做到这一点。您可以使用数据结构来存储有关被单击按钮的信息。最简单的方法是使用数组。
只需将 visited
变量制作成一个数组,然后用 visited[i]
替换所有使用它的地方。就是这样。
public Texture texA;
public Texture texB;
static Vector2[] loc = new Vector2[25];
bool[] visited = new bool[25];
void Start()
{
int i = 0;
while (i < loc.Length)
{
loc[i] = new Vector2(Random.Range(Screen.width * 0.1f, Screen.width * 0.9f), Random.Range(Screen.height * 0.1f, Screen.height * 0.9f));
i = i + 1;
}
}
void OnGUI()
{
for (int i = 0; i < loc.Length; i++)
{
if (GUI.Button(new Rect(loc[i].x, loc[i].y, Screen.width * 0.025f, Screen.height * 0.05f), visited[i] ? texA : texB, ""))
{
visited[i] = !visited[i];
}
}
}
这解决了您的问题,但您需要放弃当前代码并使用 Unity 的新 UI 系统以及 Button 组件及其事件系统。您可以了解有关新 UI 活动的更多信息 。
与新 UI:
public Texture texA;
public Texture texB;
const int buttonCount = 25;
public GameObject buttonPrefab;
public Canvas canvasForButtons;
Button[] buttons = new Button[buttonCount];
static Vector2[] loc = new Vector2[buttonCount];
bool[] visited = new bool[buttonCount];
void Start()
{
int i = 0;
while (i < loc.Length)
{
loc[i] = new Vector2(Random.Range(Screen.width * 0.1f, Screen.width * 0.9f), Random.Range(Screen.height * 0.1f, Screen.height * 0.9f));
i = i + 1;
}
createButtons();
}
void createButtons()
{
for (int i = 0; i < loc.Length; i++)
{
//Instantiate Button
GameObject tempButtonObj = Instantiate(buttonPrefab, canvasForButtons.transform) as GameObject;
Button tempButton = tempButtonObj.GetComponent<Button>();
buttons[i] = tempButton;
//Create rect for position
Rect buttonRect = new Rect(loc[i].x, loc[i].y, Screen.width * 0.025f, Screen.height * 0.05f);
//Assign Position of each Button
buttons[i].GetComponent<RectTransform>().position = buttonRect.position;
//buttons[i].GetComponent<RectTransform>().sizeDelta = buttonRect.size;
//Don't capture local variable
int tempIndex = i;
//Add click Event
buttons[i].onClick.AddListener(() => buttonClickCallBack(tempIndex));
}
}
//Called when Button is clicked
void buttonClickCallBack(int buttonIndex)
{
Debug.Log(buttonIndex);
//Get Texture to change
Texture textureToUse = visited[buttonIndex] ? texA : texB;
//Convert that Texture to Sprite
Sprite spriteToUse = Sprite.Create((Texture2D)textureToUse, new Rect(0.0f, 0.0f, textureToUse.width,
textureToUse.height), new Vector2(0.5f, 0.5f), 100.0f);
//Change the Button Image
buttons[buttonIndex].image.sprite = spriteToUse;
//Flip Image
visited[buttonIndex] = !visited[buttonIndex];
}
这是输出:
我正在创建一个按钮数组,我想创建一个按钮,这样当我单击一个按钮时,按钮的纹理就会发生变化。当我单击任何按钮时,我的代码会更改所有按钮的纹理。
有没有办法对其进行编码,以便在我单击一个按钮时该按钮的纹理从 texA 变为 texB 而其余按钮保持为 texA?
public Texture texA;
public Texture texB;
static Vector2[] loc = new Vector2[25];
bool visited = false;
void Start () {
int i = 0;
while (i < loc.Length){
loc [i] = new Vector2 (Random.Range (Screen.width * 0.1f, Screen.width * 0.9f), Random.Range(Screen.height * 0.1f, Screen.height * 0.9f));
i = i + 1;
}
}
void OnGUI(){
for (int i = 0; i < loc.Length; i++) {
if (GUI.Button (new Rect (loc [i].x, loc [i].y, Screen.width * 0.025f, Screen.height * 0.05f), visited ? texA:texB, "")) {
visited = !visited;
}
}
}
您应该避免使用 OnGUI,正如 Unity 团队自己所说,而是依赖新的 UI。
要解决您的问题,您应该这样做:
- 创建一个 Canvas,并附加脚本 CreateButtons;
- 在 Canvas 中创建一个按钮,将脚本 ChangeButtonSprite 附加到它上面,并在检查器字段中为其指定适当的 A 和 B 精灵。
- 在按钮上创建一个 OnClick 事件,将脚本 ChangeButtonSprite 传递给它,select
ChangeSprite()
方法,select 按钮本身的Image
组件作为参数 - 将此按钮设为预制件,然后将其从层次结构中删除;
- 在Canvas的
Button Prefab
字段中,放置Button prefab - 就是这样,您可能想 change/expand 了解如何生成位置、按钮的起始图像等,因为这只是一个关于如何使用 Unity UI OnClick 嵌入式事件(您甚至可以使用
onClick.AddListener
) 直接从脚本 ofc 拦截 OnClick 事件
CreateButtons.cs
using UnityEngine;
public class CreateButtons : MonoBehaviour {
public GameObject ButtonPrefab;
public int NumberOfButtons;
void Start () {
for (int i=0; i<NumberOfButtons; i++) {
Vector3 buttonPos = new Vector3 (Random.Range(0f, Screen.width), Random.Range(0f, Screen.height), 0);
GameObject buttonSpawned = Instantiate(ButtonPrefab, buttonPos, Quaternion.identity, gameObject.transform) as GameObject;
}
}
}
ChangeButtonSprite
using UnityEngine;
using UnityEngine.UI;
public class ChangeButtonSprite : MonoBehaviour {
public Sprite TexA,TexB;
void Start(){
GetComponent<Image>().sprite = TexA;
}
public void ChangeSprite(Image image){
if (image.sprite == TexA) {
image.sprite = TexB;
return;
}
image.sprite = TexA;
}
}
有很多方法可以做到这一点。您可以使用数据结构来存储有关被单击按钮的信息。最简单的方法是使用数组。
只需将 visited
变量制作成一个数组,然后用 visited[i]
替换所有使用它的地方。就是这样。
public Texture texA;
public Texture texB;
static Vector2[] loc = new Vector2[25];
bool[] visited = new bool[25];
void Start()
{
int i = 0;
while (i < loc.Length)
{
loc[i] = new Vector2(Random.Range(Screen.width * 0.1f, Screen.width * 0.9f), Random.Range(Screen.height * 0.1f, Screen.height * 0.9f));
i = i + 1;
}
}
void OnGUI()
{
for (int i = 0; i < loc.Length; i++)
{
if (GUI.Button(new Rect(loc[i].x, loc[i].y, Screen.width * 0.025f, Screen.height * 0.05f), visited[i] ? texA : texB, ""))
{
visited[i] = !visited[i];
}
}
}
这解决了您的问题,但您需要放弃当前代码并使用 Unity 的新 UI 系统以及 Button 组件及其事件系统。您可以了解有关新 UI 活动的更多信息
与新 UI:
public Texture texA;
public Texture texB;
const int buttonCount = 25;
public GameObject buttonPrefab;
public Canvas canvasForButtons;
Button[] buttons = new Button[buttonCount];
static Vector2[] loc = new Vector2[buttonCount];
bool[] visited = new bool[buttonCount];
void Start()
{
int i = 0;
while (i < loc.Length)
{
loc[i] = new Vector2(Random.Range(Screen.width * 0.1f, Screen.width * 0.9f), Random.Range(Screen.height * 0.1f, Screen.height * 0.9f));
i = i + 1;
}
createButtons();
}
void createButtons()
{
for (int i = 0; i < loc.Length; i++)
{
//Instantiate Button
GameObject tempButtonObj = Instantiate(buttonPrefab, canvasForButtons.transform) as GameObject;
Button tempButton = tempButtonObj.GetComponent<Button>();
buttons[i] = tempButton;
//Create rect for position
Rect buttonRect = new Rect(loc[i].x, loc[i].y, Screen.width * 0.025f, Screen.height * 0.05f);
//Assign Position of each Button
buttons[i].GetComponent<RectTransform>().position = buttonRect.position;
//buttons[i].GetComponent<RectTransform>().sizeDelta = buttonRect.size;
//Don't capture local variable
int tempIndex = i;
//Add click Event
buttons[i].onClick.AddListener(() => buttonClickCallBack(tempIndex));
}
}
//Called when Button is clicked
void buttonClickCallBack(int buttonIndex)
{
Debug.Log(buttonIndex);
//Get Texture to change
Texture textureToUse = visited[buttonIndex] ? texA : texB;
//Convert that Texture to Sprite
Sprite spriteToUse = Sprite.Create((Texture2D)textureToUse, new Rect(0.0f, 0.0f, textureToUse.width,
textureToUse.height), new Vector2(0.5f, 0.5f), 100.0f);
//Change the Button Image
buttons[buttonIndex].image.sprite = spriteToUse;
//Flip Image
visited[buttonIndex] = !visited[buttonIndex];
}
这是输出: