UE4网络同步实战:AIController与RPC架构解析与避坑指南

1. 项目概述:为什么AIController与RPC是UE4面试的“硬通货”?

如果你正在准备一场UE4客户端或网络同步方向的面试,尤其是瞄准中高级岗位,那么“AIController的网络同步”和“RPC的正确使用”这两个话题,几乎可以肯定是面试官手中的“王炸”问题。它们不像“什么是蓝图接口”那样基础,也不像“渲染管线优化”那样过于深入特定领域。它们恰好卡在了一个核心的十字路口:既要深刻理解UE4的Gameplay框架(Controller、Pawn、Actor的关系),又要精通网络同步模型(客户端-服务器架构、所有权、RPC),同时还得具备解决实际线上问题的能力(比如“为什么我的AI在客户端不动了?”)。我见过太多简历上写着“精通UE4网络同步”的候选人,在这两个问题上折戟沉沙。今天,我就结合自己踩过的坑和项目里的实战经验,把这套“组合拳”拆开揉碎了讲给你听,让你不仅能回答面试问题,更能理解背后的设计哲学和避坑指南。

简单来说,这个主题探讨的核心是: 如何在多玩家网络游戏中,让由AI控制的角色(AIController)的行为,在不同客户端上正确、高效且可控地同步。 这绝不仅仅是调用一个 Server Client RPC那么简单。它涉及到AIController的生成与归属权、移动指令的发起与验证、RPC的可靠性与执行目标选择等一系列环环相扣的决策。理解透了它,你对UE4网络层的认知会上一个大台阶。

2. 核心概念深度拆解:AIController与RPC的“前世今生”

在动手写代码之前,我们必须把地基打牢。很多同步问题,根源在于对基本概念的理解有偏差。

2.1 AIController:它到底是谁?在哪里?

AIController是Controller的子类,而Controller是UE4中用于“控制”Pawn的逻辑实体。你可以把它理解为一个“驾驶员”。PlayerController是真人玩家的“驾驶员”,而AIController则是AI逻辑的“驾驶员”。

关键点一:AIController的生成与存在性。 默认情况下,在Listen Server(监听服务器)或Dedicated Server(专用服务器)模式下,AIController 只在服务器端生成和存在 。这是UE4的默认设计,因为AI的决策逻辑(如寻路、选择目标)被认为是权威的、应该由服务器来执行的。客户端通常只接收服务器同步过来的Pawn状态(位置、旋转),并进行视觉表现。

关键点二:AIController的“拥有权”。 在UE4网络模型中,一个Actor(包括Controller)必须有一个“Owner”(不是指C++里的UObject Owner,而是网络意义上的“拥有者”)。PlayerController通常由连接过来的客户端“拥有”。而AIController,默认情况下由 服务器拥有 。这意味着,对这个AIController调用RPC时,你必须要清楚RPC的执行目标是谁。

面试高频问题:“客户端需要AIController吗?” 答案是: 视情况而定,但通常不需要,也不推荐客户端拥有完整的AIController。

  • 不需要 :如果AI的行为完全由服务器驱动(服务器计算移动,客户端只做表现),那么客户端根本不需要AIController实例。客户端上的AI Pawn只是一个“提线木偶”。
  • 不推荐 :如果你为了让客户端也能调用 MoveToLocation 而手动在客户端生成一个AIController,你会立刻面临严重的同步和作弊问题。两个AIController(服务器一个,客户端一个)会发出两套可能矛盾的移动指令,游戏状态将彻底混乱。

那么,社区里讨论的“Client-side AI Controller”是什么场景?通常是一些特殊的、对实时性要求极高且逻辑简单的客户端本地特效AI,比如一群纯粹为了烘托气氛、不与游戏核心逻辑交互的飞鸟。即便如此,也需要极其小心地设计,避免与服务器权威状态冲突。

2.2 RPC(远程过程调用):网络游戏的“指挥棒”

RPC是UE4网络同步的基石,它允许你在一个机器(如服务器)上调用一个函数,而在另一个机器(如客户端)上执行它。

三种核心RPC:

  1. Server RPC (UFUNCTION(Server, Reliable/Unreliable)) : 只能在客户端调用,在服务器上执行。用于客户端向服务器发送请求,如“我要攻击”、“我要移动到这里”。
  2. Client RPC (UFUNCTION(Client, Reliable/Unreliable)) : 只能在服务器调用,在指定的客户端上执行。用于服务器向特定客户端发送通知,如“你被击中了”、“播放这个特效”。
  3. NetMulticast RPC (UFUNCTION(NetMulticast, Reliable/Unreliable)) : 只能在服务器调用,在服务器和 所有客户端 上执行。用于广播全局事件,如“爆炸了”、“游戏开始”。

面试必考细节:RPC的执行者与目标。 这是最容易混淆的地方。以 UFUNCTION(Client) 为例:

// 在服务器端的某个Actor(比如AIController)里
void AAIController::TellClientSomething()
{
    // 这个RPC会在“这个Actor的拥有者客户端”上执行。
    // 如果这个AIController由服务器拥有,它没有对应的客户端拥有者,那么这个RPC将无处可去,不会执行!
    ClientRPCFunction();
}

对于AIController,由于它通常由服务器拥有,你 无法 直接从这个AIController上调用一个Client RPC到某个玩家的客户端。你需要找到正确的“信使”。通常,这个信使是:

  • 玩家控制的Pawn :它被某个客户端拥有。
  • 玩家的PlayerController :它直接被某个客户端拥有。
  • GameState :它在所有机器上存在,且服务器拥有,适合广播(NetMulticast)。

Reliable vs Unreliable:

  • Reliable(可靠) :保证送达,且按顺序送达。用于关键指令,如技能释放、物品拾取。但滥用会导致网络缓冲区堆积(Buffer)。
  • Unreliable(不可靠) :不保证送达,可能丢失,也可能乱序。用于高频、可容忍丢失的数据,如每帧的位置更新(实际上位置更新通常用属性同步Property Replication,而非RPC)。

3. 实战架构设计:四种经典场景与选型思路

理解了概念,我们来看实战。面对“AI移动同步”这个问题,根据你的游戏类型和AI角色重要性,至少有四种主流架构。选择哪一种,直接决定了你代码的复杂度和后期的维护成本。

3.1 场景一:完全服务器权威AI(最常用、最推荐)

这是MMO、MOBA、战术竞技等严肃网络游戏的标准做法。

  • 设计 :AIController仅存在于服务器。AI的感知(看见玩家)、决策(选择目标)、移动(寻路到某点)全部在服务器进行。
  • 同步方式
    1. 服务器AIController调用 MoveToLocation()
    2. AI Pawn的移动组件(如 CharacterMovementComponent )在服务器上计算移动。
    3. 由于AI Pawn的 bReplicates 设为true,且其位置( ReplicatedMovement )被设置为同步,服务器会自动将移动结果(位置、速度)同步给所有客户端。
    4. 客户端收到位置更新后,驱动本地AI Pawn的骨骼网格体移动,实现视觉同步。
  • 优点 :绝对防作弊,逻辑统一,状态一致。符合UE4默认设计,开发阻力小。
  • 缺点 :所有AI计算负载都在服务器,服务器压力大。客户端看到的移动有网络延迟。
  • RPC使用 :在这种模式下, AI移动本身通常不直接使用RPC 。移动是状态同步(属性复制)。RPC可能用于AI触发的特定事件,比如AI释放了一个技能(Server RPC通知服务器计算伤害,NetMulticast RPC播放全服特效)。

3.2 场景二:客户端预测式移动(用于玩家角色,AI慎用)

这是FPS游戏中玩家角色移动的常见模式,用于AI需要非常谨慎。

  • 设计 :客户端拥有一个AIController(或移动逻辑),可以立即响应并移动本地AI角色,同时将移动意图(输入)通过Server RPC发送给服务器。服务器验证后执行权威移动,并将结果同步回来,客户端进行纠偏(Reconciliation)。
  • 对于AI :这极其复杂。你需要在客户端模拟AI的决策逻辑,并保证与服务器的逻辑完全一致(几乎不可能)。一旦出现分歧(客户端AI认为该追击,服务器AI认为该撤退),纠偏会变得非常诡异。 除非AI逻辑极其简单且确定(如巡逻固定点),否则不推荐。
  • RPC使用 :客户端AI逻辑调用 Server_MoveTo RPC,将目标点发给服务器。服务器验证后执行移动。

3.3 场景三:客户端自主视觉表现(“假AI”)

这就是开头论坛帖子可能想尝试的。AI没有游戏逻辑意义,纯装饰。

  • 设计 :在客户端本地生成AI Pawn和AIController,其移动、行为完全在客户端计算和表现,不与服务器同步任何状态。服务器甚至不知道它的存在。
  • 用途 :场景中的小动物、飘动的旗帜、无关紧要的NPC背景板。
  • RPC使用 :完全不需要RPC,因为不涉及网络。
  • 重要配置 :需要在项目设置中开启“Allow Client Side Navigation”,客户端的导航系统才会工作。但即使开启了,如论坛帖子所述,直接调用 MoveToLocation 可能仍不工作,因为客户端的导航网格(NavMesh)可能没有正确生成或加载。你需要确保客户端也有完整的导航数据。

3.4 场景四:混合模式 - 服务器决策,客户端执行(高阶)

一种折中方案,平衡服务器压力和响应速度。

  • 设计 :服务器负责AI的“决策”(目标是谁,是否攻击),这个决策结果通过RPC(如Client RPC)下达给客户端。客户端收到指令后, 使用本地的AIController执行具体的移动和动画
  • 关键 :服务器必须保持 最终权威 。例如,服务器定期检查客户端AI的位置,如果偏离预期(可能是作弊或Bug),服务器可以强制同步一个正确位置(通过设置Pawn的Location,这会覆盖客户端移动),或者发送一个修正指令。
  • RPC使用 :服务器通过某个中介(如GameMode)调用一个在AI Pawn上的Client RPC,通知它“向X点移动”。AI Pawn在客户端收到后,调用本地AIController的 MoveToLocation
  • 优点 :移动响应快(无网络延迟),服务器只做决策,计算压力小。
  • 缺点 :架构复杂,需要设计一套完善的指令与状态校验机制,防作弊能力弱于纯服务器权威。

4. 实战代码解析:从零构建一个同步AI敌人

我们以最经典、最安全的 场景一(完全服务器权威) 为例,手把手实现一个会被同步的AI敌人。假设我们有一个 ABP_Enemy 类继承自 Character

4.1 第一步:设置Actor与组件复制

首先,确保你的AI Pawn能正确地在网络上存在和同步。

ABP_Enemy 的头文件(.h)中:

UCLASS()
class AABP_Enemy : public ACharacter
{
    GENERATED_BODY()

public:
    AABP_Enemy();

protected:
    virtual void BeginPlay() override;

    // 声明一个服务器权威的移动目标RPC
    UFUNCTION(Server, Reliable, WithValidation)
    void Server_MoveToLocation(const FVector& Location);
    bool Server_MoveToLocation_Validate(const FVector& Location);
    void Server_MoveToLocation_Implementation(const FVector& Location);

    // 用于测试的按键绑定(仅服务器或拥有客户端输入有效)
    void TestMoveCommand();
};

ABP_Enemy 的源文件(.cpp)中,构造函数里进行关键设置:

AABP_Enemy::AABP_Enemy()
{
    // 1. 将此Actor设置为在网络中复制。这是最重要的开关。
    bReplicates = true;
    // 2. 设置移动组件的复制。这确保了移动更新(位置、旋转、速度)会从服务器复制到客户端。
    GetCharacterMovement()->SetIsReplicated(true);
    // 3. (可选但推荐)设置一个较低的NetUpdateFrequency,因为AI不需要像玩家那样高频更新。
    NetUpdateFrequency = 5.0f; // 每秒更新5次
    MinNetUpdateFrequency = 2.0f;
}

注意 bReplicates=true 是让这个Actor存在于所有客户端的前提。 GetCharacterMovement()->SetIsReplicated(true) 是让移动同步生效的关键。很多新手只设了前者,结果发现AI在客户端是“太空步”(动画在播,位置不动),就是因为移动没同步。

4.2 第二步:创建并配置AIController

创建一个 AAIC_Enemy 类继承自 AAIController

AAIC_Enemy 的构造函数中:

AAIC_Enemy::AAIC_Enemy()
{
    // AIController默认bReplicates = false,且通常我们不需要它复制。
    // 因为它只存在于服务器,客户端不需要它的状态。
    bReplicates = false; // 保持false即可

    // 设置感知组件等AI模块...
}

关键理解 :这里 bReplicates=false 是故意的。我们 希望AIController本身被复制到客户端。客户端不需要它的逻辑实例,只需要看到它控制的结果(Pawn的移动)。

4.3 第三步:在服务器上生成并控制AI

游戏开始时(例如在GameMode中),在服务器上生成AI并为其分配AIController。

// 在GameMode或某个管理类中
void AMyGameMode::BeginPlay()
{
    Super::BeginPlay();

    // 确保只在服务器端生成AI
    if (HasAuthority())
    {
        FActorSpawnParameters SpawnParams;
        SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;

        // 在随机位置生成一个敌人
        FVector SpawnLocation = ...; // 你的生成逻辑
        AABP_Enemy* NewEnemy = GetWorld()->SpawnActor<AABP_Enemy>(EnemyClass, SpawnLocation, FRotator::ZeroRotator, SpawnParams);

        if (NewEnemy)
        {
            // 为这个敌人创建一个AIController
            AAIC_Enemy* EnemyAIController = GetWorld()->SpawnActor<AAIC_Enemy>(AIControllerClass);
            if (EnemyAIController)
            {
                // 关键!让AIController接管(Possess)这个敌人Pawn。
                // 这行代码只在服务器执行,客户端不会执行,因为AIController只在服务器存在。
                EnemyAIController->Possess(NewEnemy);
            }
        }
    }
}

4.4 第四步:实现移动指令与RPC

现在,我们需要一个机制来让AI移动。假设我们通过一个按键来测试。

ABP_Enemy::BeginPlay 中绑定输入(仅用于测试):

void AABP_Enemy::BeginPlay()
{
    Super::BeginPlay();
    
    // 只有被玩家控制的Pawn(或服务器)才能响应按键输入。
    // 这里我们简单判断是否有Authority(服务器),或者是否被本地玩家控制。
    // 实际项目中,移动指令可能来自AI的行为树,而不是按键。
    if (IsLocallyControlled() || HasAuthority())
    {
        // 绑定一个测试按键,比如'M'
        if (APlayerController* PC = GetWorld()->GetFirstPlayerController())
        {
            PC->InputComponent->BindAction("TestMove", IE_Pressed, this, &AABP_Enemy::TestMoveCommand);
        }
    }
}

void AABP_Enemy::TestMoveCommand()
{
    // 生成一个随机目标点
    FVector RandomDestination = GetActorLocation() + FVector(FMath::RandRange(-500, 500), FMath::RandRange(-500, 500), 0);
    
    // 调用Server RPC,将移动请求发送到服务器
    Server_MoveToLocation(RandomDestination);
}

实现Server RPC:

// _Validate函数用于简单的防作弊验证(可选但推荐)
bool AABP_Enemy::Server_MoveToLocation_Validate(const FVector& Location)
{
    // 例如:检查目标点是否在合理范围内(防止客户端传一个超远坐标)
    return (GetActorLocation() - Location).SizeSquared() < 1000000.0f; // 例如1000米内
}

void AABP_Enemy::Server_MoveToLocation_Implementation(const FVector& Location)
{
    // 这个函数只在服务器上执行!
    // 获取控制这个Pawn的AIController
    if (AAIController* AIController = Cast<AAIController>(GetController()))
    {
        // 服务器权威地执行移动指令
        AIController->MoveToLocation(Location);
        
        // 如果需要,可以在这里广播一个NetMulticast RPC,让所有客户端播放一个“开始移动”的特效或声音。
        // Multicast_PlayMoveEffect();
    }
}

流程梳理

  1. 玩家在客户端按M键,触发 TestMoveCommand
  2. TestMoveCommand 调用 Server_MoveToLocation(RandomDestination) 。这是一个Server RPC。
  3. UE4网络层将这个函数调用和参数 RandomDestination 打包,发送给服务器。
  4. 服务器收到后,执行 Server_MoveToLocation_Implementation
  5. 服务器获取到该敌人Pawn的AIController(它只在服务器存在),并调用 MoveToLocation
  6. 服务器的移动组件开始寻路并移动Pawn。
  7. 由于Pawn的 bReplicates=true 且移动组件设置了复制,Pawn的位置变化会自动同步给所有客户端。
  8. 所有客户端上的该敌人Pawn更新位置,玩家就看到敌人移动了。

5. 避坑指南与高频面试问题解析

理论结合实践后,我们来直面那些最让人头疼的问题和面试官最爱挖的坑。

5.1 坑一:客户端调用MoveToLocation没反应(论坛问题重现)

问题 :就像开头论坛帖子说的,在客户端生成的AIController上调用 MoveToLocation ,AI不动。 根因

  1. 导航网格缺失 :客户端的关卡里可能根本没有生成导航网格(NavMesh)。导航是服务器端的行为,客户端默认不关心。你需要确保客户端也有导航数据。在UE编辑器中,检查导航网格边界体积(Nav Mesh Bounds Volume)是否覆盖了区域,并确保在项目设置中勾选了“Allow Client Side Navigation”。但即使勾选,在打包后客户端也可能需要手动加载导航数据,这很复杂。
  2. AIController的归属 :即使客户端有导航,你手动在客户端生成的AIController,它控制的Pawn可能是一个“副本”,而不是服务器权威的那个Pawn。你移动了这个“副本”,但服务器的权威状态没变,下一秒就被同步覆盖了。 解决方案 99%的情况,你不应该这样做。 回归到服务器权威模式。如果必须是客户端本地特效AI,确保:
    • 项目设置中开启“Allow Client Side Navigation”。
    • 在客户端关卡开始时,手动调用 FNavigationSystem::Create<UNavigationSystemV1>(GetWorld()) 来创建导航系统,并强制构建导航网格(这有性能开销)。
    • 这个AI Pawn的 bReplicates 必须为 false ,避免与服务器Pawn冲突。

5.2 坑二:RPC没执行,调试发现根本没触发

问题 :打了断点,发现Client RPC或Server RPC的实现函数( _Implementation )没有被调用。 排查清单

  1. UFUNCTION宏检查 :是否漏写了 Server Client Reliable 等关键字?宏是否拼写正确?
  2. 执行权限检查
    • Server RPC必须从客户端调用。在服务器上直接调用 ServerXXX() 函数,它只会本地执行,不会走网络。用 HasAuthority() 判断。
    • Client RPC必须从服务器调用,并且 该Actor必须有一个网络拥有者(Net Owner) 。这是最常被忽略的!一个由服务器拥有的AIController,调用 ClientRPC() 是无效的,因为找不到对应的客户端。你需要通过PlayerController或玩家Pawn来调用。
  3. 连接性检查 :确保网络连接已经建立( GetNetMode() != NM_Standalone ),并且Actor的 Role 正确(服务器上 ROLE_Authority ,客户端上 ROLE_SimulatedProxy ROLE_AutonomousProxy )。
  4. 复制设置检查 :调用RPC的Actor,其类必须被注册为可复制的(在 GetLifetimeReplicatedProps 中有属性复制,或者本身是 bReplicates=true 的Actor)。一个纯本地(非复制)的Actor不能发送RPC。

5.3 坑三:移动同步延迟大,AI在客户端“瞬移”或“抖动”

问题 :服务器AI移动平滑,但客户端看到的AI一卡一卡的。 原因与优化

  1. 网络更新频率过低 :检查AI Pawn的 NetUpdateFrequency 。默认值可能较低。适当提高(如从2调到5-10),但注意带宽和性能。
  2. 移动组件压缩 CharacterMovementComponent 使用 ReplicatedMovement 结构体同步,它会对位置、旋转、速度进行量化压缩以减少带宽。在 CharacterMovementComponent 细节面板中,可以调整位置和旋转的复制精度,精度越高带宽消耗越大。
  3. 考虑插值(Interpolation) :客户端收到新的位置后,不是直接“跳”过去,而是平滑地移动过去。UE的移动同步本身带有插值。你可以调整AI Pawn的 NetUpdateFrequency MinNetUpdateFrequency 来平衡及时性与平滑性。也可以自定义 ReplicatedMovement 的插值逻辑,但这属于高级话题。
  4. 服务器帧率与移动计算 :确保服务器有稳定的帧率。如果服务器卡顿,移动计算慢,同步出来的位置自然不连贯。

5.4 面试高频问题集锦与回答思路

Q1:AIController需要设置 bReplicates = true 吗?为什么? A1 :绝大多数情况下不需要。AIController是纯逻辑实体,其状态(如当前目标、行为树状态)如果不需要客户端知晓,就不应复制。客户端只需要看到它控制的结果(Pawn的移动和动画)。复制AIController会浪费带宽,并可能暴露不必要的逻辑给客户端,增加安全风险。只有在极少数需要客户端知晓AI决策状态(如显示AI意图给玩家)时,才考虑有选择地复制部分属性。

Q2:如何在服务器上让AI移动,并在所有客户端播放移动开始的音效? A2 :这是一个经典的RPC组合应用。

  1. 在服务器AIController的 MoveToLocation 调用之后, 在AI Pawn上 调用一个 NetMulticast RPC,例如 Multicast_PlayMoveSound()
  2. 为什么在Pawn上?因为Pawn在所有客户端都存在( bReplicates=true ),是执行播放音效这类表现逻辑的合适载体。
  3. Multicast_PlayMoveSound_Implementation 里,编写播放音效的代码。由于是NetMulticast,它会在服务器和所有客户端执行。

Q3:如果AI的移动需要非常高的响应速度(如格斗游戏的AI),有什么架构建议? A3 :这需要权衡一致性和响应性。

  • 首选 :依然是服务器权威。但可以优化网络传输,使用UDP(Unreliable)同步非关键移动状态,提高频率。同时,服务器AI的决策逻辑要足够高效。
  • 高阶方案 :采用“服务器决策-客户端执行”的混合模式(场景四)。服务器只发送高级指令(“攻击玩家A”),客户端AI根据指令进行本地寻路和移动。服务器通过关键帧(如每0.5秒)同步一次权威位置进行校验和修正。这需要设计一套复杂的指令集和状态同步协议,开发难度大,且抗作弊能力减弱。
  • 强调 :向面试官说明,没有银弹,需要根据游戏类型、AI复杂度、安全要求来具体选择。对于大多数游戏,服务器权威是更稳妥的选择。

Q4: MoveToLocation 是一个RPC吗?它的网络行为是怎样的? A4 MoveToLocation 不是 一个RPC。它是 AAIController 的一个本地函数。它的网络行为取决于调用它的AIController在哪里。

  • 如果它在 服务器 的AIController上被调用,那么移动计算在服务器进行,移动结果通过Pawn的位置属性同步到客户端。
  • 如果它在 客户端 的AIController上被调用,那么它只尝试进行客户端本地的导航和移动,这个移动不会被同步到服务器,也通常不被允许(除非是纯客户端特效AI)。
  • 所以,让AI移动的核心,是 确保 MoveToLocation 在服务器上有权限的AIController上被调用 。我们通常通过一个从客户端发起的Server RPC来“请求”服务器执行这个调用。

6. 调试技巧与性能考量

理论、实践、避坑都讲了,最后分享一些让开发过程更顺畅的“软技能”。

6.1 网络调试可视化

UE4内置了强大的网络调试工具,一定要善用。

  • stat net :在游戏运行时控制台输入,查看网络流量、更新频率、RPC调用次数等核心数据。关注 In/Out Bunch In/Out RPC
  • showdebug ai :显示AI的当前状态、行为树执行路径、感知刺激等,对于调试AI逻辑是否在正确端执行至关重要。
  • visualize replication :在编辑器偏好设置中开启,或在控制台输入相关命令,可以高亮显示正在被复制的Actor和属性,一眼看出哪个Actor没被复制。
  • Network Profiler :通过 ~ 打开控制台,输入 NetProfile ,可以启动一个更详细的网络性能分析器,记录和分析每一帧的网络活动。

6.2 性能优化点

当你的游戏里有上百个AI时,网络同步会成为性能瓶颈。

  1. 降低更新频率 :不是所有AI都需要高频更新。远处的、非战斗状态的AI,可以将其 NetUpdateFrequency NetPriority 设低。
  2. 距离相关性更新 :实现自定义的 IsNetRelevantFor 函数,根据观察者(玩家)与AI的距离来决定是否复制以及复制频率。UE本身有距离衰减,但你可以做得更精细。
  3. 属性复制优化 :只复制必要的属性。如果一个属性不常变化,不要用 Replicated 标记,改用RPC在变化时通知。
  4. AI逻辑的服务器负载 :复杂的AI行为树、环境查询(EQS)会消耗大量CPU。考虑使用异步查询、将AI逻辑分散到多帧执行、或者对非活跃AI使用简化的“休眠”逻辑。

6.3 一个完整的检查清单

当你遇到AI网络同步问题时,按这个清单从上到下排查:

  1. [ ] AI Pawn的 bReplicates 是否设置为 true
  2. [ ] AI Pawn的移动组件是否调用了 SetIsReplicated(true)
  3. [ ] AIController是否在服务器上生成并成功 Possess 了AI Pawn?(检查服务器日志)
  4. [ ] 移动指令(如 MoveToLocation )是否确定在服务器端被执行?(在 Server_MoveToLocation_Implementation 中打日志或断点)
  5. [ ] 客户端是否能收到AI Pawn的位置更新?(使用 visualize replication 查看)
  6. [ ] 如果用了RPC,RPC的宏(Server/Client/Reliable)是否正确?调用端和执行端是否符合规则?
  7. [ ] 项目设置中,网络相关选项(如“Enable Actor Replication”)是否开启?

把这些点吃透,你在UE4网络面试中关于AIController和RPC的部分,就能从“被动回答”变为“主动输出”,向面试官展示你不仅知道是什么,更知道为什么,以及在实际项目中如何权衡和落地。这正是一个资深开发者与初级工程师的核心区别所在。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值