Unity c#发射另一个游戏对象#x27;s方法。更好的方法?
我有TCP客户端(Unity c#)和服务器(WinForms app c#)。我需要我的服务器发送一些JSON命令,如下所示: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
{ ""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(){}
}