在新的 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 中调用 Commands 吗?

你必须拥有可笑的自动生成的“玩家”对象等等,我真的完全错了吗?也许还有另一种方式可以打电话给Commands。

【问题讨论】:

我对“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 样式调用?的主要内容,如果未能解决你的问题,请参考以下文章

在新的社交网络中开放社交[关闭]

unity 怎么让一个prefab一直在新实例化的prefab下面

WPF 实现换肤功能

RPC 崩溃 Unity

在新的网络名字空间与主机通信

使用Photon引擎进行unity网络游戏开发