概述
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
脚本以匹配以下内容。
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
脚本作为组件。
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
脚本中,我们定义了两种方法来模拟播放模式下网络管理器中的编辑器按钮。
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
时定义的。- 该组件还包含非常有用的属性,如
IsClient
、IsServer
和IsLocalClient
。- 前两个决定了我们当前建立的连接状态,您将很快使用。
我们在OnGUI()内部调用这些方法。
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
public class HelloWorldPlayer : NetworkBehaviour
在这个类中,我们现在定义一个网络变量来表示这个玩家的网络位置
public NetworkVariable<Vector3> Position = new NetworkVariable<Vector3>();
HelloWorldPlayer
重写了OnNetworkSpawn
方法
public override void OnNetworkSpawn()
{
if (IsOwner)
{
Move();
}
}
任何实现NetworkBehaviour
的MonoBehaviour
都可以覆盖Netcode
上的OnNetworkSpawn()
。
- 当生成
NetworkObject
并设置网络时,将触发此方法。- 我们覆盖
OnNetworkSpawn
,因为客户端和服务器在这里运行不同的逻辑。
Player实例在客户端和服务器上,我们都调用Move()方法,它将简单地执行以下操作。
public void Move()
{
if (NetworkManager.Singleton.IsServer)
{
var randomPosition = GetRandomPositionOnPlane();
transform.position = randomPosition;
Position.Value = randomPosition;
}
else
{
SubmitPositionRequestServerRpc();
}
}
8 一些简单的RPC使用
如果这个玩家是服务器拥有的玩家,在OnNetworkSpawn()
我们可以立即移动这个玩家,如下面的代码所示。
if (NetworkManager.Singleton.IsServer)
{
var randomPosition = GetRandomPositionOnPlane();
transform.position = randomPosition;
Position.Value = randomPosition;
}
如果我们是一个客户端,我们需要调用 ServerRpc。ServerRpc可以由客户端调用,在服务器上执行。
RPC函数需要用[ServerRpc] [ClientRpc]修饰,并且函数名必须以ServerRpc或ClientRpc结尾。
else
{
SubmitPositionRequestServerRpc();
}
这个ServerRpc只是通过在平面上选择一个随机点,在这个玩家的服务器实例上设置位置网络变量。
[ServerRpc]
void SubmitPositionRequestServerRpc(ServerRpcParams rpcParams = default)
{
Position.Value = GetRandomPositionOnPlane();
}
这个Player的服务器实例刚刚修改了位置网络变量,这意味着如果我们是一个客户端,我们需要在我们的更新循环中本地应用这个位置。
void Update()
{
transform.position = Position.Value;
}
我们现在可以回到HelloWorldManager.cs
,定义SubmitNewPosition()
的内容
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系列 - 02 - HelloWorld所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复