Unity 中的多人游戏

Posted

技术标签:

【中文标题】Unity 中的多人游戏【英文标题】:Multiplayer in Unity 【发布时间】:2022-01-15 10:27:35 【问题描述】:

下面是播放器对象移动的代码,它工作得很好。但是在TellClientsToMoveClientRpc 为什么我们要这样做transform.position 因为它指的是当前的游戏对象 但并不是每个对象都在移动,只有调用上述Rpc 的那个才是可取的。但是为什么所有其他游戏对象都不动呢?

using UnityEngine;

namespace HelloWorld

    public class HelloWorldPlayer : NetworkBehaviour
    
        private const float speed = 20f;

        private void Update()
        
            if (!IsOwner)
                return;

            PlayerMove();
           
        

        void PlayerMove()
        
            Vector3 velocity = new(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical"));
            if(velocity.sqrMagnitude >= 1)
            
                TellServerToMoveClientServerRpc(velocity, NetworkManager.Singleton.LocalClientId);
            
        

        [ServerRpc]
        void TellServerToMoveClientServerRpc(Vector3 velocity, ulong clientId)
        
            TellClientsToMoveClientRpc(velocity, clientId);
        

        [ClientRpc]
        void TellClientsToMoveClientRpc(Vector3 velocity, ulong clientId)
        
            transform.position += speed * Time.deltaTime * velocity;
        
    
```

【问题讨论】:

【参考方案1】:

这样的多人游戏意味着有多个客户端运行相同的程序(游戏),这意味着每个客户端的游戏实例上都有一个所有相同游戏对象的副本 .

这意味着您附加HelloWorldPlayer 脚本的游戏对象存在于每个客户端上。

当您从客户端调用TellServerToMoveClientServerRpc 时,它将在客户端调用该函数的同一游戏对象上执行该函数,但在服务器上。这是因为您添加了[ServerRPC]

现在服务器可以控制接下来发生的事情,它调用TellClientsToMoveClientRpc。现在这一次,由于您添加了[ClientRpc],该函数将在原始客户端调用该函数的同一游戏对象上调用,但现在在连接到您服务器的每个客户端上。

由于调用函数的总是同一个游戏对象(只是在不同的游戏实例上,在不同的计算机上运行),并非所有游戏对象都会移动:只有最初调用 TellServerToMoveClientServerRpc 函数的游戏对象。

【讨论】:

以上是关于Unity 中的多人游戏的主要内容,如果未能解决你的问题,请参考以下文章

使用 Photon Unity Network(多人游戏)在 Unity 中实时同步

Steamworks and Unity – P2P多人游戏

Unity 中的 AI 角色与 Photon View

多人 Unity 游戏单独运行

如何在脚本中仅使用游戏对象启用 Unity C# 中的部件/组件

在 Unity Billiard 游戏上实现多人游戏的最佳方法是啥?