本示例工程中包含操作项、物品项和组件间通信的示例。
下载地址:DM示例工程
组件通信示例
选择Assets/DMBundle/AssetSettings/TagSetting.asset
文件,在Inspector面板中添加一个标签,修改名称并指定ID为17。
添加标签是为了更明确的分类和便于在物体列表中进行查找
在Unity中构建两个资源:通信示例控制器和通信示例控制物体。打包通信示例控制物体时,在打包插件中勾选通信示例
的Tag。
标签名称只用于打包组件时进行区分,主要为ID且不能重复
通信示例控制器:
控制器中添加两个操作项:左转和右转,ID分别为405和406。
通信示例控制物体:
创建VS工程,选择.net framework类库工程,添加引用并创建Main类作为组件入口。
点击操作项时,控制器组件会接收到MainToMain
类型的消息,所以在Main中实现IMesRec
接口处理这个事件。
每次旋转角度可以自由配置,使用Properties
动态属性,指定输入浮点数作为旋转角度。
当收到了操作项点击的消息时,发送消息到控制物体中。消息类型选择为SendType.MainToAll
,即为主、从机全部收到消息并执行相应操作。
通信示例控制器 -> Main
using APIExample; using DM.Core.Map; using DM.Entity; using DM.IFS; using UnityEngine; public class Main : ScriptManager, IMesRec { private BObjectModel controlItemBObject = null; private float rotateAngle = 0; private float rotateTime = 1; private void Awake() { //添加浮点输入框,可以设置旋转角度 Properties = new DynamicProperty[] { new InputFloatProperty("旋转角度", 90f), new InputFloatProperty("旋转时间", 1f) }; } public override void RunModeInitialized(bool isMain, SceneInfo info) { base.RunModeInitialized(isMain, info); rotateAngle = (Properties[0] as InputFloatProperty).Value; rotateTime = (Properties[1] as InputFloatProperty).Value; //查找标记了“示例物体”标签的游戏对象 for (int i = 0; i < allBObjects.Length; i++) { BObjectModel obj = allBObjects[i]; //if (obj.BObject.Info.Tags.Con<TagItem>("3")?.SubTags.Con<SubTagItem>("4") != null)//查找'标签'为3且'子标签'为4的物体 if (obj.BObject.Info.Tags.Con<TagItem>("17") != null) { controlItemBObject = obj; break; } } } public void RecMessage(SendType type, GameObject senderObj, int eventType, string param) { switch (type) { case SendType.MainToMain: //根据点击了左转或右转操作项,决定旋转方向 int dir = 1; if (eventType == (int)EventID.TurnLeft) dir = -1; else if(eventType ==(int)EventID.TurnRight) dir = 1; //发送消息到“通信示例控制物体”组件中。类型选择SendType.MainToAll,即主从机全部会收到消息 if (controlItemBObject != null) sender.RunSend(SendType.MainToAll, controlItemBObject.BObject.Id, (int)EventID.Rotate, string.Format("{0}|{1}", dir * rotateAngle, rotateTime)); else sender.LogWarning("场景中没有标记为\"示例物体\"的对象,请放置一个标记为示例物体的组件到场景中"); break; } } }
通信示例控制器 -> Const
namespace APIExample { public enum EventID { /// <summary> /// 对应左转操作项的ID /// </summary> TurnLeft = 405, /// <summary> /// 对应右转操作项的ID /// </summary> TurnRight = 406, /// <summary> /// 通知控制物体进行旋转 /// </summary> Rotate = 407 } }
此时点击“左转”或“右转”的操作项时,操作物体将会收到MainToAll
类型的一条消息,内容为“旋转角度|旋转时间”。所以在操作物体的RecMessage
消息接收接口方法内处理对应的逻辑。
通信示例控制物体 -> Main
using APIExample; using DM.IFS; using UnityEngine; using DG.Tweening; public class Main : ScriptManager, IMesRec { public void RecMessage(SendType type, GameObject senderObj, int eventType, string param) { switch (type) { case SendType.MainToAll: if(eventType == (int)EventID.Rotate) { //解析收到旋转的消息 string[] paramArray = param.Split('|'); float rotateAngle = float.Parse(paramArray[0]); float rotateTime = float.Parse(paramArray[1]); //使用DOTWeen插件进行旋转 Vector3 endValue = this.transform.localEulerAngles + new Vector3(0, rotateAngle, 0); this.transform.DORotate(endValue, rotateTime); } break; } } }
通信示例控制物体 -> Const
namespace APIExample { public enum EventID { /// <summary> /// 控制物体进行旋转 /// </summary> Rotate = 407 } }
至此,组件之间的通信Demo完成。