上一篇:【unity】3.创建prefab和编写第一个script
逻辑梳理
上次卡在为button SetListener的位置,这次重新研究了一下,记录如下:
首先是自动在画布上生成规定数目的按钮,可以这样规定:
- 给定行和列,在Canvas中生成若干个上一节内容中预设好的按钮prefab,并且希望这些按钮能生成在画布中央
- 为每一个按钮设定它们所在的行和列值
- 为每一个按钮添加listener,使得点击时可以判断他们在什么位置
用代码在画布上生成按钮
首先是生成按钮的部分,代码如下:
public GameObject buttonPrefab;
public GameObject parentButtonPrefab;
int maxRow = 9;
int maxCol = 9;
void InitMines(int _maxRow, int _maxCol)
{
for (int i = 0; i < _maxRow; i++)
{
for (int j = 0; j < _maxCol; j++)
{
int _centerX = (int)(parentButtonPrefab.GetComponent<RectTransform>().rect.width / 2);
int _centerY = (int)(parentButtonPrefab.GetComponent<RectTransform>().rect.height / 2);
int _buttonSize = (int)(buttonPrefab.GetComponent<RectTransform>().rect.height);
Vector3 _pos = new Vector3(_centerX + (i - _maxRow / 2) * _buttonSize, _centerY + (j - _maxCol / 2) * _buttonSize);
GameObject _button = GameObject.Instantiate(buttonPrefab, _pos, Quaternion.identity, parentButtonPrefab.transform);
_button.GetComponent<MinesweeperButton>().SetRow(i);
_button.GetComponent<MinesweeperButton>().SetCol(j);
}
}
}
写完后在Hierarchy中点击GameLogic,会发现多了两个选项,将上一节中创建好的MinesweeperButton.prefab拖进去,然后定义parentButtonPrefab为Canvas
Canvas应该也可以通过find方法来在代码中指定,不过这里直接在GameLogic中定义了。代码的后半部分遍历行和列,计算每个按钮应在的位置,然后生成出来,并将这些按钮所在的行和列定义在它们身上。
为生成的按钮添加事件
生成后还需要为这些按钮添加事件,直接写在循环的最里面:
_button.GetComponent<Button>().onClick.AddListener(
delegate{
ClickMine(_button);
}
);
其中ClickMine是我们上一节中定义过的函数,这里发现不能直接在Listener中定义行和列,因此改为传递按钮进去,然后通过在按钮中取出所在位置来判断,函数更改如下:
private void ClickMine(GameObject _button)
{
int _row = _button.GetComponent<MinesweeperButton>().GetRow();
int _col = _button.GetComponent<MinesweeperButton>().GetCol();
Debug.Log("click: " + _row + ", " + _col + "");
}
完整代码和运行效果
完整代码如下:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class GameLogic : MonoBehaviour
{
public GameObject buttonPrefab;
public GameObject parentButtonPrefab;
int maxRow = 9;
int maxCol = 9;
int maxBomb = 10;
// Start is called before the first frame update
void Start()
{
InitMines(maxRow, maxCol);
}
public void SetMaxRow(int _row)
{
maxRow = _row;
}
public void SetMaxCol(int _col)
{
maxCol = _col;
}
void InitMines(int _maxRow, int _maxCol)
{
for (int i = 0; i < _maxRow; i++)
{
for (int j = 0; j < _maxCol; j++)
{
int _centerX = (int)(parentButtonPrefab.GetComponent<RectTransform>().rect.width / 2);
int _centerY = (int)(parentButtonPrefab.GetComponent<RectTransform>().rect.height / 2);
int _buttonSize = (int)(buttonPrefab.GetComponent<RectTransform>().rect.height);
Vector3 _pos = new Vector3(_centerX + (i - _maxRow / 2) * _buttonSize, _centerY + (j - _maxCol / 2) * _buttonSize);
GameObject _button = GameObject.Instantiate(buttonPrefab, _pos, Quaternion.identity, parentButtonPrefab.transform);
_button.GetComponent<MinesweeperButton>().SetRow(i);
_button.GetComponent<MinesweeperButton>().SetCol(j);
_button.GetComponent<Button>().onClick.AddListener(
delegate{
ClickMine(_button);
}
);
}
}
}
private void ClickMine(GameObject _button)
{
int _row = _button.GetComponent<MinesweeperButton>().GetRow();
int _col = _button.GetComponent<MinesweeperButton>().GetCol();
Debug.Log("click: " + _row + ", " + _col + "");
}
}
生成效果如下图
点击后在console中可以看到如下打印:
vscode添加unity扩展
顺便发现上次为vscode安装的unity扩展没生效,重新参考这篇教程和这篇教程又配置了一遍,记录如下:
- 确认扩展商店了安装并启用了.NET和C#扩展
- Unity > Window > Package Manager > 更新VSCode Editor插件
- Unity > Edit > Preferences > External Tools > 选择VSCode作为编辑器
- VSCode插件可以额外选择安装Unity Tools和Unity Code Snippets