找回密码
 立即注册
查看: 296|回复: 0

UE4入门序列09(Unreal制作Moba端游点击移动)

[复制链接]
发表于 2021-11-7 13:24 | 显示全部楼层 |阅读模式

效果图,本人使用的调试模式开的独立客户端:


之前有做过基于网络的点击移动角色,但那个是基于Editor中的单核模式,也就是这个


使用这个模式有很多资源都是共享的,如果做的网络游戏会不准确;
#1 专用服务移动的问题解析
#2 关于SimpleMoveToLocation方法
#3 搭建同步需要蓝图测试类
#4 同步思路及参考资料
#5 CPP实现Moba同步

#1 专用服务移动的问题解析
    点击移动中的AIController是ServerOnly的,客户端拿不到的,所以我们需要自己创建然后同步到客户端移动的行为视为AI行为,AI的行为是自动化的,需要NavMesh的支持,默认NavMesh也是ServerOnly的Unreal中角色的移动是在服务器进行的,通过服务器同步到客户端专用服务器中的移动方式不能使用SimpelMoveToLocation方法
以上总结的问题都是基于对Unreal网络有了较深程度的了解之后

#2 关于SimpleMoveToLocation方法
SimpleMoveToLocation方法是一个工具方法
    该方法不能使用网络游戏该方法不支持寻路,只能做简单的移动该方法不会避开障碍物

#3 搭建同步需要蓝图
    客户端需求


    BP_WarriorController:角色控制器,玩家操作的控制器
    BP_WarriorProxy:客户端代理类,将服务器的角色位置同步到代理类,空Pawn
    服务器需求


    BP_Warrior:服务器的角色,也是客户端显示的角色
    BP_WarriorAI:服务器的AIController,点击的时候使用
蓝图功能截图:







#4 同步思路及参考资料
创建基于服务器的角色和AIController,同步角色及AIController到各个客户端,客户端使用代理角色来控制相机
参考资料:
    https://answers.unrealengine.com/questions/34074/does-ue4-have-client-side-prediction-built-in.html\https://drone-ah.com/2014/08/25/ue4-getting-multiplayer-player-pawn-ai-navigation-to-work-c/https://docs.unrealengine.com/udk/Three/NetworkingOverview.html#Player

#5 CPP实现Moba同步
  1. // HowTo_MOBA_PC.h#pragma once#include"CoreMinimal.h"#include"GameFramework/PlayerController.h"#include"HowTo_MOBA_PC.generated.h"/**
  2. *
  3. */UCLASS()classTUTORIALSDEMO_API AHowTo_MOBA_PC :public APlayerController
  4. {GENERATED_BODY()protected:virtualvoidSetupInputComponent() override;private:UFUNCTION()voidOnLeftMouseButtonPress();UFUNCTION(Server, Unreliable)voidServer_MoveToLocation(const FVector DestLocation);voidServer_MoveToLocation_Implementation(const FVector DestLocation);};
复制代码
  1. // HowTo_MOBA_PC.cpp#include"HowTo_MOBA_PC.h"#include"HowTo_MOBA_ProxyPawn.h"void AHowTo_MOBA_PC::SetupInputComponent(){
  2.         Super::SetupInputComponent();
  3.         InputComponent->BindAction(FName("LMB"), IE_Released,this,&AHowTo_MOBA_PC::OnLeftMouseButtonPress);}void AHowTo_MOBA_PC::OnLeftMouseButtonPress(){
  4.         FHitResult HitResult;bool bHit =GetHitResultUnderCursorByChannel(UEngineTypes::ConvertToTraceType(ECollisionChannel::ECC_Visibility),true, HitResult);if(bHit){Server_MoveToLocation(HitResult.ImpactPoint);}}void AHowTo_MOBA_PC::Server_MoveToLocation_Implementation(const FVector DestLocation){
  5.         APawn* _Pawn =GetPawn();
  6.         AHowTo_MOBA_ProxyPawn* ProxyPawn = Cast<AHowTo_MOBA_ProxyPawn>(_Pawn);if(ProxyPawn){
  7.                 ProxyPawn->MobaAICtrl->MoveToLocation(DestLocation);}}
复制代码
  1. // HowTo_MOBA_ProxyPawn.h#pragma once#include"CoreMinimal.h"#include"AIController.h"#include"HowTo_MOBA_Hero.h"#include"GameFramework/Pawn.h"#include"HowTo_MOBA_ProxyPawn.generated.h"UCLASS()classTUTORIALSDEMO_API AHowTo_MOBA_ProxyPawn :public APawn
  2. {GENERATED_BODY()public:// Sets default values for this pawn's propertiesAHowTo_MOBA_ProxyPawn();protected:// Called when the game starts or when spawnedvirtualvoidBeginPlay() override;virtualvoidGetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps)const override;public:// Called every framevirtualvoidTick(float DeltaTime) override;// Called to bind functionality to inputvirtualvoidSetupPlayerInputComponent(classUInputComponent* PlayerInputComponent) override;private:UPROPERTY(EditAnywhere, Meta =(AllowPrivateAccess ="true"))
  3.         TSubclassOf<AHowTo_MOBA_Hero> HeroClass;UPROPERTY(EditAnywhere, Meta =(AllowPrivateAccess ="true"))
  4.         TSubclassOf<AAIController> AICtrlClass;public:UPROPERTY(Replicated)
  5.         AAIController* MobaAICtrl;};
复制代码
  1. // HowTo_MOBA_ProxyPawn.cpp#include"HowTo_MOBA_ProxyPawn.h"#include"GeneratedCodeHelpers.h"// Sets default values
  2. AHowTo_MOBA_ProxyPawn::AHowTo_MOBA_ProxyPawn(){// Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
  3.         PrimaryActorTick.bCanEverTick =true;}// Called when the game starts or when spawnedvoid AHowTo_MOBA_ProxyPawn::BeginPlay(){
  4.         Super::BeginPlay();if(HasAuthority()){
  5.                 FActorSpawnParameters Parameters;
  6.                 Parameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;const FTransform ActorTransform =GetActorTransform();
  7.                 ACharacter* Hero =GetWorld()->SpawnActor<ACharacter>(HeroClass, ActorTransform, Parameters);
  8.                 MobaAICtrl =GetWorld()->SpawnActor<AAIController>(AICtrlClass, ActorTransform, Parameters);
  9.                 MobaAICtrl->Possess(Hero);}}void AHowTo_MOBA_ProxyPawn::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps)const{
  10.         Super::GetLifetimeReplicatedProps(OutLifetimeProps);DOREPLIFETIME(AHowTo_MOBA_ProxyPawn, MobaAICtrl);}// Called every framevoid AHowTo_MOBA_ProxyPawn::Tick(float DeltaTime){
  11.         Super::Tick(DeltaTime);}// Called to bind functionality to inputvoid AHowTo_MOBA_ProxyPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent){
  12.         Super::SetupPlayerInputComponent(PlayerInputComponent);}
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-24 22:26 , Processed in 0.089103 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表