美文网首页
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"));
}

  • 碰撞开始的函数执行,并广播自定义事件:碰撞处理事件

相关文章

  • 允许或者禁止playerinput

    AActor::DisableInput(APlayerController* PlayerController)

  • 架构学习

    AActor 首先是继承自UObject的AActor,它代表着游戏中的种种表示,不只是游戏物体对象这种概念,而且...

  • 热更

    UCLASS()class AMyActor : public AActor { GENERATED_BODY()...

  • 程序打包

    关于UE5打包问题[https://www.bilibili.com/read/cv11679358] UE5 P...

  • character 响应 clicked 事件

    绑定AActor的OnClicked事件image.png 设置PlayerController里面的bEnabl...

  • 目录、资产命名规范

    【UE5】目录、资产命名规范[https://zhuanlan.zhihu.com/p/484119115]

  • 地理坐标转换

    关联GIS:条条道路通UE5城[https://zhuanlan.zhihu.com/p/528244402] 关...

  • 通讯

    开源篇-WebSocket搭建UE5通信桥梁[https://zhuanlan.zhihu.com/p/54621...

  • 调试

    UE4/UE5的崩溃,卡死等问题处理[https://zhuanlan.zhihu.com/p/565680732]

  • 源代码

    从零开始:编译UE5 source code[https://www.jianshu.com/p/4a6b8603...

网友评论

      本文标题:24 UE5 AActor简介

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