本文记录通过蓝图以及 cpp 的方式建立局域网连接。
蓝图实现
Unreal Engine 建立局域网(Lan)连接
使用 Open Level 节点可以切换到其它关卡, Level Name 为关卡的名字,Options 如果填 listen 则让这个实例作为 Listen Server 。使用 Execute Console Command 可以执行控制台命令,使用下面的命令可以打开 ip 地址为 192.168.0.133 的关卡(显然这是一个内网地址,也就是局域网内的地址)。
将人数设置为 2 人后,将网络模式设置为 Play As Listen Server ,接着打包。本地运行两个打包后的 exe 文件,其中一个按 1 ,切换到新建地图并设为 Listen Server,另一个按 2 即可访问过去。
C++ 实现
编码
Content Browser 中找到 C++ Classes ,从中找到 Character 对应的 C++ 文件。双击后 Visual Stduio 会启动。
同时在 解决方案资源管理器 窗口中找到 Character.cpp 的头文件,如下图:
将这两个文件进行修改,添加三个方法的声明与实现。首先是 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 风格字符串。
编译
在 Visual Studio 中编写代码后,要编译代码,使用 Ctrl + Shift + B ,它是编译(生成解决方案)的快捷键。接着,我得到了一堆错误提示,如下图:
如此简单的操作,怎么会报错,而且报的感觉错和我做过的事情毫无关联呢?经过一番检索,我在 reditt 找到了 相关帖子 。解决这个问题,首先打开 Unreal Engine ,取消 Enable Live Coding 的勾选。
此时,打开 Visual Studio ,再次使用Ctrl + Shift + B ,就不报错了。
在 Unreal Engine 中使用编写的 Cpp 函数
直接挂到 BP_ThirdPersonCharacter 上面,打开蓝图编辑器如下配置:
最后,可以打包测试了。