在新的Unity网络中进行"直接"RPC样式调用?

Fat*_*tie 4 networking unity-game-engine

说你有

在此输入图像描述

使用"新的"统一网络,你必须有(据我所知)一个NetworkManager地方.它会产生荒谬的"玩家"对象.

荒谬的"玩家"对象必须有一个继承自的类NetworkBehaviour.

大多数团队称该类为"Comms"或"AbstractPlayer"或"Junction".

public class Comms : NetworkBehaviour { }
Run Code Online (Sandbox Code Playgroud)

因此,每个命令(如"跳转")都必须由"Comms"类调解.

对于每个命令(如"Jump"),您需要 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

所以!

随着新的Unity网络,在客户端,每次你想要

send to server Jump()
Run Code Online (Sandbox Code Playgroud)

你实际上必须通过抽象播放器上的"通信"类发送它.

public class Jumping: MonoBehavior...

    // here in the client side ... we want to send "Jump"
    Comms comms = Object.FindObjectOfType<Comms>();
    comms.CommandClick1();
Run Code Online (Sandbox Code Playgroud)

(注意 - 显然,你会在那里缓存"通信".这只是一个例子.)

旁白:非常重要:这只是一个大纲示例.

在实践中你必须这样做:

/sf/answers/3623150961/

所以!

事情是这样的:

在"旧"Unity网络中,任何旧的客户端脚本都可以直接进行网络调用(示例中为"CmdJump").您只需要一个指向NetworkView的链接.

现在你必须在这个例子中有这个新的"中间"类,"Comms".

我想了解,

有没有办法让客户端的正常脚本(如Jumping - MonoBehavior)直接调用Command

据我所知,只有NetworkBehaviour派生类才能做到这一点.在旧的网络中,任何一个班级都可以打电话.

在"新的"Unity网络中,据我所知,您必须通过NetworkBehaviour派生类传递每个调用,如我的示例所示.

正如你所看到的,如果我"缺少某些东西",而像Jumping这样的类可以直接进行,那么我的代码就是令人发指的:)

你能Command直接从MonoBehavior中调用s吗?

我实际上完全错了你必须拥有荒谬的自动生成的"玩家"对象,等等?也许还有另外一种方式来调用Commands.

Hri*_*sto 6

对你的问题的简短回答是否定的.因为在编辑中使用[Command]关键字MonoBehavior会立即导致编辑错误,因为代码无法编译.

UNetWeaver错误:脚本XXXXXX使用[Command] YYYYY但不是NetworkBehaviour.

然而,还有其他可能性非常接近您想要实现的目标.

  • 正如评论中所讨论的,您可以使用Events和Delegates将您的[Command]函数订阅到继承自的类中的另一个函数MonoBehavior.
  • 我刚刚尝试并取得成功的另一个非常聪明的可能性是使用Interfaces.

我刚刚创建了一个不实现任何其他接口的简单接口,它只是声明了一个命令.它看起来像这样:

public interface ICustomCommands
{
    [Command]
    void CmdCustomSpawn(GameObject toSpawn);
}
Run Code Online (Sandbox Code Playgroud)

然后我创建了一个简单的类,它将实现此接口(一个方法)而不使用[Command]关键字.我的自定义类继承自MonoBehavior,看起来像这样:

public class CustomCommands : MonoBehaviour, ICustomCommands
{
    public void CmdCustomSpawn(GameObject toSpawn)
    {
        NetworkServer.Spawn(toSpawn);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我成功地调用了我的CmdCustomSpawn函数并在服务器上生成了一个播放器.