From 389b45cf9931f7e719d855ef45ce4e4c4fe40557 Mon Sep 17 00:00:00 2001 From: Steven Lai <2061455536@qq.com> Date: Sun, 23 Feb 2025 19:03:58 +0800 Subject: [PATCH] Update README --- EasyInteractive/Example/Scripts/DragToUI.cs | 6 +- EasyInteractive/Example/Scripts/SceneItem.cs | 2 - EasyInteractive/Example/Scripts/Table.cs | 1 + EasyInteractive/Example/Scripts/UIItem.cs | 6 +- InteractiveSystem.png | Bin 0 -> 47967 bytes InteractiveSystem.png.meta | 114 +++++++++++++++++++ README.md | 104 +++++++++++++++++ 7 files changed, 228 insertions(+), 5 deletions(-) create mode 100644 InteractiveSystem.png create mode 100644 InteractiveSystem.png.meta diff --git a/EasyInteractive/Example/Scripts/DragToUI.cs b/EasyInteractive/Example/Scripts/DragToUI.cs index f2b82cd..fa098bb 100644 --- a/EasyInteractive/Example/Scripts/DragToUI.cs +++ b/EasyInteractive/Example/Scripts/DragToUI.cs @@ -9,6 +9,7 @@ using UnityEngine; public class DragToUI : DragSubjectFocusTargetInteractCase { private SceneItem sceneItem; + private UIItem uiItem; public DragToUI(Type subject, Type target) : base(subject, target) { } @@ -16,14 +17,15 @@ public class DragToUI : DragSubjectFocusTargetInteractCase { Debug.Log("Enter Case"); sceneItem = (subject as SceneItem); + uiItem = (target as UIItem); } protected override void OnExecute(IDragable subject, IFocusable target) { if (EndDrag) { Debug.Log("Execute"); - (target as UIItem).icon.gameObject.SetActive(true); - (target as UIItem).icon.sprite = sceneItem.iconSprite; + uiItem.icon.gameObject.SetActive(true); + uiItem.icon.sprite = sceneItem.iconSprite; } } protected override void OnExit() diff --git a/EasyInteractive/Example/Scripts/SceneItem.cs b/EasyInteractive/Example/Scripts/SceneItem.cs index db0e767..af58a16 100644 --- a/EasyInteractive/Example/Scripts/SceneItem.cs +++ b/EasyInteractive/Example/Scripts/SceneItem.cs @@ -1,7 +1,5 @@ using HalfDog.EasyInteractive; using System; -using System.Collections; -using System.Collections.Generic; using UnityEngine; public class SceneItem : MonoBehaviour, IDragable diff --git a/EasyInteractive/Example/Scripts/Table.cs b/EasyInteractive/Example/Scripts/Table.cs index 2ba19fa..fadb8db 100644 --- a/EasyInteractive/Example/Scripts/Table.cs +++ b/EasyInteractive/Example/Scripts/Table.cs @@ -20,4 +20,5 @@ public class Table : MonoBehaviour, IFocusable { _outline.enabled = false; } + } diff --git a/EasyInteractive/Example/Scripts/UIItem.cs b/EasyInteractive/Example/Scripts/UIItem.cs index 2698572..fc31973 100644 --- a/EasyInteractive/Example/Scripts/UIItem.cs +++ b/EasyInteractive/Example/Scripts/UIItem.cs @@ -6,15 +6,19 @@ using UnityEngine.UI; public class UIItem : InteractableUIElement,IDragable { public Image icon; + private bool _enableDrag = true; + public Type interactTag => typeof(UIItem); public bool enableFocus => true; - public bool enableDrag => true; + public bool enableDrag => _enableDrag; public void OnFocus() { + _enableDrag = icon.gameObject.activeSelf; } public void EndFocus() { + _enableDrag = true; } public void OnDrag() { diff --git a/InteractiveSystem.png b/InteractiveSystem.png new file mode 100644 index 0000000000000000000000000000000000000000..9e690cf6eee6557b60cb9f592d06a4bde4329cdd GIT binary patch literal 47967 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«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 literal 0 HcmV?d00001 diff --git a/InteractiveSystem.png.meta b/InteractiveSystem.png.meta new file mode 100644 index 0000000..9cd13cc --- /dev/null +++ b/InteractiveSystem.png.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: dd83e1b0f467d96479c77dfef29e917f +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/README.md b/README.md index 8b13789..3dd00a1 100644 --- a/README.md +++ b/README.md @@ -1 +1,105 @@ +# EasyInteractive +*** +## 概述 +交互系统是我针对统一场景和UI交互而所研究的一套系统,主要是为了解决当有大量的场景物体和UI物体需要交互时代码凌乱耦合度过高的问题,这一套系统能够很好的将不同的交互逻辑分离开,并且能够随时更改相同物体间不同的交互逻辑,不过目前此系统还仅支持Focus、Select、Drag这几种交互动作。 +*** +## 总览 +处理UI与UI间,UI和场景间的各种交互是很麻烦的,最终实现的代码冗长且各个交互间高度耦合,并且为了避免交互间的冲突,会有很多的判断条件,进一步降低了代码的可读性、可拓展性与可维护性。出现这种情况的原因是游戏中需要交互的对象多且杂,交互对象间的关系往往呈网状,直接写代码处理代价太大。
+为了避免这种问题,我们需要一种能够解耦不同交互操作,高可扩展,高可维护的交互框架。需要说明的是,这里的交互指代的是UI对象与UI对象间、UI对象与场景对象间、场景对象与场景对象间这样一个狭义的交互范围,且所有的交互都是需要玩家主动操作的,即使用键盘鼠标等输入设备进行交互操作。例如交换两个UI槽位的内容;将UI槽位中的内容放置到场景中;将场景中某个对象拖拽到另一个地方等等。
+本项目中实现了交互系统来解决这个问题,系统框架如图所示: +![alt text](InteractiveSystem.png) +在交互系统下,游戏中的交互被分为了两个部分,交互动作与交互情景。交互动作将不同的交互对象的操作抽象为了统一的接口,也就是说UI与场景对象的交互操作是统一的,使用相同的接口。交互情景(InteractCase)则是将多个交互对象间的交互抽象,在一个交互情景下,不需要关心交互对象具体细节,也不需要关心当前交互动作的上下文关系,将每种特定的交互关系模块化,做到了解耦不同交互间的耦合。 +*** +## 交互动作 +接下来说明交互动作是如何将不同交互操作抽象统一的。首先在本项目中我们可以确定的是,需要交互的对象有且只有特定的UI与场景对象,所以将交互操作分为两大类一类是UI交互,一类是场景交互,两类交互对象拥有的交互操作类型是相同的,都有Focus(指针聚焦)、Select(选中)、Drag(拖拽)三种操作,并且这三种操作可以囊括游戏中所有的交互操作。 +``` csharp +public interface IInteractable +{ + ... +} +//可聚焦接口 +public interface IFocusable : IInteractable +{ + ... +} +//可选中接口 +public interface ISelectable : IFocusable, IInteractable +{ + ... +} +//可拖拽接口 +public interface IDragable :IFocusable, IInteractable +{ + ... +} +``` +游戏UI因为有EventSystem的存在,其本身就拥有处理这些操作的能力,比如使用EventSystem.IPointerEnterHandler / EventSystem.IPointerExitHandler两个接口来实现Focus操作。而场景对象自身没有类似的处理指针交互的接口,所以项目中实现一套基于RayCast的射线检测交互系统。目前为止UI与场景都具有了进行交互的基础条件,在此基础上就可以通过接口抽象统一二者的操作。
+详细来说,交互系统针对每一种交互操作都提供了一个接口,实现任意一种交互操作接口的对象可以被称为一个交互对象,换句话说,就算是一个UI如果不实现任意一种交互操作接口,那么它就不能被称之为一个交互对象,自然也就不会作为交互系统的处理对象。这样的一种操作一个接口的好处就是,功能跟着接口走,按需实现,让不同交互对象的职责更清晰。 +``` csharp +//一个能被聚焦和拖拽的UIItem +public class TestUIItem : UIItemController,IFocusable,IDragable +{ + ... + public Type interactType => this.GetType(); + public void OnFocus(){} + public void EndFocus(){} + public void OnDrag(){} + public void ProcessDrag(){} + public void EndDrag(){} + ... +} +``` +如此一来,当某个对象需要Focus交互操作时,只需要实现对应的IFocusable接口,就可以在各自交互功能的支持下实现交互操作(UI下使用的是EventSystem相关接口,场景对象使用基于RayCast的射线检测交互),至此,UI与场景的交互操作通过接口统一了。
+> 在UI模块一文中提到了UIItemController可以使用交互系统提供的接口来简化交互操作,这是因为UIItemController实现了EventSystem.IPointerEnterHandler / EventSystem.IPointerExitHandler两个接口,并且在各自实现的代码中都对接了交互系统,所以我们才可以在UIItem上直接实现IFocusable等IInteractable接口就可以和交互系统对接。 +*** +## 交互情景 +接下来说明交互情景(InteractCase)是如何将多个交互对象间的交互抽象并模块化的。交互动作仅仅只是解决了不同类型的交互对象统一交互接口的问题,实际在处理多个交互对象间的交互时还是避免不了出现过多的耦合与判断,导致这个结果的关键点在于,交互代码要么分散在各个交互对象内,不易于维护与拓展;要么就把所有的交互代码写到一个脚本中,这更是导致了问题的加重。
+而交互情景很好的解决了上述问题,交互情景将多个交互对象间的交互抽象为:在特定的交互动作下交互主体(InteractSubject)与交互目标(InteractTarget)的一次交互。举个例子,将UI栏的塔拖拽到某个场景中的地块上放置这样一次交互,可以抽象为:拖拽UI(交互主体),聚集地块(交互目标),当结束拖拽时放置塔。其中结束拖拽后要做的事情交互情景并不关心,交互情景关心的是当前交互主体与其交互动作,以及当前交互目标与其交互动作,这样一来几乎所有的多个交互对象间的交互都能用交互主体、交互目标、以及各自的交互动作来描述,两个交互情景有相同的交互主体与目标,但交互动作不同,那么这两个交互情景就是不同的两种交互。 +``` csharp +/// 拖拽主体并聚焦目标的交互情景 +public abstract class DragSubjectFocusTargetInteractCase : AbstractInteractCase +{ + private bool _isEnter = false; + private bool _isExit = true; + protected bool endDrag => Input.GetMouseButtonUp(0); + public DragSubjectFocusTargetInteractCase(Type subject,Type target) : base(subject,target){} + protected abstract void OnExecute(IDragable subject,IFocusable target); + public override bool Execute(IFocusable focusable, ISelectable selectable, IDragable dragable) + { + ... + } + /// 进入交互情景 + protected virtual void OnEnter(IDragable subject, IFocusable target) { } + /// 退出交互情景 + protected virtual void OnExit(IDragable subject, IFocusable target) { } +} +``` +这样一来,针对某一类的交互,我们可以抽象出一个交互情景来描述,列如“拖拽主体,聚集目标”这样一种交互情景(DragSubjectFocusTargetInteractCase),然后针对具体的某一个交互,我们可以在此交互情景的基础上填入不同类型的交互主体与交互目标,列如“放置塔”(PlacedTower : DragSubjectFocusTargetInteractCase),UI是交互主体,地块是交互目标,交互对象类型明确,交互动作明确,那么这就是一次明确的交互。之后针对这一个交互情景再写具体的交互相关的效果代码,就能够做到高度模块化,高可拓展与高可维护了。 +``` csharp +///当拖拽BackpackBeUsingRelicItem并聚焦到BackpackRelicSlotItem上时会触发此交互情景 +[InteractCase(typeof(BackpackBeUsingRelicItem), typeof(BackpackRelicSlotItem))] +public class ChangeUsingRelisOrder : DragSubjectFocusTargetInteractCase +{ + ... + public ChangeUsingRelisOrder(Type subject, Type target) : base(subject, target){} + protected override void OnEnter(IDragable subject, IFocusable target) + { + ... + } + protected override void OnExecute(IDragable subject, IFocusable target) + { + ... + } + protected override void OnExit(IDragable subject, IFocusable target) + { + ... + } +} +``` +*** +## 总结 +最后用一段话来形容一下整个交互系统是如何运作的:在游戏开始时,InteractiveSystem初始化,会将所有的继承自AbstractInteractCase以及由InteractCaseAttribute修饰的InteracCase实例化并保存,作为后续处理各种交互的基础。
+游戏开始后,所有实现了任意IInteractable接口(IFocusable\ISelectable\IDragable)的对象会作为交互对象开始检测是否与玩家输入发生互动,UI交互对象由EventSystem的IPointerHandler相关接口提供支持,场景交互对象由InteractiveSystem内的RayCast射线交互检测提供支持。
+同时在InteractiveSystem内,每一帧会调用所有的初始化时保存的InteractCase,并将当前的交互对象与其相对应的交互动作状态传入其中作为过滤识别特定InteractCase的依据,包括当前聚焦的对象(currentFocused)、当前选择的对象(currentSelected)与当前拖拽的对象(currentDraged)。如果当前帧的交互动作状态与交互对象双方的类型符合某个InteractCase的要求,那么这个InteractCase就会被执行,从而完成一次当前交互双方所期望的一次操作,如此重复,整个InteractiveSystem便很好的运行了起来。
+最后在扩展时,有新的交互对象就实现IInteractable接口,有新的交互操作类型就实现新的InteractCase,至此,交互系统便能够支撑复杂且多变的交互逻辑了。