我是靠谱客的博主 体贴项链,这篇文章主要介绍MLAPI系列 - 02 - HelloWorld,现在分享给大家,希望可以做个参考。

MLAPI系列 - 02 - HelloWorld

    • 1 构建 “你好,世界”
    • 2 要求
    • 3 向Hello World添加脚本
    • 4 添加脚本 HellowWorldPlayer.cs
    • 5 添加 HelloWorldManager.cs
    • 6 增加编辑模式
    • 7 Player对象添加基本移动
    • 8 一些简单的RPC使用
    • 9 现在,您可以创建上述概念的demo。

1 构建 “你好,世界”

在本指南中,我们将在已经在Hello World中完成的工作的基础上增加一些功能,我们将涵盖以下内容:

  • 向对象添加脚本
  • 在游戏中添加编辑器模式(主机服务器和客户端)
  • 基本玩家移动
  • 许可
  • 基本RPC使用
  • Adding scripts to your objects
  • Adding editor modes inside your game (Host Server and Client)
  • Basic Player Movement
  • Permissions
  • Basic RPC use

2 要求

教程需要支持 Netcode 的Unity版本(2020.3+)

我们建议您在开始这一个之前完成你的第一个网络游戏“ MLAPI - 01 - 你好世界 ”指南。

3 向Hello World添加脚本

本部分将向Hello World添加一些脚本,这些脚本将包含我们将在教程中介绍的新功能。

1 单击“Assets”文件夹。
2 创建一个新文件夹,并命名为Scripts

4 添加脚本 HellowWorldPlayer.cs

1 创建一个新的脚本HelloWorldPlayer
2 打开HelloWorldPlayer.cs脚本。
3 编辑HelloWorldPlayer.cs脚本以匹配以下内容。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using Unity.Netcode; using UnityEngine; namespace HelloWorld { public class HelloWorldPlayer : NetworkBehaviour { public NetworkVariable<Vector3> Position = new NetworkVariable<Vector3>(); public override void OnNetworkSpawn() { if (IsOwner) { Move(); } } public void Move() { if (NetworkManager.Singleton.IsServer) { var randomPosition = GetRandomPositionOnPlane(); transform.position = randomPosition; Position.Value = randomPosition; } else { SubmitPositionRequestServerRpc(); } } [ServerRpc] void SubmitPositionRequestServerRpc(ServerRpcParams rpcParams = default) { Position.Value = GetRandomPositionOnPlane(); } static Vector3 GetRandomPositionOnPlane() { return new Vector3(Random.Range(-3f, 3f), 1f, Random.Range(-3f, 3f)); } void Update() { transform.position = Position.Value; } } }

5 添加 HelloWorldManager.cs

1 创建一个空的GameObject并将其重命名为HelloWorldManager
2 创建一个名为HelloWorldManager的脚本。
3 打开HelloWorldManager.cs脚本。
4 编辑HelloWorldManager.cs脚本以匹配以下内容。
5 添加HelloWorldManager脚本作为组件。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
using Unity.Netcode; using UnityEngine; namespace HelloWorld { public class HelloWorldManager : MonoBehaviour { void OnGUI() { GUILayout.BeginArea(new Rect(10, 10, 300, 300)); if (!NetworkManager.Singleton.IsClient && !NetworkManager.Singleton.IsServer) { StartButtons(); } else { StatusLabels(); SubmitNewPosition(); } GUILayout.EndArea(); } static void StartButtons() { if (GUILayout.Button("Host")) NetworkManager.Singleton.StartHost(); if (GUILayout.Button("Client")) NetworkManager.Singleton.StartClient(); if (GUILayout.Button("Server")) NetworkManager.Singleton.StartServer(); } static void StatusLabels() { var mode = NetworkManager.Singleton.IsHost ? "Host" : NetworkManager.Singleton.IsServer ? "Server" : "Client"; GUILayout.Label("Transport: " + NetworkManager.Singleton. NetworkConfig.NetworkTransport.GetType().Name); GUILayout.Label("Mode: " + mode); } static void SubmitNewPosition() { if (GUILayout.Button( NetworkManager.Singleton.IsServer ? "Move" : "Request Position Change")) { if (NetworkManager.Singleton.IsServer && !NetworkManager.Singleton.IsClient ) { foreach (ulong uid in NetworkManager.Singleton.ConnectedClientsIds) NetworkManager.Singleton.SpawnManager. GetPlayerNetworkObject(uid). GetComponent<HelloWorldPlayer>().Move(); } else { var playerObject = NetworkManager.Singleton.SpawnManager.GetLocalPlayerObject(); var player = playerObject.GetComponent<HelloWorldPlayer>(); player.Move(); } } } } }

6 增加编辑模式

HelloWorldManager.cs脚本中,我们定义了两种方法来模拟播放模式下网络管理器中的编辑器按钮。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
static void StartButtons() { if (GUILayout.Button("Host")) NetworkManager.Singleton.StartHost(); if (GUILayout.Button("Client")) NetworkManager.Singleton.StartClient(); if (GUILayout.Button("Server")) NetworkManager.Singleton.StartServer(); } static void StatusLabels() { var mode = NetworkManager.Singleton.IsHost ? "Host" : NetworkManager.Singleton.IsServer ? "Server" : "Client"; GUILayout.Label("Transport: " + NetworkManager.Singleton.NetworkConfig.NetworkTransport.GetType().Name); GUILayout.Label("Mode: " + mode); }

网络管理器NetworkManager实现了单例模式,因为它声明了名为Singleton的单例。

  • 这是在启用MonoBehaviour时定义的。
  • 该组件还包含非常有用的属性,如IsClientIsServerIsLocalClient
  • 前两个决定了我们当前建立的连接状态,您将很快使用。

我们在OnGUI()内部调用这些方法。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void OnGUI() { GUILayout.BeginArea(new Rect(10, 10, 300, 300)); if (!NetworkManager.Singleton.IsClient && !NetworkManager.Singleton.IsServer) { StartButtons(); } else { StatusLabels(); SubmitNewPosition(); } GUILayout.EndArea(); }

NOTE

您将注意到一个新方法的引入,SubmitNewPosition();我们稍后会用到。

7 Player对象添加基本移动

HelloWorldPlayer.cs”脚本为Player添加了一些基本移动

1选择 Player 预设。
2添加脚本 ** HelloWorldPlayer** 脚本作为组件。

此类将继承自NetworkBehaviour ,而不是MonoBehaviour

复制代码
1
2
public class HelloWorldPlayer : NetworkBehaviour

在这个类中,我们现在定义一个网络变量来表示这个玩家的网络位置

复制代码
1
2
public NetworkVariable<Vector3> Position = new NetworkVariable<Vector3>();

HelloWorldPlayer重写了OnNetworkSpawn方法

复制代码
1
2
3
4
5
6
7
8
public override void OnNetworkSpawn() { if (IsOwner) { Move(); } }

任何实现NetworkBehaviourMonoBehaviour 都可以覆盖Netcode上的OnNetworkSpawn()

  • 当生成NetworkObject 并设置网络时,将触发此方法。
  • 我们覆盖OnNetworkSpawn,因为客户端和服务器在这里运行不同的逻辑。

Player实例在客户端和服务器上,我们都调用Move()方法,它将简单地执行以下操作。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void Move() { if (NetworkManager.Singleton.IsServer) { var randomPosition = GetRandomPositionOnPlane(); transform.position = randomPosition; Position.Value = randomPosition; } else { SubmitPositionRequestServerRpc(); } }

8 一些简单的RPC使用

如果这个玩家是服务器拥有的玩家,在OnNetworkSpawn()我们可以立即移动这个玩家,如下面的代码所示。

复制代码
1
2
3
4
5
6
7
if (NetworkManager.Singleton.IsServer) { var randomPosition = GetRandomPositionOnPlane(); transform.position = randomPosition; Position.Value = randomPosition; }

如果我们是一个客户端,我们需要调用 ServerRpc。ServerRpc可以由客户端调用,在服务器上执行。

RPC函数需要用[ServerRpc] [ClientRpc]修饰,并且函数名必须以ServerRpc或ClientRpc结尾。

复制代码
1
2
3
4
5
else { SubmitPositionRequestServerRpc(); }

这个ServerRpc只是通过在平面上选择一个随机点,在这个玩家的服务器实例上设置位置网络变量。

复制代码
1
2
3
4
5
6
7
[ServerRpc] void SubmitPositionRequestServerRpc(ServerRpcParams rpcParams = default) { Position.Value = GetRandomPositionOnPlane(); }

这个Player的服务器实例刚刚修改了位置网络变量,这意味着如果我们是一个客户端,我们需要在我们的更新循环中本地应用这个位置。

复制代码
1
2
3
4
5
void Update() { transform.position = Position.Value; }

我们现在可以回到HelloWorldManager.cs,定义SubmitNewPosition()的内容

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
static void SubmitNewPosition() { if (GUILayout.Button( NetworkManager.Singleton.IsServer ? "Move" : "Request Position Change")) { var playerObject = NetworkManager.Singleton .SpawnManager.GetLocalPlayerObject(); var player = playerObject. GetComponent<HelloWorldPlayer>(); player.Move(); } }

只要您按下GUI按钮(这取决于您是服务器还是客户端),您就会找到您的本地Player并简单地调用Move()


9 现在,您可以创建上述概念的demo。

一个构建实例可以创建一个 host ,另一个客户端可以加入 host 的游戏。

  • 两者都能够按下 GUI按钮 来移动,服务器将立即移动并在客户端上复制。
  • 客户端可以请求新的位置,这将指示服务器修改该服务器实例的位置网络变量。
  • 该客户端将在其Update()方法中应用该网络变量位置。

最后

以上就是体贴项链最近收集整理的关于MLAPI系列 - 02 - HelloWorld的全部内容,更多相关MLAPI系列内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(91)

评论列表共有 0 条评论

立即
投稿
返回
顶部