美文网首页
24 UE5 AActor简介

24 UE5 AActor简介

作者: 游戏开发程序员 | 来源:发表于2024-04-27 15:07 被阅读0次

    Actor介绍和作用

    • Actor类是游戏中一切实体Actor的基类(继承UObject)。
    • 代表着游戏中的一个实体或物体。
    • 是可见的角色、道具、敌人、NPC、触发器等。
    • 可以在游戏世界中被放置、创建和操作。
    • 需要挂载组件的时候,你才应该继承自Actor类。
    • 运行中通过网络来复制属性和函数调用
    image.png

    Actor的行为表现

    • 在游戏世界中的位置(位置矢量)和变换(旋转和缩放)
    • 组件系统:Actor由一个或多个组件组成,每个组件代表Actor的一个功能或特性。
    • 组件可以附加和管理Actor的行为、外观和交互。
    • 通过脚本或视觉蓝图来定义其行为和交互。
    • 控制Actor的移动、动画、碰撞、触发事件等,能够响应玩家的输入、与其他Actor进行交互。
    • 碰撞和触发器:设置碰撞体积和形状,导致伤害、触发事件或改变游戏状态。

    Actor的常用函数

    • BeginPlay():第一次被放置到场景中并准备开始游戏时被调用。
    • Tick() :它在每一帧中被调用,用于更新 Actor 的逻辑和状态。
    • OnActorBeginOverlap() 和 OnActorEndOverlap():碰撞事件的回调函数
    • Destroy() :用于销毁当前的 Actor。
    • SetActorLocation() 和 SetActorRotation():设置 Actor 的位置和旋转。
    • SetActorHiddenInGame() 可以设置 Actor 在游戏中是否隐藏。
    • GetWorld() 返回当前 Actor 所属的 World 对象。
    • GetOwner() 返回当前 Actor 的所有者 Actor。
    • GetActorScale3D() 和 SetActorScale3D() 用于获取和设置 Actor 的缩放值。

    Actor的优秀子类

    • AStaticMeshActor(内部包含UStaticMeshComponent): 呈现具有实体属性的静态网格模型。
    • ACharacter: 继承APawn, 具有角色属性和动画的角色.
    • AProjectile: 用于表示游戏中的抛射物或子弹的 Actor 子类
    • ATriggerVolume: 继承AVolume, 用于创建触发器区域的 Actor 子类
    • APlayerStart:指定玩家初始或重生位置的 Actor 子类
    • ACameraActor:(内部包含CameraComponent), 控制摄像机位置、旋转和视角。

    Actor的创建

    • 创建方式:
    • 1 从磁盘加载(Load From Disk): 用于已经在关卡中的Actor(LoadMap, 关卡流送)
    • 2 在编辑器PIE中运行: Actor从编辑器中复制而来,并非从磁盘中加载。
    • 3 代码生成: 调用 UWorld::SpawnActor(才会有World::OnActorSpawned 回调)
    • 4 延迟生成: SpawnActorDeferred 生成流程性Actor,允许在蓝图构建脚本之前进行额外设置。
    • 多种创建的Actor的销毁路径是相同的

    Actor EndPlay的全部情形:

    • 1 对Destroy显式调用。
    • 2 "在编辑器中运行(Play in Editor)"终结。
    • 3 关卡过渡(无缝行程或加载地图)。
    • 4 包含Actor的流送关卡被卸载。
    • 5 Actor的生命周期已过。
    • 6 应用程序关闭(全部Actor被销毁)。
    • Actor将被标记为 RF_PendingKill,在下个垃圾回收周期中,UE会将其从内存中解除。

    Actor的回收函数

    • UObject::BeginDestroy - 利用此机会释放内存并处理其他多线程资源。大多数Gameplay功能应在EndPlay中处理。
    • UObject::IsReadyForFinishDestroy - GC调用,以确定对象是否可以永久解除分配或延迟对象销毁。
    • UObject::FinishDestroy - 释放内部数据结构。内存释放前的最后一次调用。
    创建和组件初始化
    • 销毁和回收


      销毁和回收

    Actor的组件系统

    • Actor包含一个或多个Actor组件
    • 组件控制Actor的移动方式,渲染等行为、外观和其他属性。

    Actor的创建和配置

    • 编辑器中直接摆放
    • 通过C++代码运行时动态生成
    • 编辑器可见性 和 灵活性和可编程性 不同
    • 直接摆放 适合于静态场景布置和设计,对于位置、外观和属性相对固定。

    Actor的交互和行为

    • DECLARE_EVENT来关心Actor的事件,并进行绑定.
    • DECLARE_MULTICAST_DELEGATE 多播委托
    • DECLARE_DYNAMIC_MULTICAST 动态多播委托(支持蓝图)
    • public 的方法直接调用

    Actor的优化和性能

    • 包括减少组件数量、使用合适的碰撞设置等。
    • 对Actor的生命周期合理管理,避免资源泄漏和性能问题。
    #pragma once
    
    #include "CoreMinimal.h"
    #include "GameFramework/Actor.h"
    #include "Materials/Material.h"
    
    #include "Components/PointLightComponent.h"
    #include "Components/SphereComponent.h"
    #include "Components/StaticMeshComponent.h"
    
    #include "MyActor.generated.h"
    
    • 头文件包含注意: #include "MyActor.generated.h" 必须在最后一行
    UCLASS()
    class AMyActor : public AActor
    {
        GENERATED_BODY()
    
    public:
        // 声明事件
        DECLARE_EVENT(AMyActor, FMyCrashEvent);
        // 外部使用此函数来绑定和广播
        FMyCrashEvent& OnCrashed() { return CrashEvent; }
    
        // 事件内部封装
    private:
        FMyCrashEvent CrashEvent;
    
        // 事件回调函数
        UFUNCTION()
        void HandleCrashEvent();
        
    public: 
        AMyActor();
    
        // Called every frame
        virtual void Tick(float DeltaTime) override;
    
        UFUNCTION()
        void OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, 
            class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
    
        UFUNCTION()
        void OnOverlapEnd(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, 
            class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);
    
        /** 切换光照组件的可见性*/
        UFUNCTION()
        void ToggleLight();
    
    • 上半部分声明事件和时间的回调函数
    • 下半部分声明了tick 和 重叠的开始和结束的委托函数
        // Called when the game starts or when spawned
        virtual void BeginPlay() override
        {
            Super::BeginPlay();
            UE_LOG(LogTemp, Warning, TEXT("BeginPlay"));
        }
    
        virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override
        {
            Super::EndPlay(EndPlayReason);
            UE_LOG(LogTemp, Warning, TEXT("EndPlay"));
        }
    
        virtual void BeginDestroy() override
        {
            Super::BeginDestroy();
            UE_LOG(LogTemp, Warning, TEXT("BeginDestroy"));
        }
    
        virtual void FinishDestroy() override
        {
            Super::FinishDestroy();
            UE_LOG(LogTemp, Warning, TEXT("FinishDestroy"));
        }
    
    • Actor的主要重载函数和执行顺序
    /// <summary>
    /// Actor的成员对象
    /// </summary>
    public:
        // 点光源组件
        UPROPERTY(VisibleAnywhere, Category = "Switch Components")
        class UPointLightComponent* PointLight1;
    
        /** 点光源的光照强度 */
        UPROPERTY(VisibleAnywhere, Category = "Switch Variables")
        float DesiredIntensity;
    
        // 球体碰撞体组件
        UPROPERTY(VisibleAnywhere, Category = "Switch Components")
        class USphereComponent* Sphere1;
    
        // 静态网格体组件
        UPROPERTY(VisibleAnywhere, Category = "Switch Components")
        class UStaticMeshComponent* MeshComponent1;
    };
    
    • 本Actor的成员对象
    AMyActor::AMyActor()
    {
        PrimaryActorTick.bCanEverTick = true;
    
        // 光源强度
        DesiredIntensity = 3000.0f;
    
        // 创建点光源(create,SetVisibility,RootComponent相关)
        PointLight1 = CreateDefaultSubobject<UPointLightComponent>(TEXT("PointLight1"));
        PointLight1->Intensity = DesiredIntensity;
        PointLight1->SetVisibility(true);
    
        // 设为根组件
        SetRootComponent(PointLight1);  // RootComponent = PointLight1;
    
        // 创建静态网格体组件(先设StaticMesh,再设置材质)
        MeshComponent1 = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MeshComponent"));
        // 查询和设置网格
        static ConstructorHelpers::FObjectFinder<UStaticMesh> DefaultMeshAsset(TEXT("/Engine/BasicShapes/Sphere"));
        if (DefaultMeshAsset.Succeeded())
        {
            MeshComponent1->SetStaticMesh(DefaultMeshAsset.Object);
        }
    
        // 查询和设置材质
        static ConstructorHelpers::FObjectFinder<UMaterial> DefaultMaterialAsset(TEXT("/Engine/EngineMaterials/ScreenMaterial"));
        if (DefaultMaterialAsset.Succeeded())
        {
            UMaterial* DefaultMaterial = (UMaterial*)DefaultMaterialAsset.Object;
            MeshComponent1->SetMaterial(0, DefaultMaterial);
        }
        // 附加到根组件
        MeshComponent1->SetupAttachment(RootComponent);
        MeshComponent1->SetVisibility(true);
    
        // 创建球形碰撞体
        Sphere1 = CreateDefaultSubobject<USphereComponent>(TEXT("Sphere1"));
        Sphere1->InitSphereRadius(250.0f);
        Sphere1->SetupAttachment(RootComponent);
        Sphere1->SetVisibility(true);
    
        // 注册进入和离开重叠时的回调
        Sphere1->OnComponentBeginOverlap.AddDynamic(this, &AMyActor::OnOverlapBegin);
        Sphere1->OnComponentEndOverlap.AddDynamic(this, &AMyActor::OnOverlapEnd);
    
        // 关心碰撞事件
        OnCrashed().AddUObject(this, &AMyActor::HandleCrashEvent); // C++
        OnCrashed().AddUFunction(this, FName("HandleCrashEvent")); // todo 测试蓝图
    }
    
    • 构造函数中创建和添加组件
    • 注册碰撞的进入和离开回调
    • 注册碰撞事件的回调函数 X 2
    void AMyActor::OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor,
        class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
    {
        if (OtherActor && (OtherActor != this) && OtherComp)
        {
            ToggleLight();
        }
    
        OnCrashed().Broadcast();
    }
    
    // 碰撞处理事件
    void AMyActor::HandleCrashEvent()
    {
        UE_LOG(LogTemp, Warning, TEXT("HandleCrashEvent be Called"));
    }
    
    
    • 碰撞开始的函数执行,并广播自定义事件:碰撞处理事件

    相关文章

      网友评论

          本文标题:24 UE5 AActor简介

          本文链接:https://www.haomeiwen.com/subject/uwfexjtx.html