更改数组中按下按钮的纹理 - 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];
}

这是输出: