我是靠谱客的博主 体贴项链,最近开发中收集的这篇文章主要介绍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脚本以匹配以下内容。

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时定义的。
  • 该组件还包含非常有用的属性,如IsClientIsServerIsLocalClient
  • 前两个决定了我们当前建立的连接状态,您将很快使用。

我们在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();
}
}

任何实现NetworkBehaviourMonoBehaviour 都可以覆盖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所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部