You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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方法保持不变
}

使用说明

  1. 方案一需在编辑器中,将ScrollRectSnap_CS组件拖拽到YearManager的scrollSnap字段。
  2. 方案二需在ScrollRectSnap_CS的scrollViewContent字段赋值对应的Content物体。
  3. 确保按钮预制件上带有Button组件,否则无法被正确收集。

内容的提问来源于stack exchange,提问作者ni6hant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 04:57:46