Unity c#发射另一个游戏对象#x27;s方法。更好的方法?

Unity c#发射另一个游戏对象#x27;s方法。更好的方法?,c#,unity3d,invoke,C#,Unity3d,Invoke,我有TCP客户端(Unity c#)和服务器(WinForms app c#)。我需要我的服务器发送一些JSON命令,如下所示: { ""ObjName"": ""Cube_2"", ""Method"":""MoveLeft"", ""Delay"":0} 这个特定的命令说找到游戏对象“Cube_2”并发射方法“MoveLeft” 当我从服务器收到此命令时,我将其转换为我的AOSCommand类: public class AOSCommand { public string Obj

我有TCP客户端(Unity c#)和服务器(WinForms app c#)。我需要我的服务器发送一些JSON命令,如下所示:

{ ""ObjName"": ""Cube_2"", ""Method"":""MoveLeft"", ""Delay"":0}
这个特定的命令说找到游戏对象“Cube_2”并发射方法“MoveLeft”

当我从服务器收到此命令时,我将其转换为我的AOSCommand类:

public class AOSCommand
{
    public string ObjName;
    public string Method;
    public int delay;
}
然后我做了以下工作(我认为这不是最好的解决方案,所以这里有一个问题):

如何更好地从AOSCommand.method字符串中激发某些方法?

附加到多维数据集2(和多维数据集1)的脚本,可能附加到其他对象的未知计数:


这取决于你认为什么错误。

您应该有一个脚本来处理传入数据的解析,这将消除搜索组件的需要,它将始终保持不变

然后,您可以使用的字典来替换调用

因此,您的代码片段变成:

private void ProcessCommand(AOSCommand command)
{
    GameObject cube = GameObject.Find(command.ObjName);
    AOSDispatch dispatch = cube.GetComponent<AOSDispatch>()
    if(dispatch == null){ return; } // or debug or exception
    dispatch.Call(command);
}
private void ProcessCommand(AOSCommand命令)
{
GameObject cube=GameObject.Find(command.ObjName);
AOSDispatch dispatch=cube.GetComponent()
如果(dispatch==null){return;}//或调试或异常
调度、呼叫(命令);
}
这是在主接收器上。然后是多维数据集上的脚本:

public class AOSDispatch : MonoBehaviour
{
    Dictionary<string, Action> dict;
    void Start()
    {
        dict.Add("MoveLeft", MoveLeft);
        dict.Add("MoveRight", MoveRight);
    }
    public void Call(AOSCommand command)
    {
        if(dict.Contains(command.Method) == false){  return; } //Or debug
        // use the delay as well as you wish
        dict[command.Method]();
    }
    private void MoveLeft(){}  
    private void MoveRight(){}
}
公共类AOSDispatch:MonoBehavior
{
词典词典;
void Start()
{
dict.Add(“MoveLeft”,MoveLeft);
dict.Add(“MoveRight”,MoveRight);
}
公共无效调用(AOSCommand命令)
{
if(dict.Contains(command.Method)==false){return;}//或debug
//按照你的意愿使用延迟
dict[command.Method]();
}
私有void MoveLeft(){}
私有void MoveRight(){}
}
这不一定更好,只是我的两分钱而已

编辑:有评论提到json可能包含脚本类型,以了解要使用的脚本。我不会走这条路。AOSDispatch将负责消息的发送

消息显示MoveLeft,AOSDispatch可以处理信息或转发给移动控制器:

public class AOSDispatch : MonoBehaviour
{
    [SerializeField] private MoveController moveCtrl = null;
    Dictionary<string, Action> dict;
    void Start()
    {
        dict.Add("MoveLeft", this.moveCtrl.MoveLeft);
        dict.Add("MoveRight", this.moveCtrl.MoveRight);
    }
    public void Call(AOSCommand command)
    {
        if(dict.Contains(command.Method) == false){  return; } //Or debug
        // use the delay as well as you wish
        dict[command.Method]();
    }
}
public class MoveController: MonoBehaviour
{
    private void MoveLeft(){}  
    private void MoveRight(){}
}
公共类AOSDispatch:MonoBehavior
{
[SerializeField]专用MoveController moveCtrl=null;
词典词典;
void Start()
{
dict.Add(“MoveLeft”,this.moveCtrl.MoveLeft);
dict.Add(“MoveRight”,this.moveCtrl.MoveRight);
}
公共无效调用(AOSCommand命令)
{
if(dict.Contains(command.Method)==false){return;}//或debug
//按照你的意愿使用延迟
dict[command.Method]();
}
}
公共类控制器:单行为
{
私有void MoveLeft(){}
私有void MoveRight(){}
}
好了,消息是向前的,干净的,AOSDispatch只做它想做的工作,分派AOS

二次编辑:

仔细想想,这里有一个改进的版本。 创建DispatchManager游戏对象并添加以下脚本:

public class AOSDispatch:MonoBehaviour
{
     private IDictionary<string, AOSController> dict;
     void Awake(){
           this.dict = new Dictionary<string, AOSController>(); 
           AOSController.RaiseCreation += ProcessCreation;
           AOSController.RaiseDestruction += ProcessDestruction;
     }
    void OnDestroy()
    {
           AOSController.RaiseCreation -= ProcessCreation;
           AOSController.RaiseDestruction -= ProcessDestruction;
    }
    private void ProcessCreation(AOSController controller){
         this.dict.Add(controller.name, controller);
    }
    private void ProcessDestruction(AOSController controller){
         AOSController temp= null;
         if(this.dict.TryGetValue(controller.name, out temp) == true){
             this.dict.Remove(name);
        }
    }
    private void ProcessCommand(AOSCommand command)
    {
        AOSController controller = null;
        if(this.dict.TryGetValue(command.ObjName, out controller) == true){
             controller.Call(command);
             return;
        }
    }
}
公共类AOSDispatch:MonoBehavior
{
私人词典;
无效唤醒(){
this.dict=新字典();
AOSController.RaiseCreation+=进程创建;
AOSController.RaiseDestruction+=ProcessDestruction;
}
void OnDestroy()
{
AOSController.RaiseCreation-=进程创建;
AOSController.RaiseDestruction-=进程销毁;
}
私有void进程创建(AOSCOontroller控制器){
this.dict.Add(controller.name,controller);
}
私有void ProcessDestruction(AOSController控制器){
AOS控制器温度=空;
if(this.dict.TryGetValue(controller.name,out temp)==true){
此。dict.Remove(名称);
}
}
私有void进程命令(AOSCommand命令)
{
AOSController控制器=空;
if(this.dict.TryGetValue(command.ObjName,out controller)==true){
控制器。呼叫(命令);
返回;
}
}
}
然后在对象上有AOSCOcontroller,它像以前一样转发信息(只是重命名):

公共类AOS控制器:单行为
{
公共静态事件行动的提高;
公共静态事件行动引发指令;
[SerializeField]专用MoveController moveCtrl=null;
词典词典;
void Start()
{
如果(RaiseCreation!=null){RaiseCreation(this);}
dict.Add(“MoveLeft”,this.moveCtrl.MoveLeft);
dict.Add(“MoveRight”,this.moveCtrl.MoveRight);
}
void OnDestroy()
{
如果(RaiseDestruction!=null){RaiseDestruction(this);}
}
公共无效调用(AOSCommand命令)
{
if(dict.Contains(command.Method)==false){return;}//或debug
//按照你的意愿使用延迟
dict[command.Method]();
}
}
公共类控制器:单行为
{
私有void MoveLeft(){}
私有void MoveRight(){}
}
唤醒时,调度从AOSCOontroller注册到静态事件。在AOSController.Start中,对象触发事件并将自身传递给AOSDispatch。那个人把它加到字典里。销毁时,AOSDispatch获取事件并删除AOSController

现在,您有了一个集合,该集合在任何给定时间都包含场景中的所有AOS控制器


因此,您不需要执行GameObject.Find,因为您可以从字典中获取对象(真正快速的过程)

非常感谢!我确实认为你的方式应该快一点。我还应该在Json命令中添加一个类型,以便使用更安全的
FindObjectOfType
。如果你依赖AOSDispatch来知道该做什么,你就不需要该类型了。。@我添加了一个使用事件的辅助编辑。如果有什么你不明白的,请问。
public class AOSDispatch : MonoBehaviour
{
    [SerializeField] private MoveController moveCtrl = null;
    Dictionary<string, Action> dict;
    void Start()
    {
        dict.Add("MoveLeft", this.moveCtrl.MoveLeft);
        dict.Add("MoveRight", this.moveCtrl.MoveRight);
    }
    public void Call(AOSCommand command)
    {
        if(dict.Contains(command.Method) == false){  return; } //Or debug
        // use the delay as well as you wish
        dict[command.Method]();
    }
}
public class MoveController: MonoBehaviour
{
    private void MoveLeft(){}  
    private void MoveRight(){}
}
public class AOSDispatch:MonoBehaviour
{
     private IDictionary<string, AOSController> dict;
     void Awake(){
           this.dict = new Dictionary<string, AOSController>(); 
           AOSController.RaiseCreation += ProcessCreation;
           AOSController.RaiseDestruction += ProcessDestruction;
     }
    void OnDestroy()
    {
           AOSController.RaiseCreation -= ProcessCreation;
           AOSController.RaiseDestruction -= ProcessDestruction;
    }
    private void ProcessCreation(AOSController controller){
         this.dict.Add(controller.name, controller);
    }
    private void ProcessDestruction(AOSController controller){
         AOSController temp= null;
         if(this.dict.TryGetValue(controller.name, out temp) == true){
             this.dict.Remove(name);
        }
    }
    private void ProcessCommand(AOSCommand command)
    {
        AOSController controller = null;
        if(this.dict.TryGetValue(command.ObjName, out controller) == true){
             controller.Call(command);
             return;
        }
    }
}
public class AOSController: MonoBehaviour
{
    public static event Action<AOSController> RaiseCreation;
    public static event Action<AOSController> RaiseDestruction;
    [SerializeField] private MoveController moveCtrl = null;
    Dictionary<string, Action> dict;
    void Start()
    {
        if(RaiseCreation != null) { RaiseCreation(this); }
        dict.Add("MoveLeft", this.moveCtrl.MoveLeft);
        dict.Add("MoveRight", this.moveCtrl.MoveRight);
    }
    void OnDestroy()
    {
        if(RaiseDestruction != null) { RaiseDestruction(this); }
    }
    public void Call(AOSCommand command)
    {
        if(dict.Contains(command.Method) == false){  return; } //Or debug
        // use the delay as well as you wish
        dict[command.Method]();
    }
}
public class MoveController: MonoBehaviour
{
    private void MoveLeft(){}  
    private void MoveRight(){}
}