Unity C#中如何将脚本生成的Button数组传递给另一个脚本?
解决Unity中动态生成按钮数组传递给ScrollRectSnap脚本的问题
方案一:直接在YearManager中生成并传递按钮数组
通过在YearManager中收集生成的Button组件,直接赋值给ScrollRectSnap_CS的目标数组,同时调整ScrollRectSnap的初始化逻辑避免执行顺序问题:
修改后的YearManager脚本
using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.UI; public class YearManager : MonoBehaviour { public GameObject scrollViewContent; public GameObject buttonTemplate; public ScrollRectSnap_CS scrollSnap; // 在编辑器中拖拽赋值ScrollRectSnap_CS组件 public int initialYear = 1900; public int finalYear = 2023; void Start() { List<Button> generatedButtons = new List<Button>(); for (int i = initialYear; i < finalYear; i++) { GameObject button = Instantiate(buttonTemplate, scrollViewContent.transform); button.GetComponentInChildren<TextMeshProUGUI>().text = i.ToString(); button.name = i.ToString(); generatedButtons.Add(button.GetComponent<Button>()); // 收集每个按钮的Button组件 } // 将列表转为数组传递给ScrollRectSnap scrollSnap.bttn = generatedButtons.ToArray(); // 手动触发ScrollRectSnap的初始化 scrollSnap.Init(); } }
修改后的ScrollRectSnap_CS脚本
将原Start中的初始化逻辑移至公开方法,避免依赖启动顺序:
using System; using UnityEngine; using UnityEngine.UI; public class ScrollRectSnap_CS : MonoBehaviour { public RectTransform panel; public Button[] bttn; public RectTransform center; private float[] distance; private bool dragging = false; private int bttnDistance; private int minButtonNum; void Start() { // 空实现,改为手动调用Init方法 } public void Init() { if (bttn == null || bttn.Length < 2) { Debug.LogError("按钮数组未赋值或数量不足"); return; } int bttnLength = bttn.Length; distance = new float[bttnLength]; // 计算按钮间距 bttnDistance = (int)Math.Abs(bttn[1].GetComponent<RectTransform>().anchoredPosition.x - bttn[0].GetComponent<RectTransform>().anchoredPosition.x); Debug.Log("Button Distance = " + bttnDistance); } void Update() { if (bttn == null || bttn.Length == 0) return; for (int i = 0; i < bttn.Length; i++) { distance[i] = Mathf.Abs(center.transform.position.x - bttn[i].transform.position.x); } float minDistance = Mathf.Min(distance); for (int a = 0; a < bttn.Length; a++) { if (minDistance == distance[a]) { minButtonNum = a; } } if (!dragging) { LerpToBttn(minButtonNum * -bttnDistance); } } void LerpToBttn(int position) { float newX = Mathf.Lerp(panel.anchoredPosition.x, position, Time.deltaTime * 10f); Vector2 newPosition = new Vector2(newX, panel.anchoredPosition.y); panel.anchoredPosition = newPosition; } public void StartDrag() { dragging = true; } public void EndDrag() { dragging = false; } }
方案二:ScrollRectSnap自动获取子物体按钮
如果不想修改YearManager,可让ScrollRectSnap直接从Content物体下收集所有Button组件:
修改后的ScrollRectSnap_CS脚本
using System; using UnityEngine; using UnityEngine.UI; public class ScrollRectSnap_CS : MonoBehaviour { public RectTransform panel; public Button[] bttn; public RectTransform center; public GameObject scrollViewContent; // 在编辑器中拖拽赋值Content物体 private float[] distance; private bool dragging = false; private int bttnDistance; private int minButtonNum; void Start() { // 自动获取Content下所有Button组件(包含禁用物体) bttn = scrollViewContent.GetComponentsInChildren<Button>(true); if (bttn == null || bttn.Length < 2) { Debug.LogError("未找到足够的按钮"); return; } int bttnLength = bttn.Length; distance = new float[bttnLength]; bttnDistance = (int)Math.Abs(bttn[1].GetComponent<RectTransform>().anchoredPosition.x - bttn[0].GetComponent<RectTransform>().anchoredPosition.x); Debug.Log("Button Distance = " + bttnDistance); } // Update、LerpToBttn、StartDrag、EndDrag方法保持不变 }
使用说明
- 方案一需在编辑器中,将ScrollRectSnap_CS组件拖拽到YearManager的
scrollSnap字段。 - 方案二需在ScrollRectSnap_CS的
scrollViewContent字段赋值对应的Content物体。 - 确保按钮预制件上带有Button组件,否则无法被正确收集。
内容的提问来源于stack exchange,提问作者ni6hant
相关产品推荐
相关产品推荐

