UE4 網(wǎng)游中角色Pawn的移動(dòng)位置同步以及RTS多角色同
下面方案的思路是:
每個(gè)Actor,為其定義一個(gè)代理(ActorProxy),真實(shí)的Actor放在服務(wù)端,代理ActorProxy放在客戶端,移動(dòng)Actor時(shí),實(shí)際是移動(dòng)服務(wù)端上的Actor,然后對(duì)客戶端ActorProxy的位置進(jìn)行同步。
攝像機(jī)綁定的是ActorProxy,服務(wù)端的真實(shí)Actor不用攝像機(jī);而AIController實(shí)際控制的是服務(wù)端Actor,客戶端其實(shí)沒有AIController。
另外,下面例子的同步機(jī)制使用的UE4自身集成的Replication(也就是常用的UFUNCTION(Server, Reliable, WithValidation)),這個(gè)是非常耗費(fèi)帶寬的,因?yàn)槭嵌〞r(shí)且頻繁的同步數(shù)據(jù)。這個(gè)如果是做局域網(wǎng)服務(wù)端還可以,但是如果是大型高負(fù)載服務(wù)端,建議自己實(shí)現(xiàn)同步機(jī)制。另外,v4.4開始,shipping編譯出來的版本會(huì)自動(dòng)刪掉UE4的server模式。原因肯定是官方也不希望這個(gè)方便測(cè)試的同步機(jī)制被開發(fā)者應(yīng)用到生產(chǎn)環(huán)境中。所以下面例子中,參考下它的思路即可,具體的同步處理的細(xì)節(jié)問題可以忽略。
RTS游戲中多角色同時(shí)移動(dòng)的方案:
為在每個(gè)自定義Pawn類定義個(gè)AIController,群體移動(dòng)時(shí),遍歷所有Pawn,依次調(diào)用各自的AIController->MoveToLocation。
另外注意點(diǎn):AIController->MoveToLocation無法像UNavigationSystem->SimpleMoveToLocation()那樣可以主動(dòng)繞開障礙物,一般建議在服務(wù)端通過UNavigationSystem獲取移動(dòng)路徑的數(shù)據(jù),然后將這些數(shù)據(jù)與客戶端同步。
可參考:
Creating a Movement Component for an RTS in UE4
http://www.gamedev.net/page/resources/_/technical/game-programming/creating-a-movement-component-for-an-rts-in-ue4-r4019
=============================================================================
=============================================================================
下面文章有點(diǎn)不足的問題是:服務(wù)端是通過AIController->MoveToLocation來尋路的,如果對(duì)于一個(gè)有障礙物的地圖來啊,移動(dòng)的時(shí)候會(huì)出現(xiàn)停滯。另外文章建議說服務(wù)端不要用UNavigationSystem>SimpleMoveToLocation,這個(gè)可能是誤解,服務(wù)端是可以使用的。
正文:
[UE4] Getting Multiplayer Player Pawn AI Navigation to work (C++)
http://droneah.com/content/ue4-getting-multiplayer-player-pawn-ai-navigation-work-c
Unreal Engine is an awesome piece of technology making it easy to do almost anything you might want.
When using the Top Down view however, there is a hurdle to get over when trying to get multiplayer to work. This is a C++ project solution to this problem based on a BluePrints solution.
The basic problem stems from the fact that
"SimpleMoveToLocation was never intended to be used in a network environment. It's simple after all ;) Currently there's no dedicated engine way of making player pawn follow a path. " (from the same page)
To be able to get a working version of SimpleMoveToLocation, we need to do the following:
Create a proxy player class (BP_WarriorProxy is BP solution)
Set the proxy class as the default player controller class
Move the camera to the proxy (Since the actual player class is on the server, we can't put a camera on it to display on the client)
The BP solution talks about four classes - our counterparts are as follows:
BP_WarriorProxy: ADemoPlayerProxy
BP_WarriorController: ADemoPlayerController (Auto-created when creating a c++ top down project)
BP_Warrior: ADemoCharacter (Auto-created when creating a C++ top down project)
BP_WarriorAI: AAIController - we have no reason to subclass it.
So, from a standard c++ top down project, the only class we need to add is the ADemoPlayerProxy - so go ahead and do that first.
The first thing we'll do is rewire the ADemoGameMode class to initialise the proxy class instead of the default MyCharacter Blueprint.
- ADemoGameMode::ADemoGameMode(const class FPostConstructInitializeProperties& PCIP) : Super(PCIP)
- {
- // use our custom PlayerController class
- PlayerControllerClass = ADemoPlayerController::StaticClass();
- // set default pawn class to our Blueprinted character
- /* static ConstructorHelpers::FClassFinder<apawn> PlayerPawnBPClass(TEXT("/Game/Blueprints/MyCharacter"));
- if (PlayerPawnBPClass.Class != NULL)
- {
- DefaultPawnClass = PlayerPawnBPClass.Class;
- }*/
- DefaultPawnClass = ADemoPlayerProxy::StaticClass();
- }
Our Player Proxy class declaration
- /* This class will work as a proxy on the client - tracking the movements of the
- * real Character on the server side and sending back controls. */
- UCLASS() class Demo_API ADemoPlayerProxy : public APawn
- {
- GENERATED_UCLASS_BODY()
- /** Top down camera */
- UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera) TSubobjectPtr<class ucameracomponent> TopDownCameraComponent;
- /** Camera boom positioning the camera above the character */
- UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera) TSubobjectPtr<class uspringarmcomponent> CameraBoom;
- // Needed so we can pick up the class in the constructor and spawn it elsewhere
- TSubclassOf<aactor> CharacterClass;
- // Pointer to the actual character. We replicate it so we know its location for the camera on the client
- UPROPERTY(Replicated) ADemoCharacter* Character;
- // The AI Controller we will use to auto-navigate the player
- AAIController* PlayerAI;
- // We spawn the real player character and other such elements here
- virtual void BeginPlay() override;
- // Use do keep this actor in sync with the real one
- void Tick(float DeltaTime);
- // Used by the controller to get moving to work
- void MoveToLocation(const FVector& vector);
- };
and the definition:
- #include "Demo.h"
- #include "DemoCharacter.h"
- #include "AIController.h"
- #include "DemoPlayerProxy.h"
- #include "UnrealNetwork.h"
- ADemoPlayerProxy::ADemoPlayerProxy(const class FPostConstructInitializeProperties& PCIP)
- : Super(PCIP)
- {
- // Don't rotate character to camera direction
- bUseControllerRotationPitch = false;
- bUseControllerRotationYaw = false;
- bUseControllerRotationRoll = false;
- // It seems that without a RootComponent, we can't place the Actual Character easily
- TSubobjectPtr<UCapsuleComponent> TouchCapsule = PCIP.CreateDefaultSubobject<ucapsulecomponent>(this, TEXT("dummy"));
- TouchCapsule->InitCapsuleSize(1.0f, 1.0f);
- TouchCapsule->SetCollisionEnabled(ECollisionEnabled::NoCollision);
- TouchCapsule->SetCollisionResponseToAllChannels(ECR_Ignore);
- RootComponent = TouchCapsule;
- // Create a camera boom...
- CameraBoom = PCIP.CreateDefaultSubobject<USpringArmComponent>(this, TEXT("CameraBoom"));
- CameraBoom->AttachTo(RootComponent);
- CameraBoom->bAbsoluteRotation = true; // Don't want arm to rotate when character does
- CameraBoom->TargetArmLength = 800.f;
- CameraBoom->RelativeRotation = FRotator(-60.f, 0.f, 0.f);
- CameraBoom->bDoCollisionTest = false; // Don't want to pull camera in when it collides with level
- // Create a camera...
- TopDownCameraComponent = PCIP.CreateDefaultSubobject<UCameraComponent>(this, TEXT("TopDownCamera"));
- TopDownCameraComponent->AttachTo(CameraBoom, USpringArmComponent::SocketName);
- TopDownCameraComponent->bUseControllerViewRotation = false; // Camera does not rotate relative to arm
- if (Role == ROLE_Authority)
- {
- static ConstructorHelpers::FObjectFinder<UClass> PlayerPawnBPClass(TEXT("/Game/Blueprints/MyCharacter.MyCharacter_C"));
- CharacterClass = PlayerPawnBPClass.Object;
- }
- }
- void ADemoPlayerProxy::BeginPlay()
- {
- Super::BeginPlay();
- if (Role == ROLE_Authority)
- {
- // Get current location of the Player Proxy
- FVector Location = GetActorLocation();
- FRotator Rotation = GetActorRotation();
- FActorSpawnParameters SpawnParams;
- SpawnParams.Owner = this;
- SpawnParams.Instigator = Instigator;
- SpawnParams.bNoCollisionFail = true;
- // Spawn the actual player character at the same location as the Proxy
- Character = Cast<ADemoCharacter>(GetWorld()->SpawnActor(CharacterClass, &Location, &Rotation, SpawnParams));
- // We use the PlayerAI to control the Player Character for Navigation
- PlayerAI = GetWorld()->SpawnActor<AAIController>(GetActorLocation(), GetActorRotation());
- PlayerAI->Possess(Character);
- }
- }
- void ADemoPlayerProxy::Tick(float DeltaTime)
- {
- Super::Tick(DeltaTime);
- if (Character)
- {
- // Keep the Proxy in sync with the real character
- FTransform CharTransform = Character->GetTransform();
- FTransform MyTransform = GetTransform();
- FTransform Transform;
- Transform.LerpTranslationScale3D(CharTransform, MyTransform, ScalarRegister(0.5f));
- SetActorTransform(Transform);
- <li micxptag"="" style="overflow-wrap: break-word; margin: 0px 0px 0px 38px; padding: 0px; font-size: 1em;">虛幻4,ue4,虛幻4入門,虛幻4基礎(chǔ),虛幻4高級(jí)
-
分享到:
您需要登錄后才可以發(fā)帖 登錄 | 立即注冊(cè)
- 用戶名:
- 密 碼:
- 驗(yàn)證碼: 看不清? 點(diǎn)擊更換
- 忘記密碼?
全部評(píng)論:0條