Unity:复制带有事件的按钮

时间:2019-01-22 17:18:16

标签: c# unity3d events

在事件中单击“ +”时,我需要创建另一个按钮预制件。这样,该按钮的图标便更改为我已在事件中放置的图标。 我需要为此写些什么?

这是您可以使用的变量名。

public Button PrefabButton;
public Image[] ButtonIcon;
Event CopyEvent;

我应该怎么写才能得到像这样的事件

here

1 个答案:

答案 0 :(得分:0)

您在屏幕快照中描述并显示的实际上不是事件,而是ReorderableList

这只能由某些复杂的CustomEditor scripting归档。另请参见TutorialAPI

我想了解的是为每个按钮定义按钮设置,包括Spritestring标签和UnityEvent来调用onclick:

    using System;
    using System.Collections.Generic;
#if UNITY_EDITOR
    using UnityEditor;
    using UnityEditorInternal;
#endif
    using UnityEngine;
    using UnityEngine.Events;
    using UnityEngine.UI;

    public class ButtonSpawner : MonoBehaviour   
    {
        // a class for storing those settings
        [Serializable]
        private class ButtonSetting
        {
            public UnityEvent UnityEvent;
            public Sprite Sprite;
            public string Label;
        }

        // the list we want to make a custom editor for
        [SerializeField] private List<ButtonSetting> buttonSettings = new List<ButtonSetting>();

        // a prefab for buttons in general
        [SerializeField] private Button buttonPrefab;

        // e.g. use the data for spawning the prefab with given settings
        [ContextMenu("Instantiate Buttons")]
        public void InstantiateButtons()
        {
            foreach (var settings in buttonSettings)
            {
                // Spawn button prefab
                var newButton = Instantiate(buttonPrefab);

                // Set onClick callback
                var callback = settings .UnityEvent;
                newButton.onClick.AddListener(() => callback.Invoke());

                // Change the image if available
                var image = newButton.GetComponentInChildren<Image>(true);
                if(image && settings.Sprite)
                {
                    image.sprite = settings.Sprite;
                }

                // Set the label if available                  
                var labelText = newButton.GetComponentInChildren<Text>(true);
                if(labelText && !string.IsNullOrEmpty(settings.Label)
                {
                    labelText.text = settings .Label;
                }
            }
        }
    }

#if UNITY_EDITOR
    [CustomEditor(typeof(ButtonSpawner))]
    public class ButtonSpawnerInspector : Editor
    {
        private SerializedProperty _buttonSettings;
        private SerializedProperty _buttonPrefab;

        private ReorderableList _list;

        private void OnEnable()
        {
            _buttonSettings = serializedObject.FindProperty("buttonSettings");
            _buttonPrefab = serializedObject.FindProperty("buttonPrefab");

            _list = new ReorderableList(serializedObject, _buttonSettings)
            {
                displayAdd = true,
                displayRemove = true,
                draggable = true,
                drawHeaderCallback = rect =>
                {
                    EditorGUI.LabelField(rect, "Button settings");
                },
                drawElementCallback = (rect, index, h, a) =>
                {
                    var element = _buttonSettings.GetArrayElementAtIndex(index);

                    var unityEvent = element.FindPropertyRelative("UnityEvent");
                    var sprite = element.FindPropertyRelative("Sprite");
                    var label = element.FindPropertyRelative("Label");

                    EditorGUI.PropertyField(new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight), label);
                    rect.y += EditorGUIUtility.singleLineHeight;
                    EditorGUI.PropertyField(new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight), sprite);
                    rect.y += EditorGUIUtility.singleLineHeight;
                    EditorGUI.PropertyField(rect, unityEvent);
                },
                elementHeightCallback = index =>
                {
                    var element = _buttonSettings.GetArrayElementAtIndex(index);

                    var unityEvent = element.FindPropertyRelative("UnityEvent");
                    var sprite = element.FindPropertyRelative("Sprite");
                    var label = element.FindPropertyRelative("Label");

                    return EditorGUI.GetPropertyHeight(unityEvent) + EditorGUI.GetPropertyHeight(sprite) + EditorGUI.GetPropertyHeight(label) + EditorGUIUtility.singleLineHeight;
                }
            };
        }

        public override void OnInspectorGUI()
        {
            DrawScriptField();

            serializedObject.Update();

            EditorGUILayout.PropertyField(_buttonPrefab);

            _list.DoLayoutList();

            serializedObject.ApplyModifiedProperties();
        }

        // draw the default list field
        private void DrawScriptField()
        {
            EditorGUI.BeginDisabledGroup(true);
            EditorGUILayout.ObjectField("Script:", MonoScript.FromMonoBehaviour((ButtonSpawner)target), typeof(ButtonSpawner), false);
            EditorGUI.EndDisabledGroup();
        }
    }
#endif

请在链接中找到编辑器脚本的详细说明。如果我以后有空,我也可以在这里详细介绍。


结果:

enter image description here

默认情况下,您会看到最后一项的值被复制到新添加的项中。