|
效果图,本人使用的调试模式开的独立客户端:
之前有做过基于网络的点击移动角色,但那个是基于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同步- // HowTo_MOBA_PC.h#pragma once#include"CoreMinimal.h"#include"GameFramework/PlayerController.h"#include"HowTo_MOBA_PC.generated.h"/**
- *
- */UCLASS()classTUTORIALSDEMO_API AHowTo_MOBA_PC :public APlayerController
- {GENERATED_BODY()protected:virtualvoidSetupInputComponent() override;private:UFUNCTION()voidOnLeftMouseButtonPress();UFUNCTION(Server, Unreliable)voidServer_MoveToLocation(const FVector DestLocation);voidServer_MoveToLocation_Implementation(const FVector DestLocation);};
复制代码- // HowTo_MOBA_PC.cpp#include"HowTo_MOBA_PC.h"#include"HowTo_MOBA_ProxyPawn.h"void AHowTo_MOBA_PC::SetupInputComponent(){
- Super::SetupInputComponent();
- InputComponent->BindAction(FName("LMB"), IE_Released,this,&AHowTo_MOBA_PC::OnLeftMouseButtonPress);}void AHowTo_MOBA_PC::OnLeftMouseButtonPress(){
- 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){
- APawn* _Pawn =GetPawn();
- AHowTo_MOBA_ProxyPawn* ProxyPawn = Cast<AHowTo_MOBA_ProxyPawn>(_Pawn);if(ProxyPawn){
- ProxyPawn->MobaAICtrl->MoveToLocation(DestLocation);}}
复制代码- // 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
- {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"))
- TSubclassOf<AHowTo_MOBA_Hero> HeroClass;UPROPERTY(EditAnywhere, Meta =(AllowPrivateAccess ="true"))
- TSubclassOf<AAIController> AICtrlClass;public:UPROPERTY(Replicated)
- AAIController* MobaAICtrl;};
复制代码- // HowTo_MOBA_ProxyPawn.cpp#include"HowTo_MOBA_ProxyPawn.h"#include"GeneratedCodeHelpers.h"// Sets default values
- 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.
- PrimaryActorTick.bCanEverTick =true;}// Called when the game starts or when spawnedvoid AHowTo_MOBA_ProxyPawn::BeginPlay(){
- Super::BeginPlay();if(HasAuthority()){
- FActorSpawnParameters Parameters;
- Parameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;const FTransform ActorTransform =GetActorTransform();
- ACharacter* Hero =GetWorld()->SpawnActor<ACharacter>(HeroClass, ActorTransform, Parameters);
- MobaAICtrl =GetWorld()->SpawnActor<AAIController>(AICtrlClass, ActorTransform, Parameters);
- MobaAICtrl->Possess(Hero);}}void AHowTo_MOBA_ProxyPawn::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps)const{
- Super::GetLifetimeReplicatedProps(OutLifetimeProps);DOREPLIFETIME(AHowTo_MOBA_ProxyPawn, MobaAICtrl);}// Called every framevoid AHowTo_MOBA_ProxyPawn::Tick(float DeltaTime){
- Super::Tick(DeltaTime);}// Called to bind functionality to inputvoid AHowTo_MOBA_ProxyPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent){
- Super::SetupPlayerInputComponent(PlayerInputComponent);}
复制代码
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|