下面方案的思路是:
每个Actor,为其定义一个代理(ActorProxy),真实的Actor放在服务端,代理ActorProxy放在客户端,移动Actor时,实际是移动服务端上的Actor,然后对客户端ActorProxy的位置进行同步。

摄像机绑定的是ActorProxy,服务端的真实Actor不用摄像机;而AIController实际控制的是服务端Actor,客户端其实没有AIController。

另外,下面例子的同步机制使用的ue4自身集成的Replication(也就是常用的UFUNCTION(Server, Reliable, WithValidation)),这个是非常耗费带宽的,因为是定时且频繁的同步数据。这个如果是做局域网服务端还可以,但是如果是大型高负载服务端,建议自己实现同步机制。另外,v4.4开始,shipping编译出来的版本会自动删掉UE4的server模式。原因肯定是官方也不希望这个方便测试的同步机制被开发者应用到生产环境中。所以下面例子中,参考下它的思路即可,具体的同步处理的细节问题可以忽略。

RTS游戏中多角色同时移动的方案:

为在每个自定义Pawn类定义个AIController,群体移动时,遍历所有Pawn,依次调用各自的AIController->MoveToLocation。

另外注意点:AIController->MoveToLocation无法像UNavigationSystem->SimpleMoveToLocation()那样可以主动绕开障碍物,一般建议在服务端通过UNavigationSystem获取移动路径的数据,然后将这些数据与客户端同步。

可参考:
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

=============================================================================

=============================================================================

下面文章有点不足的问题是:服务端是通过AIController->MoveToLocation来寻路的,如果对于一个有障碍物的地图来啊,移动的时候会出现停滞。另外文章建议说服务端不要用UNavigationSystem>SimpleMoveToLocation,这个可能是误解,服务端是可以使用的。

正文:

[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.

Cpp代码  
  1. ADemoGameMode::ADemoGameMode(const class FPostConstructInitializeProperties& PCIP) : Super(PCIP)
  2. {
  3. // use our custom PlayerController class
  4. PlayerControllerClass = ADemoPlayerController::StaticClass();
  5. // set default pawn class to our Blueprinted character
  6. /* static ConstructorHelpers::FClassFinder<apawn> PlayerPawnBPClass(TEXT("/Game/Blueprints/MyCharacter"));
  7. if (PlayerPawnBPClass.Class != NULL)
  8. {
  9. DefaultPawnClass = PlayerPawnBPClass.Class;
  10. }*/
  11. DefaultPawnClass = ADemoPlayerProxy::StaticClass();
  12. }

Our Player Proxy class declaration

Cpp代码  
  1. /* This class will work as a proxy on the client - tracking the movements of the
  2. * real Character on the server side and sending back controls. */
  3. UCLASS() class Demo_API ADemoPlayerProxy : public APawn
  4. {
  5. GENERATED_UCLASS_BODY()
  6. /** Top down camera */
  7. UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera) TSubobjectPtr<class ucameracomponent> TopDownCameraComponent;
  8. /** Camera boom positioning the camera above the character */
  9. UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera) TSubobjectPtr<class uspringarmcomponent> CameraBoom;
  10. // Needed so we can pick up the class in the constructor and spawn it elsewhere
  11. TSubclassOf<aactor> CharacterClass;
  12. // Pointer to the actual character. We replicate it so we know its location for the camera on the client
  13. UPROPERTY(Replicated) ADemoCharacter* Character;
  14. // The AI Controller we will use to auto-navigate the player
  15. AAIController* PlayerAI;
  16. // We spawn the real player character and other such elements here
  17. virtual void BeginPlay() override;
  18. // Use do keep this actor in sync with the real one
  19. void Tick(float DeltaTime);
  20. // Used by the controller to get moving to work
  21. void MoveToLocation(const FVector& vector);
  22. };

and the definition:

Cpp代码  
  1. #include "Demo.h"
  2. #include "DemoCharacter.h"
  3. #include "AIController.h"
  4. #include "DemoPlayerProxy.h"
  5. #include "UnrealNetwork.h"
  6. ADemoPlayerProxy::ADemoPlayerProxy(const class FPostConstructInitializeProperties& PCIP)
  7. : Super(PCIP)
  8. {
  9. // Don't rotate character to camera direction
  10. bUseControllerRotationPitch = false;
  11. bUseControllerRotationYaw = false;
  12. bUseControllerRotationRoll = false;
  13. // It seems that without a RootComponent, we can't place the Actual Character easily
  14. TSubobjectPtr<UCapsuleComponent> TouchCapsule = PCIP.CreateDefaultSubobject<ucapsulecomponent>(this, TEXT("dummy"));
  15. TouchCapsule->InitCapsuleSize(1.0f, 1.0f);
  16. TouchCapsule->SetCollisionEnabled(ECollisionEnabled::NoCollision);
  17. TouchCapsule->SetCollisionResponseToAllChannels(ECR_Ignore);
  18. RootComponent = TouchCapsule;
  19. // Create a camera boom...
  20. CameraBoom = PCIP.CreateDefaultSubobject<USpringArmComponent>(this, TEXT("CameraBoom"));
  21. CameraBoom->AttachTo(RootComponent);
  22. CameraBoom->bAbsoluteRotation = true; // Don't want arm to rotate when character does
  23. CameraBoom->TargetArmLength = 800.f;
  24. CameraBoom->RelativeRotation = FRotator(-60.f, 0.f, 0.f);
  25. CameraBoom->bDoCollisionTest = false; // Don't want to pull camera in when it collides with level
  26. // Create a camera...
  27. TopDownCameraComponent = PCIP.CreateDefaultSubobject<UCameraComponent>(this, TEXT("TopDownCamera"));
  28. TopDownCameraComponent->AttachTo(CameraBoom, USpringArmComponent::SocketName);
  29. TopDownCameraComponent->bUseControllerViewRotation = false; // Camera does not rotate relative to arm
  30. if (Role == ROLE_Authority)
  31. {
  32. static ConstructorHelpers::FObjectFinder<UClass> PlayerPawnBPClass(TEXT("/Game/Blueprints/MyCharacter.MyCharacter_C"));
  33. CharacterClass = PlayerPawnBPClass.Object;
  34. }
  35. }
  36. void ADemoPlayerProxy::BeginPlay()
  37. {
  38. Super::BeginPlay();
  39. if (Role == ROLE_Authority)
  40. {
  41. // Get current location of the Player Proxy
  42. FVector Location =  GetActorLocation();
  43. FRotator Rotation = GetActorRotation();
  44. FActorSpawnParameters SpawnParams;
  45. SpawnParams.Owner = this;
  46. SpawnParams.Instigator = Instigator;
  47. SpawnParams.bNoCollisionFail = true;
  48. // Spawn the actual player character at the same location as the Proxy
  49. Character = Cast<ADemoCharacter>(GetWorld()->SpawnActor(CharacterClass, &Location, &Rotation, SpawnParams));
  50. // We use the PlayerAI to control the Player Character for Navigation
  51. PlayerAI = GetWorld()->SpawnActor<AAIController>(GetActorLocation(), GetActorRotation());
  52. PlayerAI->Possess(Character);
  53. }
  54. }
  55. void ADemoPlayerProxy::Tick(float DeltaTime)
  56. {
  57. Super::Tick(DeltaTime);
  58. if (Character)
  59. {
  60. // Keep the Proxy in sync with the real character
  61. FTransform CharTransform = Character->GetTransform();
  62. FTransform MyTransform = GetTransform();
  63. FTransform Transform;
  64. Transform.LerpTranslationScale3D(CharTransform, MyTransform, ScalarRegister(0.5f));
  65. SetActorTransform(Transform);
  66. <li micxptag"="" style="word-wrap: break-word; margin: 0px 0px 0px 38px; padding: 0px; font-size: 1em;">虚幻4,ue4,虚幻4入门,虚幻4基础,虚幻4高级

[UE4]网游中角色Pawn的移动位置同步以及RTS多角色同时移动的解决方案相关推荐

  1. 网游中的网络编程系列1:UDP vs. TCP

    原文:UDP vs. TCP,作者是Glenn Fiedler,专注于游戏网络编程相关工作多年. 目录 网游中的网络编程系列1:UDP vs. TCP 网游中的网络编程2:发送和接收数据包 网游中的网 ...

  2. 3D网游中人物的碰撞后反应控制

    人物移动控制是单机和网游中比较重要的部分,但前单机游戏使用动力学以及IK动画等已经达到了非常逼真的地步,在大型网络游戏中这样的物理模拟同步是很实现的,因此在目前多数网游中仍旧是采取使用一个包围体(盒子 ...

  3. 网游中针对网络延迟的优化

    在网络游戏中,由于延迟或者网络状况的抖动,可能会将客户端效果产生一定的扭曲和卡顿.影响玩家体验以及进一步的操作.要降低因为延迟带来的体验问题,有两种策略,一种为客户端预测,一种为延迟补偿. 1.客户端 ...

  4. 上海全市实景被搬到韩国赛车网游中

    转自:DoNews http://www.donews.com/Content/200512/a4c78c68-cb0e-4c7e-a64b-e78e608cb523.shtm 12月22日,大型网络 ...

  5. 关于wow网游中软件管理的设想

    偶尔会玩下wow,特别是在大的公会里,都有排队等候RL 召唤进副本的现象,对于一些暂时没有需求或者装备太差的人 就在在副本门口等候召唤的现象,我在想,如果我的软件团队中也有冗余人员,一般会进行测试,而 ...

  6. wegame饥荒一直连接中_谁是老牛?谁是嫩草?WeGame与老牌网游的故事 | 游戏茶馆...

    每当WeGame上的大型网游名单上又多出一位"新来"的客人时,WeGame都会收到一些质疑的声音. "好的单机没引进多少,国内快凉的老网游倒是一个接一个的迎上来" ...

  7. 2010.5.11项目管理群主题:网游那些事-DDV731731-SSE

    ddv731731-SSE-上海 说:  今天的想法是玩游戏中的一些感受结合现实谈谈自己的一点感受,那我就以网游为例. 大家都知道我们国家网游的普及程度之广,参与人数之多,大大小小的游戏公司,数不清的 ...

  8. 浅谈3D网游引擎变迁史 看国产游戏引擎趋势

    玩家们在享受游戏带来的快乐时,其实很少想到游戏引擎到底发挥了多么重要的作用.无论是2D游戏还是3D游戏,游戏引擎都充当着游戏骨架的角色,没有游戏引擎就无法做出一款真正的游戏,通过游戏引擎制作者可以把画 ...

  9. 以网游服务端的网络接入层设计为例,理解实时通信的技术挑战

    前言 以现在主流的即时通讯应用形态来讲,一个完整的即时通讯IM应用其实是即时通信(英文简写:IM=Instant messaging)和实时通信(英文简写:RTC=Real-time communic ...

最新文章

  1. 基于YOLO的手部检测和计数实现(课程设计,训练和测试)(1)
  2. 企业移动化诉求与开发者之间的矛盾
  3. visual basic.net 2019-当前内存状态、字符串内插、操作系统系统信息
  4. PostgreSQL在何处处理 sql查询
  5. [html] 你知道短链接的生成原理吗?
  6. 排序算法 --- 希尔排序
  7. jQuery设计动画
  8. php生日计算年龄,php根据生日计算年龄的方法
  9. centos 的php5.3.3 升级5.5.3
  10. Swift之 ? 和 !
  11. 汽车UDS诊断之控制诊断故障码设置服务(0x85)深度剖析
  12. java 10的 6次方_【Java】 剑指offer(15) 数值的整数次方
  13. 弘辽科技:复购率太低怎么办呢?
  14. 邮件服务器加密方式,盈世Coremail邮件系统四种安全加密方式揭秘
  15. Python爬取网易云音乐歌手歌曲和歌单!推荐好听的歌吗?
  16. 隐秘的度假地_如何避免花太多钱去度假
  17. Linux Regulator Framework(1) - Framework
  18. scrapy框架基础学习之囧事百科
  19. 索引顺序查找(分块查找)
  20. 计算器算贝塞尔公式_绝版应用!超级好用的计算器!

热门文章

  1. vuex-along解决vuex中存储的数据在页面刷新之后失去的问题
  2. STlink下载出现st-link usb communication error解决方法
  3. Docker系列5--一些问题及解决
  4. json_decode到数组
  5. 如何混淆(保护)JavaScript? [关闭]
  6. 1990: 分解质因数
  7. HTC推出新款VR头显,奇怪的是只在日本销售
  8. Spring Boot持久化的简单实现
  9. apache nginx 性能简单对比测试
  10. 【linux高级程序设计】(第十一章)System V进程间通信 3