Unreal Engine 建立局域网(Lan)连接

599 阅读3分钟

  本文记录通过蓝图以及 cpp 的方式建立局域网连接。

蓝图实现

Unreal Engine 建立局域网(Lan)连接

  使用 Open Level 节点可以切换到其它关卡, Level Name 为关卡的名字,Options 如果填 listen 则让这个实例作为 Listen Server 。使用 Execute Console Command 可以执行控制台命令,使用下面的命令可以打开 ip 地址为 192.168.0.133 的关卡(显然这是一个内网地址,也就是局域网内的地址)。

1662466072690.png

  将人数设置为 2 人后,将网络模式设置为 Play As Listen Server ,接着打包。本地运行两个打包后的 exe 文件,其中一个按 1 ,切换到新建地图并设为 Listen Server,另一个按 2 即可访问过去。

C++ 实现

编码

  Content Browser 中找到 C++ Classes ,从中找到 Character 对应的 C++ 文件。双击后 Visual Stduio 会启动。

1662518237409.png

  同时在 解决方案资源管理器 窗口中找到 Character.cpp 的头文件,如下图:

1662518473870.png

  将这两个文件进行修改,添加三个方法的声明与实现。首先是 MPTestCharacter.h

// MPTestCharacter.h

#include "CoreMinimal.h"
......

UCLASS(config=Game)
class AMPTestCharacter : public ACharacter
{
	// ......

protected:
	// ......

public:
	// ......

	UFUNCTION(BlueprintCallable)   // 这一行的作用是让这个函数能够在 Unreal Engine 的蓝图编辑器中调用
	void OpenLobby();

	UFUNCTION(BlueprintCallable)
	void CallOpenLevel(const FString& Address);

	UFUNCTION(BlueprintCallable)
	void CallClientTravel(const FString& Address);
};

  接着是 AMPTestCharacter.cpp

// Copyright Epic Games, Inc. All Rights Reserved.

......
#include "Kismet/GameplayStatics.h"   // 使用 UGameplayStatics 则需要引入

AMPTestCharacter::AMPTestCharacter()
{
	// ......

// 打开 Lobby 关卡
void AMPTestCharacter::OpenLobby() {
	UWorld* World = GetWorld();
	if(World){ // 如果获取到了游戏世界,则通过 ServerTravel 跳转到 Lobby 关卡
		// 路径中 一直到 Content 都可以用 /Game/ 代替。
		// 省略了 Lobby 的后缀
		// ?listen 让它作为 Listen Server
		World->ServerTravel("/Game/ThirdPerson/Maps/Lobby?listen"); 
	}
}

// 通过 UGameplayStatics::OpenLevel 打开关卡
void AMPTestCharacter::CallOpenLevel(const FString& Address) {
	// 打开关卡, this 代表世界上下文
	// Address 是一个字符串引用,OpenLevel 要求的第二个参数是 FName,直接传入 Address 会提示错误
	// *Address 结果是一个 C 风格字符串
	// 打开传入的关卡
	UGameplayStatics::OpenLevel(this, *Address);
}

// 通过 APlayerController 实例的 ClientTravel 打开关卡
void AMPTestCharacter::CallClientTravel(const FString& Address) {
	// 获取一个 PlayerController
	APlayerController* PlayerController = GetGameInstance()->GetFirstLocalPlayerController();
	if (PlayerController) {
		// 如果存在,则使用ClientTravel 打开传入的关卡
		PlayerController->ClientTravel(Address, ETravelType::TRAVEL_Absolute);
	}
}

// ......

  前面使用 UGameplayStatics::OpenLevel 时,第二个参数使用的方式是 *Address 。此时就产生疑惑,怎么传入引用字符串,使用时要加个 * 呢?它的用法和我理解的好像不太一样。首先想到这是 FString 类型,先看下它有没有重载运算符。果然,通过查看定义可以看到重写了 * 运算符,它返回一个 C 风格字符串。

1662524855878.png

编译

  在 Visual Studio 中编写代码后,要编译代码,使用 Ctrl + Shift + B ,它是编译(生成解决方案)的快捷键。接着,我得到了一堆错误提示,如下图:

1662525647315.png

  如此简单的操作,怎么会报错,而且报的感觉错和我做过的事情毫无关联呢?经过一番检索,我在 reditt 找到了 相关帖子 。解决这个问题,首先打开 Unreal Engine ,取消 Enable Live Coding 的勾选。

1662525926294.png

  此时,打开 Visual Studio ,再次使用Ctrl + Shift + B ,就不报错了。

在 Unreal Engine 中使用编写的 Cpp 函数

  直接挂到 BP_ThirdPersonCharacter 上面,打开蓝图编辑器如下配置:

1662525367665.png

  最后,可以打包测试了。