本示例工程中包含操作项、物品项和组件间通信的示例。

下载地址:DM示例工程


组件通信示例

选择Assets/DMBundle/AssetSettings/TagSetting.asset文件,在Inspector面板中添加一个标签,修改名称并指定ID为17。

添加标签是为了更明确的分类和便于在物体列表中进行查找

AddTagSetting.png

在Unity中构建两个资源:通信示例控制器和通信示例控制物体。打包通信示例控制物体时,在打包插件中勾选通信示例的Tag。

标签名称只用于打包组件时进行区分,主要为ID且不能重复

通信示例控制器:

APIExampleControl.png

控制器中添加两个操作项:左转和右转,ID分别为405和406。

通信示例控制物体:

APIExampleControlItem1.PNG

APIExampleControlItem2.PNG

创建VS工程,选择.net framework类库工程,添加引用并创建Main类作为组件入口。

APIExampleCreateVSProject.png

点击操作项时,控制器组件会接收到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完成。

APIExampleFinish.gif