UE4入门序列05(UE MMO游戏制作鼠标点击移动)


演示效果,模拟专用服务器多人游戏时候的同步场景,本文只作功能解析:
本人郑重说明,Unreal是可以做任何类型游戏的,门槛非常高

呀哈哈,就这么一个点击移动的功能,如果放在Unity中几句代码,放在Unreal中可是非常的复杂,因为
这个行为在Unreal中认为是一个AI行为,点击了地面,然后自动移动过去,没有玩家的参与,这不就是AI行为?
Unreal是这么认识的,所以这个行为会经过Unreal中AI、检测、导航、移动、目标、及Network;


涉及到的功能点包括:AI、检测、导航、移动、目标、及Network

#1 执行流程图,简化版
UE4入门序列05(UE MMO游戏制作鼠标点击移动)_第1张图片


#2 AI部分说明

点击地面进行移动需要有AI的功能,我们操作的角色不是AI,Unreal中的角色可以携带一个AI功能;不需要这个角色本身就是一个AI的主体,每个Character的子类都有AIController的功能,默认情况下会生成一个
UE4入门序列05(UE MMO游戏制作鼠标点击移动)_第2张图片
如果制作AI也会用到,这里的AI表示自动化,并不真正的要表示是一个AI。


#3 当前使用到检测功能

点击需要检测鼠标点击到地面的位置信息,有两种方式,一般使用第二种,效率高
转换的地方,这个源码资料很少有的

// Trace to see what is under the mouse cursor
FHitResult Hit;
GetHitResultUnderCursor(ECC_Visibility, false, Hit);
GetHitResultUnderCursorByChannel(UEngineTypes::ConvertToTraceType(ECC_Camera), true, Hit);


#4 Unreal中的导航功能

Unreal的导航功能咋一看好像非常的强大,应该是非常的强大,在AI的移动的时候可以看到;
Project Settings中也有NavMeshSystem相关的设置,

MoveToLocation(const FVector& Dest, float AcceptanceRadius, bool bStopOnOverlap, bool bUsePathfinding, bool bProjectDestinationToNavigation, bool bCanStrafe, TSubclassOf<UNavigationQueryFilter> FilterClass, bool bAllowPartialPaths

在这里插入图片描述


#5 导航移动

如果是使用默认的AIController,可以使用这个简单的移动功能,更加高级的移动功能需要自定义AIController,在
AIController中进行功能封装;

UAIBlueprintHelperLibrary::SimpleMoveToLocation(this, DestLocation);
AAIController* AIC = UAIBlueprintHelperLibrary::GetAIController(SelectedCharacter);
if (AIC)
{
     
	AHowToCTM_AIController* AICC = Cast<AHowToCTM_AIController>(AIC);
	if (AICC)
	{
     
		AICC->MoveUnit(Location);
		//Ctm_AIController->MoveUnit();
	}
}

#6 点击的目标
Unreal的NavMesh如果在多人Online的情况,是在服务器端才有控制权的,客户端默认不会开启控制权,需要手动开启客户端的NavMesh导航寻路功能,见tag1标记处


#7 Uneral中的RPC Network
Unreal的多人游戏制作,如果使用UnrealNetwork.h;则会进入混合开发,客户端也是服务器,服务器也是客户端;非常方便的进行网络游戏的开发及调试;Unreal使用的SC网络,Server对所有客户端都进行同步;
客户端默认情况下只有Owning权限,需要告诉服务器那些事情需要让其他客户端知道;
点击移动中,客户端需要让服务器知道,我请求移动,其中:

private:
	UFUNCTION(Server, Unreliable)
	void Server_NewDestination(const FVector DestLocation);
	void Server_NewDestination_Implementation(const FVector DestLocation);

一般情况下使用Unreliable,差不多理解为UDP网络把,Reliable相当于TCP;如果使用Reliable,数据是需要经过一次确认的,然后再执行,使用Unreliable是数据是不需要经过确认的,各有优劣。


放个工具方法,方便分屏调试使用

FString GetPIENetModeNamePrefix(UWorld* WorldContext)
{
     
	FString NameType("");
	if (WorldContext)
	{
     
		if (WorldContext->WorldType == EWorldType::PIE)
		{
     
			switch (WorldContext->GetNetMode())
			{
     
				case NM_Standalone:
					NameType = TEXT("Standalone:");
					break;
				case NM_DedicatedServer:
					NameType = TEXT("DedicatedServer:");
					break;
				case NM_ListenServer:
					NameType = TEXT("ListenServer:");
					break;
				case NM_Client:
					NameType = FString::Printf(TEXT("Client %d:"), GPlayInEditorID - 1);
					break;
				case NM_MAX:
					NameType = TEXT("MAX:");
					break;
				default: ;
			}
		}
	}
	return NameType;
}

你可能感兴趣的:(Unreal,Unreal)