服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - Unity3D实现甜品消消乐游戏

Unity3D实现甜品消消乐游戏

2022-12-14 12:00米莱虾 C#

这篇文章主要介绍了通过C# Unity3D绘制一个甜品消消乐游戏,文中的示例代码讲解详细,对我们学习或工作有一定的帮助,感兴趣的小伙伴可以学习一下

前言

解释:

之前用的ScreenToGif录屏,因为上传的.gif最大不超过5MB,所以做了不少删帧和色彩弱化等处理,这才导致色彩看上去不是很舒服,不要盯着它看太久,不然会有点难受...

由于使用的素材是现成的,没有花时间精力去扒,所以细节方面可能不是做的很好。

说明:

这次的甜品消消乐虽然看上去好像挺简单普通的,但是相对于之前的坦克大战,某种程度上已然提升难度了,归类到了算法类层的游戏。

拉到最后看代码你就能理解我的意思了,坦克大战的所有代码加起来还不如消消乐两个类的代码多,其他各种细节,坦克也只能望其项背...

如果坦克大战是低阶的,那么甜品消消乐就是中阶的,有着不少的动画效果和交互(碰撞检测和甜品的控制等),游戏运行的所有机制和功能需要在模型层上进行操控。

这次的消消乐需要一定的逻辑思维、算法基础、Unity综合能力和编程基础。

方正粗圆的字体和布灵布灵的闪光特效会赋予游戏可爱风的氛围感。

我们把物体分为模型层和渲染层,这样它们各司其职,降低工作的耦合性。

由于12.29日放假前还剩 两门课设答辩和一门考试,不足之处以后再补充...

项目效果展示

Unity3D实现甜品消消乐游戏

项目概况

素材展示

游戏资源(音频、图片、特效等)

Unity3D实现甜品消消乐游戏

场景和包(动画。渲染精灵和控制器等)

Unity3D实现甜品消消乐游戏

游戏脚本(UI、Runtime等)

Unity3D实现甜品消消乐游戏

Unity3D实现甜品消消乐游戏

......太多了,只选择了部分作为展示

场景展示

在Gizmos目录下,可以找到对应按钮隐藏摄像机,这样处理场景的时候会舒服很多

Clone都放上会有些杂乱,都删掉,只放了一个背景图

Unity3D实现甜品消消乐游戏

场景元素

开始按钮(玩家通过点击开始按钮,进入新的一局游戏)

重玩按钮(玩家可以及时返回开始界面进行相应操作)

时钟(显示游戏剩余时间,一局游戏初始化时间是60s)

计分板(显示当前游戏得分)

普通甜品(甜甜圈、糖果、起司...至少同时有3个在同一排或同一列时,可以消除)

特殊甜品(一定条件下会触发2种特殊甜品道具,一种是带有左右晃动特效的甜品,可以消除一整排的甜品;另一种是带有上下晃动特效的甜品,可以消除一整列的甜品)

积分面板(游戏时间结束后,会用类似飞跃的动画效果产生得分界面窗口,逐渐变大显示,最终定格。点击重玩立即开始下一局游戏,叉掉返回开始界面)

玩法介绍

  • 点击开始进入游戏,每一局新开的游戏设时60s(可以根据需要调整),用最快的速度消除出现在同一行或者同一列的相同的甜点会获得相应积分。
  • 尽量用最优的策略使得一定时间内的积分最大化(不过这一点,游戏玩熟了可能才能渐渐领悟,属于大师级别的操作了。可以用ACM相关算法写个外挂,应该是用动态规划算法处理)。
  • 当符合特定消除条件的甜品被消除后,会随机产生两类特殊甜品的一种,这个甜品会瞬间清除一整行或者一整列的甜品,使得积分暴增。
  • 相同时间内积分高者或者相同积分用时少者优胜。

版本说明

小虾选用的是Unity个人版,采用的是Unity一个较新的版本-2021.1.16,这里建议小伙伴们下载和教程相同版本的,不然真的会有可能遇到卡点消耗心情哈。

可以和我一样在Unity Hub里面安装,Hub感觉挺好用的。

但是每次重启后都要手动激活许可证,这是真的挺烦的。

Unity3D实现甜品消消乐游戏

项目源码

小虾在这里主要介绍部分核心代码实现,想知道其他部分实现的小伙伴在下方留言,我再添加~

UI-PropertyDrawers-MenuOptions.cs

using System;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using UnityEditor.Experimental.SceneManagement;
 
namespace UnityEditor.UI
{
    /// <summary>
    /// This script adds the UI menu options to the Unity Editor.
    /// </summary>
 
    static internal class MenuOptions
    {
        private const string kUILayerName = "UI";
 
        private const string kStandardSpritePath       = "UI/Skin/UISprite.psd";
        private const string kBackgroundSpritePath     = "UI/Skin/Background.psd";
        private const string kInputFieldBackgroundPath = "UI/Skin/InputFieldBackground.psd";
        private const string kKnobPath                 = "UI/Skin/Knob.psd";
        private const string kCheckmarkPath            = "UI/Skin/Checkmark.psd";
        private const string kDropdownArrowPath        = "UI/Skin/DropdownArrow.psd";
        private const string kMaskPath                 = "UI/Skin/UIMask.psd";
 
        static private DefaultControls.Resources s_StandardResources;
 
        static private DefaultControls.Resources GetStandardResources()
        {
            if (s_StandardResources.standard == null)
            {
                s_StandardResources.standard = AssetDatabase.GetBuiltinExtraResource<Sprite>(kStandardSpritePath);
                s_StandardResources.background = AssetDatabase.GetBuiltinExtraResource<Sprite>(kBackgroundSpritePath);
                s_StandardResources.inputField = AssetDatabase.GetBuiltinExtraResource<Sprite>(kInputFieldBackgroundPath);
                s_StandardResources.knob = AssetDatabase.GetBuiltinExtraResource<Sprite>(kKnobPath);
                s_StandardResources.checkmark = AssetDatabase.GetBuiltinExtraResource<Sprite>(kCheckmarkPath);
                s_StandardResources.dropdown = AssetDatabase.GetBuiltinExtraResource<Sprite>(kDropdownArrowPath);
                s_StandardResources.mask = AssetDatabase.GetBuiltinExtraResource<Sprite>(kMaskPath);
            }
            return s_StandardResources;
        }
 
        private class DefaultEditorFactory : DefaultControls.IFactoryControls
        {
            public static DefaultEditorFactory Default = new DefaultEditorFactory();
 
            public GameObject CreateGameObject(string name, params Type[] components)
            {
                return ObjectFactory.CreateGameObject(name, components);
            }
        }
 
        private class FactorySwapToEditor : IDisposable
        {
            DefaultControls.IFactoryControls factory;
 
            public FactorySwapToEditor()
            {
                factory = DefaultControls.factory;
                DefaultControls.factory = DefaultEditorFactory.Default;
            }
 
            public void Dispose()
            {
                DefaultControls.factory = factory;
            }
        }
 
        private static void SetPositionVisibleinSceneView(RectTransform canvasRTransform, RectTransform itemTransform)
        {
            SceneView sceneView = SceneView.lastActiveSceneView;
 
            // Couldn"t find a SceneView. Don"t set position.
            if (sceneView == null || sceneView.camera == null)
                return;
 
            // Create world space Plane from canvas position.
            Vector2 localPlanePosition;
            Camera camera = sceneView.camera;
            Vector3 position = Vector3.zero;
            if (RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRTransform, new Vector2(camera.pixelWidth / 2, camera.pixelHeight / 2), camera, out localPlanePosition))
            {
                // Adjust for canvas pivot
                localPlanePosition.x = localPlanePosition.x + canvasRTransform.sizeDelta.x * canvasRTransform.pivot.x;
                localPlanePosition.y = localPlanePosition.y + canvasRTransform.sizeDelta.y * canvasRTransform.pivot.y;
 
                localPlanePosition.x = Mathf.Clamp(localPlanePosition.x, 0, canvasRTransform.sizeDelta.x);
                localPlanePosition.y = Mathf.Clamp(localPlanePosition.y, 0, canvasRTransform.sizeDelta.y);
 
                // Adjust for anchoring
                position.x = localPlanePosition.x - canvasRTransform.sizeDelta.x * itemTransform.anchorMin.x;
                position.y = localPlanePosition.y - canvasRTransform.sizeDelta.y * itemTransform.anchorMin.y;
 
                Vector3 minLocalPosition;
                minLocalPosition.x = canvasRTransform.sizeDelta.x * (0 - canvasRTransform.pivot.x) + itemTransform.sizeDelta.x * itemTransform.pivot.x;
                minLocalPosition.y = canvasRTransform.sizeDelta.y * (0 - canvasRTransform.pivot.y) + itemTransform.sizeDelta.y * itemTransform.pivot.y;
 
                Vector3 maxLocalPosition;
                maxLocalPosition.x = canvasRTransform.sizeDelta.x * (1 - canvasRTransform.pivot.x) - itemTransform.sizeDelta.x * itemTransform.pivot.x;
                maxLocalPosition.y = canvasRTransform.sizeDelta.y * (1 - canvasRTransform.pivot.y) - itemTransform.sizeDelta.y * itemTransform.pivot.y;
 
                position.x = Mathf.Clamp(position.x, minLocalPosition.x, maxLocalPosition.x);
                position.y = Mathf.Clamp(position.y, minLocalPosition.y, maxLocalPosition.y);
            }
 
            itemTransform.anchoredPosition = position;
            itemTransform.localRotation = Quaternion.identity;
            itemTransform.localScale = Vector3.one;
        }
 
        private static void PlaceUIElementRoot(GameObject element, MenuCommand menuCommand)
        {
            GameObject parent = menuCommand.context as GameObject;
            bool explicitParentChoice = true;
            if (parent == null)
            {
                parent = GetOrCreateCanvasGameObject();
                explicitParentChoice = false;
 
                // If in Prefab Mode, Canvas has to be part of Prefab contents,
                // otherwise use Prefab root instead.
                PrefabStage prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
                if (prefabStage != null && !prefabStage.IsPartOfPrefabContents(parent))
                    parent = prefabStage.prefabContentsRoot;
            }
            if (parent.GetComponentsInParent<Canvas>(true).Length == 0)
            {
                // Create canvas under context GameObject,
                // and make that be the parent which UI element is added under.
                GameObject canvas = MenuOptions.CreateNewUI();
                Undo.SetTransformParent(canvas.transform, parent.transform, "");
                parent = canvas;
            }
 
            GameObjectUtility.EnsureUniqueNameForSibling(element);
 
            SetParentAndAlign(element, parent);
            if (!explicitParentChoice) // not a context click, so center in sceneview
                SetPositionVisibleinSceneView(parent.GetComponent<RectTransform>(), element.GetComponent<RectTransform>());
 
            // This call ensure any change made to created Objects after they where registered will be part of the Undo.
            Undo.RegisterFullObjectHierarchyUndo(parent == null ? element : parent, "");
 
            // We have to fix up the undo name since the name of the object was only known after reparenting it.
            Undo.SetCurrentGroupName("Create " + element.name);
 
            Selection.activeGameObject = element;
        }
 
        private static void SetParentAndAlign(GameObject child, GameObject parent)
        {
            if (parent == null)
                return;
 
            Undo.SetTransformParent(child.transform, parent.transform, "");
 
            RectTransform rectTransform = child.transform as RectTransform;
            if (rectTransform)
            {
                rectTransform.anchoredPosition = Vector2.zero;
                Vector3 localPosition = rectTransform.localPosition;
                localPosition.z = 0;
                rectTransform.localPosition = localPosition;
            }
            else
            {
                child.transform.localPosition = Vector3.zero;
            }
            child.transform.localRotation = Quaternion.identity;
            child.transform.localScale = Vector3.one;
 
            SetLayerRecursively(child, parent.layer);
        }
 
        private static void SetLayerRecursively(GameObject go, int layer)
        {
            go.layer = layer;
            Transform t = go.transform;
            for (int i = 0; i < t.childCount; i++)
                SetLayerRecursively(t.GetChild(i).gameObject, layer);
        }
 
        // Graphic elements
 
        [MenuItem("GameObject/UI/Text", false, 2000)]
        static public void AddText(MenuCommand menuCommand)
        {
            GameObject go;
            using (new FactorySwapToEditor())
                go = DefaultControls.CreateText(GetStandardResources());
            PlaceUIElementRoot(go, menuCommand);
        }
 
        [MenuItem("GameObject/UI/Image", false, 2001)]
        static public void AddImage(MenuCommand menuCommand)
        {
            GameObject go;
            using (new FactorySwapToEditor())
                go = DefaultControls.CreateImage(GetStandardResources());
            PlaceUIElementRoot(go, menuCommand);
        }
 
        [MenuItem("GameObject/UI/Raw Image", false, 2002)]
        static public void AddRawImage(MenuCommand menuCommand)
        {
            GameObject go;
            using (new FactorySwapToEditor())
                go = DefaultControls.CreateRawImage(GetStandardResources());
            PlaceUIElementRoot(go, menuCommand);
        }
 
        // Controls
 
        // Button and toggle are controls you just click on.
 
        [MenuItem("GameObject/UI/Button", false, 2030)]
        static public void AddButton(MenuCommand menuCommand)
        {
            GameObject go;
            using (new FactorySwapToEditor())
                go = DefaultControls.CreateButton(GetStandardResources());
            PlaceUIElementRoot(go, menuCommand);
        }
 
        [MenuItem("GameObject/UI/Toggle", false, 2031)]
        static public void AddToggle(MenuCommand menuCommand)
        {
            GameObject go;
            using (new FactorySwapToEditor())
                go = DefaultControls.CreateToggle(GetStandardResources());
            PlaceUIElementRoot(go, menuCommand);
        }
 
        // Slider and Scrollbar modify a number
 
        [MenuItem("GameObject/UI/Slider", false, 2033)]
        static public void AddSlider(MenuCommand menuCommand)
        {
            GameObject go;
            using (new FactorySwapToEditor())
                go = DefaultControls.CreateSlider(GetStandardResources());
            PlaceUIElementRoot(go, menuCommand);
        }
 
        [MenuItem("GameObject/UI/Scrollbar", false, 2034)]
        static public void AddScrollbar(MenuCommand menuCommand)
        {
            GameObject go;
            using (new FactorySwapToEditor())
                go = DefaultControls.CreateScrollbar(GetStandardResources());
            PlaceUIElementRoot(go, menuCommand);
        }
 
        // More advanced controls below
 
        [MenuItem("GameObject/UI/Dropdown", false, 2035)]
        static public void AddDropdown(MenuCommand menuCommand)
        {
            GameObject go;
            using (new FactorySwapToEditor())
                go = DefaultControls.CreateDropdown(GetStandardResources());
            PlaceUIElementRoot(go, menuCommand);
        }
 
        [MenuItem("GameObject/UI/Input Field", false, 2036)]
        public static void AddInputField(MenuCommand menuCommand)
        {
            GameObject go;
            using (new FactorySwapToEditor())
                go = DefaultControls.CreateInputField(GetStandardResources());
            PlaceUIElementRoot(go, menuCommand);
        }
 
        // Containers
 
        [MenuItem("GameObject/UI/Canvas", false, 2060)]
        static public void AddCanvas(MenuCommand menuCommand)
        {
            var go = CreateNewUI();
            SetParentAndAlign(go, menuCommand.context as GameObject);
            if (go.transform.parent as RectTransform)
            {
                RectTransform rect = go.transform as RectTransform;
                rect.anchorMin = Vector2.zero;
                rect.anchorMax = Vector2.one;
                rect.anchoredPosition = Vector2.zero;
                rect.sizeDelta = Vector2.zero;
            }
            Selection.activeGameObject = go;
        }
 
        [MenuItem("GameObject/UI/Panel", false, 2061)]
        static public void AddPanel(MenuCommand menuCommand)
        {
            GameObject go;
            using (new FactorySwapToEditor())
                go = DefaultControls.CreatePanel(GetStandardResources());
            PlaceUIElementRoot(go, menuCommand);
 
            // Panel is special, we need to ensure there"s no padding after repositioning.
            RectTransform rect = go.GetComponent<RectTransform>();
            rect.anchoredPosition = Vector2.zero;
            rect.sizeDelta = Vector2.zero;
        }
 
        [MenuItem("GameObject/UI/Scroll View", false, 2062)]
        static public void AddScrollView(MenuCommand menuCommand)
        {
            GameObject go;
            using (new FactorySwapToEditor())
                go = DefaultControls.CreateScrollView(GetStandardResources());
            PlaceUIElementRoot(go, menuCommand);
        }
 
        // Helper methods
 
        static public GameObject CreateNewUI()
        {
            // Root for the UI
            var root = ObjectFactory.CreateGameObject("Canvas", typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster));
            root.layer = LayerMask.NameToLayer(kUILayerName);
            Canvas canvas = root.GetComponent<Canvas>();
            canvas.renderMode = RenderMode.ScreenSpaceOverlay;
 
            // Works for all stages.
            StageUtility.PlaceGameObjectInCurrentStage(root);
            bool customScene = false;
            PrefabStage prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
            if (prefabStage != null)
            {
                Undo.SetTransformParent(root.transform, prefabStage.prefabContentsRoot.transform, "");
                customScene = true;
            }
 
            Undo.SetCurrentGroupName("Create " + root.name);
 
            // If there is no event system add one...
            // No need to place event system in custom scene as these are temporary anyway.
            // It can be argued for or against placing it in the user scenes,
            // but let"s not modify scene user is not currently looking at.
            if (!customScene)
                CreateEventSystem(false);
            return root;
        }
 
        [MenuItem("GameObject/UI/Event System", false, 2100)]
        public static void CreateEventSystem(MenuCommand menuCommand)
        {
            GameObject parent = menuCommand.context as GameObject;
            CreateEventSystem(true, parent);
        }
 
        private static void CreateEventSystem(bool select)
        {
            CreateEventSystem(select, null);
        }
 
        private static void CreateEventSystem(bool select, GameObject parent)
        {
            StageHandle stage = parent == null ? StageUtility.GetCurrentStageHandle() : StageUtility.GetStageHandle(parent);
            var esys = stage.FindComponentOfType<EventSystem>();
            if (esys == null)
            {
                var eventSystem = ObjectFactory.CreateGameObject("EventSystem");
                if (parent == null)
                    StageUtility.PlaceGameObjectInCurrentStage(eventSystem);
                else
                    SetParentAndAlign(eventSystem, parent);
                esys = ObjectFactory.AddComponent<EventSystem>(eventSystem);
                ObjectFactory.AddComponent<StandaloneInputModule>(eventSystem);
 
                Undo.RegisterCreatedObjectUndo(eventSystem, "Create " + eventSystem.name);
            }
 
            if (select && esys != null)
            {
                Selection.activeGameObject = esys.gameObject;
            }
        }
 
        // Helper function that returns a Canvas GameObject; preferably a parent of the selection, or other existing Canvas.
        static public GameObject GetOrCreateCanvasGameObject()
        {
            GameObject selectedGo = Selection.activeGameObject;
 
            // Try to find a gameobject that is the selected GO or one if its parents.
            Canvas canvas = (selectedGo != null) ? selectedGo.GetComponentInParent<Canvas>() : null;
            if (IsValidCanvas(canvas))
                return canvas.gameObject;
 
            // No canvas in selection or its parents? Then use any valid canvas.
            // We have to find all loaded Canvases, not just the ones in main scenes.
            Canvas[] canvasArray = StageUtility.GetCurrentStageHandle().FindComponentsOfType<Canvas>();
            for (int i = 0; i < canvasArray.Length; i++)
                if (IsValidCanvas(canvasArray[i]))
                    return canvasArray[i].gameObject;
 
            // No canvas in the scene at all? Then create a new one.
            return MenuOptions.CreateNewUI();
        }
 
        static bool IsValidCanvas(Canvas canvas)
        {
            if (canvas == null || !canvas.gameObject.activeInHierarchy)
                return false;
 
            // It"s important that the non-editable canvas from a prefab scene won"t be rejected,
            // but canvases not visible in the Hierarchy at all do. Don"t check for HideAndDontSave.
            if (EditorUtility.IsPersistent(canvas) || (canvas.hideFlags & HideFlags.HideInHierarchy) != 0)
                return false;
 
            return StageUtility.GetStageHandle(canvas.gameObject) == StageUtility.GetCurrentStageHandle();
        }
    }
}

Editor-EventSystem-EventTriggerEditors.cs

using System;
using UnityEngine;
using UnityEngine.EventSystems;
 
namespace UnityEditor.EventSystems
{
    [CustomEditor(typeof(EventTrigger), true)]
    public class EventTriggerEditor : Editor
    {
        SerializedProperty m_DelegatesProperty;
 
        GUIContent m_IconToolbarMinus;
        GUIContent m_EventIDName;
        GUIContent[] m_EventTypes;
        GUIContent m_AddButonContent;
 
        protected virtual void OnEnable()
        {
            m_DelegatesProperty = serializedObject.FindProperty("m_Delegates");
            m_AddButonContent = EditorGUIUtility.TrTextContent("Add New Event Type");
            m_EventIDName = new GUIContent("");
            // Have to create a copy since otherwise the tooltip will be overwritten.
            m_IconToolbarMinus = new GUIContent(EditorGUIUtility.IconContent("Toolbar Minus"));
            m_IconToolbarMinus.tooltip = "Remove all events in this list.";
 
            string[] eventNames = Enum.GetNames(typeof(EventTriggerType));
            m_EventTypes = new GUIContent[eventNames.Length];
            for (int i = 0; i < eventNames.Length; ++i)
            {
                m_EventTypes[i] = new GUIContent(eventNames[i]);
            }
        }
 
        public override void OnInspectorGUI()
        {
            serializedObject.Update();
            int toBeRemovedEntry = -1;
 
            EditorGUILayout.Space();
 
            Vector2 removeButtonSize = GUIStyle.none.CalcSize(m_IconToolbarMinus);
 
            for (int i = 0; i < m_DelegatesProperty.arraySize; ++i)
            {
                SerializedProperty delegateProperty = m_DelegatesProperty.GetArrayElementAtIndex(i);
                SerializedProperty eventProperty = delegateProperty.FindPropertyRelative("eventID");
                SerializedProperty callbacksProperty = delegateProperty.FindPropertyRelative("callback");
                m_EventIDName.text = eventProperty.enumDisplayNames[eventProperty.enumValueIndex];
 
                EditorGUILayout.PropertyField(callbacksProperty, m_EventIDName);
                Rect callbackRect = GUILayoutUtility.GetLastRect();
 
                Rect removeButtonPos = new Rect(callbackRect.xMax - removeButtonSize.x - 8, callbackRect.y + 1, removeButtonSize.x, removeButtonSize.y);
                if (GUI.Button(removeButtonPos, m_IconToolbarMinus, GUIStyle.none))
                {
                    toBeRemovedEntry = i;
                }
 
                EditorGUILayout.Space();
            }
 
            if (toBeRemovedEntry > -1)
            {
                RemoveEntry(toBeRemovedEntry);
            }
 
            Rect btPosition = GUILayoutUtility.GetRect(m_AddButonContent, GUI.skin.button);
            const float addButonWidth = 200f;
            btPosition.x = btPosition.x + (btPosition.width - addButonWidth) / 2;
            btPosition.width = addButonWidth;
            if (GUI.Button(btPosition, m_AddButonContent))
            {
                ShowAddTriggermenu();
            }
 
            serializedObject.ApplyModifiedProperties();
        }
 
        private void RemoveEntry(int toBeRemovedEntry)
        {
            m_DelegatesProperty.DeleteArrayElementAtIndex(toBeRemovedEntry);
        }
 
        void ShowAddTriggermenu()
        {
            // Now create the menu, add items and show it
            GenericMenu menu = new GenericMenu();
            for (int i = 0; i < m_EventTypes.Length; ++i)
            {
                bool active = true;
 
                // Check if we already have a Entry for the current eventType, if so, disable it
                for (int p = 0; p < m_DelegatesProperty.arraySize; ++p)
                {
                    SerializedProperty delegateEntry = m_DelegatesProperty.GetArrayElementAtIndex(p);
                    SerializedProperty eventProperty = delegateEntry.FindPropertyRelative("eventID");
                    if (eventProperty.enumValueIndex == i)
                    {
                        active = false;
                    }
                }
                if (active)
                    menu.AddItem(m_EventTypes[i], false, OnAddNewSelected, i);
                else
                    menu.AddDisabledItem(m_EventTypes[i]);
            }
            menu.ShowAsContext();
            Event.current.Use();
        }
 
        private void OnAddNewSelected(object index)
        {
            int selected = (int)index;
 
            m_DelegatesProperty.arraySize += 1;
            SerializedProperty delegateEntry = m_DelegatesProperty.GetArrayElementAtIndex(m_DelegatesProperty.arraySize - 1);
            SerializedProperty eventProperty = delegateEntry.FindPropertyRelative("eventID");
            eventProperty.enumValueIndex = selected;
            serializedObject.ApplyModifiedProperties();
        }
    }
}

Runtime-UIElements-ExecuteEvents.cs

using System;
using System.Collections.Generic;
using UnityEngine.Pool;
 
namespace UnityEngine.EventSystems
{
    public static class ExecuteEvents
    {
        public delegate void EventFunction<T1>(T1 handler, BaseEventData eventData);
 
        public static T ValidateEventData<T>(BaseEventData data) where T : class
        {
            if ((data as T) == null)
                throw new ArgumentException(String.Format("Invalid type: {0} passed to event expecting {1}", data.GetType(), typeof(T)));
            return data as T;
        }
 
        private static readonly EventFunction<IPointerMoveHandler> s_PointerMoveHandler = Execute;
 
        private static void Execute(IPointerMoveHandler handler, BaseEventData eventData)
        {
            handler.OnPointerMove(ValidateEventData<PointerEventData>(eventData));
        }
 
        private static readonly EventFunction<IPointerEnterHandler> s_PointerEnterHandler = Execute;
 
        private static void Execute(IPointerEnterHandler handler, BaseEventData eventData)
        {
            handler.OnPointerEnter(ValidateEventData<PointerEventData>(eventData));
        }
 
        private static readonly EventFunction<IPointerExitHandler> s_PointerExitHandler = Execute;
 
        private static void Execute(IPointerExitHandler handler, BaseEventData eventData)
        {
            handler.OnPointerExit(ValidateEventData<PointerEventData>(eventData));
        }
 
        private static readonly EventFunction<IPointerDownHandler> s_PointerDownHandler = Execute;
 
        private static void Execute(IPointerDownHandler handler, BaseEventData eventData)
        {
            handler.OnPointerDown(ValidateEventData<PointerEventData>(eventData));
        }
 
        private static readonly EventFunction<IPointerUpHandler> s_PointerUpHandler = Execute;
 
        private static void Execute(IPointerUpHandler handler, BaseEventData eventData)
        {
            handler.OnPointerUp(ValidateEventData<PointerEventData>(eventData));
        }
 
        private static readonly EventFunction<IPointerClickHandler> s_PointerClickHandler = Execute;
 
        private static void Execute(IPointerClickHandler handler, BaseEventData eventData)
        {
            handler.OnPointerClick(ValidateEventData<PointerEventData>(eventData));
        }
 
        private static readonly EventFunction<IInitializePotentialDragHandler> s_InitializePotentialDragHandler = Execute;
 
        private static void Execute(IInitializePotentialDragHandler handler, BaseEventData eventData)
        {
            handler.OnInitializePotentialDrag(ValidateEventData<PointerEventData>(eventData));
        }
 
        private static readonly EventFunction<IBeginDragHandler> s_BeginDragHandler = Execute;
 
        private static void Execute(IBeginDragHandler handler, BaseEventData eventData)
        {
            handler.OnBeginDrag(ValidateEventData<PointerEventData>(eventData));
        }
 
        private static readonly EventFunction<IDragHandler> s_DragHandler = Execute;
 
        private static void Execute(IDragHandler handler, BaseEventData eventData)
        {
            handler.OnDrag(ValidateEventData<PointerEventData>(eventData));
        }
 
        private static readonly EventFunction<IEndDragHandler> s_EndDragHandler = Execute;
 
        private static void Execute(IEndDragHandler handler, BaseEventData eventData)
        {
            handler.OnEndDrag(ValidateEventData<PointerEventData>(eventData));
        }
 
        private static readonly EventFunction<IDropHandler> s_DropHandler = Execute;
 
        private static void Execute(IDropHandler handler, BaseEventData eventData)
        {
            handler.OnDrop(ValidateEventData<PointerEventData>(eventData));
        }
 
        private static readonly EventFunction<IScrollHandler> s_ScrollHandler = Execute;
 
        private static void Execute(IScrollHandler handler, BaseEventData eventData)
        {
            handler.OnScroll(ValidateEventData<PointerEventData>(eventData));
        }
 
        private static readonly EventFunction<IUpdateSelectedHandler> s_UpdateSelectedHandler = Execute;
 
        private static void Execute(IUpdateSelectedHandler handler, BaseEventData eventData)
        {
            handler.OnUpdateSelected(eventData);
        }
 
        private static readonly EventFunction<ISelectHandler> s_SelectHandler = Execute;
 
        private static void Execute(ISelectHandler handler, BaseEventData eventData)
        {
            handler.OnSelect(eventData);
        }
 
        private static readonly EventFunction<IDeselectHandler> s_DeselectHandler = Execute;
 
        private static void Execute(IDeselectHandler handler, BaseEventData eventData)
        {
            handler.OnDeselect(eventData);
        }
 
        private static readonly EventFunction<IMoveHandler> s_MoveHandler = Execute;
 
        private static void Execute(IMoveHandler handler, BaseEventData eventData)
        {
            handler.OnMove(ValidateEventData<AxisEventData>(eventData));
        }
 
        private static readonly EventFunction<ISubmitHandler> s_SubmitHandler = Execute;
 
        private static void Execute(ISubmitHandler handler, BaseEventData eventData)
        {
            handler.OnSubmit(eventData);
        }
 
        private static readonly EventFunction<ICancelHandler> s_CancelHandler = Execute;
 
        private static void Execute(ICancelHandler handler, BaseEventData eventData)
        {
            handler.OnCancel(eventData);
        }
 
        public static EventFunction<IPointerMoveHandler> pointerMoveHandler
        {
            get { return s_PointerMoveHandler; }
        }
 
        public static EventFunction<IPointerEnterHandler> pointerEnterHandler
        {
            get { return s_PointerEnterHandler; }
        }
 
        public static EventFunction<IPointerExitHandler> pointerExitHandler
        {
            get { return s_PointerExitHandler; }
        }
 
        public static EventFunction<IPointerDownHandler> pointerDownHandler
        {
            get { return s_PointerDownHandler; }
        }
 
        public static EventFunction<IPointerUpHandler> pointerUpHandler
        {
            get { return s_PointerUpHandler; }
        }
 
        public static EventFunction<IPointerClickHandler> pointerClickHandler
        {
            get { return s_PointerClickHandler; }
        }
 
        public static EventFunction<IInitializePotentialDragHandler> initializePotentialDrag
        {
            get { return s_InitializePotentialDragHandler; }
        }
 
        public static EventFunction<IBeginDragHandler> beginDragHandler
        {
            get { return s_BeginDragHandler; }
        }
 
        public static EventFunction<IDragHandler> dragHandler
        {
            get { return s_DragHandler; }
        }
 
        public static EventFunction<IEndDragHandler> endDragHandler
        {
            get { return s_EndDragHandler; }
        }
 
        public static EventFunction<IDropHandler> dropHandler
        {
            get { return s_DropHandler; }
        }
 
        public static EventFunction<IScrollHandler> scrollHandler
        {
            get { return s_ScrollHandler; }
        }
 
        public static EventFunction<IUpdateSelectedHandler> updateSelectedHandler
        {
            get { return s_UpdateSelectedHandler; }
        }
 
        public static EventFunction<ISelectHandler> selectHandler
        {
            get { return s_SelectHandler; }
        }
 
        public static EventFunction<IDeselectHandler> deselectHandler
        {
            get { return s_DeselectHandler; }
        }
 
        public static EventFunction<IMoveHandler> moveHandler
        {
            get { return s_MoveHandler; }
        }
 
        public static EventFunction<ISubmitHandler> submitHandler
        {
            get { return s_SubmitHandler; }
        }
 
        public static EventFunction<ICancelHandler> cancelHandler
        {
            get { return s_CancelHandler; }
        }
 
        private static void GetEventChain(GameObject root, IList<Transform> eventChain)
        {
            eventChain.Clear();
            if (root == null)
                return;
 
            var t = root.transform;
            while (t != null)
            {
                eventChain.Add(t);
                t = t.parent;
            }
        }
 
        public static bool Execute<T>(GameObject target, BaseEventData eventData, EventFunction<T> functor) where T : IEventSystemHandler
        {
            var internalHandlers = ListPool<IEventSystemHandler>.Get();
            GetEventList<T>(target, internalHandlers);
            //  if (s_InternalHandlers.Count > 0)
            //      Debug.Log("Executinng " + typeof (T) + " on " + target);
 
            var internalHandlersCount = internalHandlers.Count;
            for (var i = 0; i < internalHandlersCount; i++)
            {
                T arg;
                try
                {
                    arg = (T)internalHandlers[i];
                }
                catch (Exception e)
                {
                    var temp = internalHandlers[i];
                    Debug.LogException(new Exception(string.Format("Type {0} expected {1} received.", typeof(T).Name, temp.GetType().Name), e));
                    continue;
                }
 
                try
                {
                    functor(arg, eventData);
                }
                catch (Exception e)
                {
                    Debug.LogException(e);
                }
            }
 
            var handlerCount = internalHandlers.Count;
            ListPool<IEventSystemHandler>.Release(internalHandlers);
            return handlerCount > 0;
        }
 
        /// <summary>
        /// Execute the specified event on the first game object underneath the current touch.
        /// </summary>
        private static readonly List<Transform> s_InternalTransformList = new List<Transform>(30);
 
        public static GameObject ExecuteHierarchy<T>(GameObject root, BaseEventData eventData, EventFunction<T> callbackFunction) where T : IEventSystemHandler
        {
            GetEventChain(root, s_InternalTransformList);
 
            var internalTransformListCount = s_InternalTransformList.Count;
            for (var i = 0; i < internalTransformListCount; i++)
            {
                var transform = s_InternalTransformList[i];
                if (Execute(transform.gameObject, eventData, callbackFunction))
                    return transform.gameObject;
            }
            return null;
        }
 
        private static bool ShouldSendToComponent<T>(Component component) where T : IEventSystemHandler
        {
            var valid = component is T;
            if (!valid)
                return false;
 
            var behaviour = component as Behaviour;
            if (behaviour != null)
                return behaviour.isActiveAndEnabled;
            return true;
        }
 
        /// <summary>
        /// Get the specified object"s event event.
        /// </summary>
        private static void GetEventList<T>(GameObject go, IList<IEventSystemHandler> results) where T : IEventSystemHandler
        {
            // Debug.LogWarning("GetEventList<" + typeof(T).Name + ">");
            if (results == null)
                throw new ArgumentException("Results array is null", "results");
 
            if (go == null || !go.activeInHierarchy)
                return;
 
            var components = ListPool<Component>.Get();
            go.GetComponents(components);
 
            var componentsCount = components.Count;
            for (var i = 0; i < componentsCount; i++)
            {
                if (!ShouldSendToComponent<T>(components[i]))
                    continue;
 
                // Debug.Log(string.Format("{2} found! On {0}.{1}", go, s_GetComponentsScratch[i].GetType(), typeof(T)));
                results.Add(components[i] as IEventSystemHandler);
            }
            ListPool<Component>.Release(components);
            // Debug.LogWarning("end GetEventList<" + typeof(T).Name + ">");
        }
 
        /// <summary>
        /// Whether the specified game object will be able to handle the specified event.
        /// </summary>
        public static bool CanHandleEvent<T>(GameObject go) where T : IEventSystemHandler
        {
            var internalHandlers = ListPool<IEventSystemHandler>.Get();
            GetEventList<T>(go, internalHandlers);
            var handlerCount = internalHandlers.Count;
            ListPool<IEventSystemHandler>.Release(internalHandlers);
            return handlerCount != 0;
        }
 
        /// <summary>
        /// Bubble the specified event on the game object, figuring out which object will actually receive the event.
        /// </summary>
        public static GameObject GetEventHandler<T>(GameObject root) where T : IEventSystemHandler
        {
            if (root == null)
                return null;
 
            Transform t = root.transform;
            while (t != null)
            {
                if (CanHandleEvent<T>(t.gameObject))
                    return t.gameObject;
                t = t.parent;
            }
            return null;
        }
    }
}

以上就是Unity3D实现甜品消消乐游戏的详细内容,更多关于Unity3D消消乐游戏的资料请关注服务器之家其它相关文章!

原文链接:https://blog.csdn.net/Luoxiaobaia/article/details/122006655

延伸 · 阅读

精彩推荐
  • C#C#正则过滤HTML标签并保留指定标签的方法

    C#正则过滤HTML标签并保留指定标签的方法

    这篇文章主要介绍了C#正则过滤HTML标签并保留指定标签的方法,涉及C#针对页面HTML元素正则匹配与替换相关操作技巧,需要的朋友可以参考下...

    蓝色水6822022-01-11
  • C#C#开发教程之FTP上传下载功能详解

    C#开发教程之FTP上传下载功能详解

    这篇文章主要为大家详细介绍了C#开发教程之FTP上传下载功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    持&恒6422021-12-31
  • C#C#获取HTML文本的第一张图片与截取内容摘要示例代码

    C#获取HTML文本的第一张图片与截取内容摘要示例代码

    在日常web开发的时候,经常会遇到需要获取保存的HTML文本中的第一张图片,并且截取内容摘要的效果,例如织梦的后台添加完详细内容后就是自动读取内容...

    C#教程网10932021-12-08
  • C#使用接口实现多继承的方法

    使用接口实现多继承的方法

    下面小编就为大家分享一篇c#使用接口实现多继承的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    杨明波(Leo Yang)8282022-02-17
  • C#c#中LINQ的基本用法实例

    c#中LINQ的基本用法实例

    语言集成查询 (LINQ) 是 Visual Studio 2008 和 .NET Framework 3.5 版中引入的一项创新功能。下面这篇文章主要给大家介绍了关于c#中LINQ的基本用法,需要的朋友可以...

    阡陌染6232022-03-09
  • C#C# 创建MDB数据库、并存放表格数据的案例

    C# 创建MDB数据库、并存放表格数据的案例

    这篇文章主要介绍了C# 创建MDB数据库、并存放表格数据的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    南方北先生11892022-10-27
  • C#c# EnumHelper枚举常用操作类

    c# EnumHelper枚举常用操作类

    在项目中需要把枚举填充到下拉框中,所以使用统一的方法实现,测试代码如下,需要的朋友可以参考下...

    C#教程网7202021-12-10
  • C#C#学习笔记整理_深入剖析构造函数、析构函数

    C#学习笔记整理_深入剖析构造函数、析构函数

    下面小编就为大家带来一篇C#学习笔记整理_深入剖析构造函数、析构函数。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来...

    C#教程网7492021-12-07