在新的 Unity 网络中进行“直接”RPC 样式调用?
Posted
技术标签:
【中文标题】在新的 Unity 网络中进行“直接”RPC 样式调用?【英文标题】:Making "direct" RPC style calls in new Unity networking? 【发布时间】:2018-07-17 12:56:18 【问题描述】:说你有
使用“新”Unity 网络,您必须在某处(据我所知)NetworkManager
。它会产生可笑的“玩家”对象。
荒谬的“玩家”对象必须有一个继承自NetworkBehaviour
的类。
大多数团队将该类称为“Comms”或“AbstractPlayer”或“Junction”。
public class Comms : NetworkBehaviour
因此,每个命令(例如“Jump”)都必须由该“Comms”类进行调解。
对于每个命令(如“跳转”)您需要在 Comms 类中使用一对函数:
public class Comms : NetworkBehaviour
// for every command (say, "Jump") you need THIS PAIR of functions:
public void CommandJump()
Debug.Log("this is comms - client, do a Jump");
CmdJump();
[Command]
void CmdJump()
Debug.Log("this is comms - server. a Jump arrived");
// simply pass on that command to the correct script on a server...
s = Object.FindObjectOfType<Some Class On The Server>();
s.ClientJumped();
所以!
使用新的 Unity 网络,在客户端,每次您想要
send to server Jump()
实际上,您必须通过抽象播放器上的“comms”类发送它。
public class Jumping: MonoBehavior...
// here in the client side ... we want to send "Jump"
Comms comms = Object.FindObjectOfType<Comms>();
comms.CommandClick1();
(注意 - 显然,您会在此处缓存“通讯”。这只是一个示例。)
旁白:非常重要:这只是一个大纲示例。
在 练习你必须这样做:
https://***.com/a/51759299/294884
所以!
事情是这样的:
在“旧”Unity 网络中,任何旧客户端脚本可以直接进行网络调用(示例中为“CmdJump”)。您只需要一个指向 NetworkView 的链接。
现在您必须拥有这个新的“中间”类,在示例中为“Comms”。
我正在努力理解,
有没有办法让客户端的普通脚本(例如 Jumping - a MonoBehavior)直接调用 Command
?
据我所知,只有NetworkBehaviour
派生类可以做到这一点。在旧的网络中,任何班级都可以进行这样的调用。
在“新”Unity 网络中,据我所知,您必须通过NetworkBehaviour
派生类传递每个调用,就像我在此处的示例一样。
如你所见,如果我“遗漏了什么”,而像 Jumping 这样的类可以直接完成,那么我的代码是令人发指的 :)
您可以直接从 MonoBehavior 中调用 Command
s 吗?
你必须拥有可笑的自动生成的“玩家”对象等等,我真的完全错了吗?也许还有另一种方式可以打电话给Command
s。
【问题讨论】:
我对“a MonoBehavior 直接调用命令?”的看法是否定的,但这并不意味着NetworkingBehavior
不能订阅 Mono事件,这将触发[Command]
函数。
这里有大量的赏金!
@Hristo,当然你可以使用统一事件作为一种方便(我个人只是使用一个微不足道的单例或全局来达到“逗号”类)。确实,正如您所知,关键是您能否“实际上”从非 NetworkBehaviour 调用 Command
...(就像您“过去能够做到”..)!
【参考方案1】:
您的问题的简短回答是否定的。仅仅因为在MonoBehavior
中使用[Command]
关键字将立即导致您的编辑器出错,因为无法编译代码。
UNetWeaver 错误:脚本 XXXXXX 使用 [命令] YYYYY 但不是 NetworkBehaviour。
但是,还有其他可能非常接近您想要实现的目标。
如 cmets 中所述,您可以使用事件和委托将您的[Command]
函数订阅到继承自 MonoBehavior
的类中的另一个函数。
我刚刚尝试并取得成功的另一个非常聪明的可能性是使用接口。
我刚刚做了一个简单的接口,它没有实现任何其他接口,它只是声明了一个命令。它看起来像这样:
public interface ICustomCommands
[Command]
void CmdCustomSpawn(GameObject toSpawn);
然后我创建了一个简单的类来实现这个接口(一个方法)而不使用[Command]
关键字。 我的自定义类继承自 MonoBehavior
,如下所示:
public class CustomCommands : MonoBehaviour, ICustomCommands
public void CmdCustomSpawn(GameObject toSpawn)
NetworkServer.Spawn(toSpawn);
然后我成功地调用了我的CmdCustomSpawn
函数并在服务器上生成了一个播放器。
【讨论】:
接口和类不派生自NetworkBehaviour
.. ??怎么能行?!太棒了..
@Fattie 我自己都惊呆了,你试过了吗?
还没有,我一直很困惑......也许你不能在 MonoBehavior 中使用它的事实是那些“假”的 Unity 东西之一?所以,他们(不知何故)“阻止”了它,不需要NetworkBehaviour
。 (也许它只适用于原始基类?我必须检查一下!)
仅供参考,我为此发送了赏金! :)
仍在调查中!有时我需要 4 个人:/ 会回来..以上是关于在新的 Unity 网络中进行“直接”RPC 样式调用?的主要内容,如果未能解决你的问题,请参考以下文章