当前位置: 首页 > article >正文

UE5Actor模块源码深度剖析:从核心架构到实践应用

UE5 Actor模块源码深度剖析:从核心架构到实践应用

a. UE5 Actor模块架构概述

在UE5引擎中,Actor扮演着至关重要的角色,它是整个游戏世界中各类可交互对象的基础抽象。从本质上来说,所有能够被放置到关卡中的对象都属于Actor的范畴,像摄像机、静态网格体以及玩家起始位置等,这些都是游戏场景构建和交互的关键元素。

Actor具备强大的三维变换能力,支持平移、旋转和缩放操作。这使得开发者可以根据游戏设计的需求,灵活地调整Actor在游戏世界中的位置、朝向和大小。而且,借助游戏逻辑代码,无论是使用C++还是蓝图,都能够方便地创建(生成)或销毁Actor,为游戏的动态性和交互性提供了有力支持。在C++层面,AActor是所有Actor的基类,它为派生类提供了基础的功能和接口。

从模块整体架构设计来看,Actor模块与UE5引擎的其他核心模块紧密协作,共同构建起一个完整的游戏世界。Actor模块的架构设计遵循了高内聚、低耦合的原则,使得各个部分之间既相互独立又能协同工作。

接下来从源码层次深入探讨Actor与World、Level的关系。在UE5中,World代表着整个游戏世界,它是一个包含了所有关卡和Actor的容器。而Level则是World中的一个具体关卡,每个Level可以包含多个Actor。以下是一段简单的源码片段,展示了Actor在World中的存在形式:

// 在UWorld类中,有一个TArray用于存储所有的Actorclass UWorld : public UObject
{// ...TArray<AActor*> Actors;// ...
};

从这段代码可以看出,UWorld类中维护了一个存储AActor指针的数组,这意味着World可以管理和操作其中的所有Actor。而Level则是World中的一个子集,它包含了一部分特定的Actor,用于构建一个具体的游戏场景。

Actor与Level之间的关系也十分紧密。当一个Actor被创建并放置到关卡中时,它实际上是被添加到了对应的Level中。以下是一个简单的示例,展示了如何在Level中创建一个Actor:

// 在某个Level类中创建一个Actorvoid UMyLevel::CreateActorInLevel()
{FActorSpawnParameters SpawnParams;AActor* NewActor = GetWorld()->SpawnActor<AActor>(MyActorClass, SpawnLocation, SpawnRotation, SpawnParams);if (NewActor){// 将Actor添加到当前Level中AddActorToLevel(NewActor);}
}

通过以上的分析可以看出,Actor在UE5引擎中处于核心地位,它与World、Level相互协作,共同构建起了一个丰富多彩的游戏世界。开发者可以通过对Actor模块的深入理解和灵活运用,实现各种复杂的游戏功能和交互效果。

b. Actor核心类源码解密

i. AActor类继承体系解析

在UE5中,理解AActor类的继承体系是深入掌握Actor模块的基础。AActor类的继承链路起始于UObject,这是UE5中所有对象的基类,它提供了对象的基本属性和功能,如反射、序列化等。

从UObject到AActor的继承链路如下:

UObject

└── AActor

UObject类是整个UE5对象系统的基石,它定义了对象的基本生命周期管理、属性反射等功能。而AActor作为UObject的派生类,继承了这些基本功能,并在此基础上进行了扩展,以满足游戏对象的需求。

下面结合源码说明UCLASS宏展开机制。UCLASS宏是UE5中用于定义类的重要工具,它为类提供了元数据信息,使得UE5能够对类进行反射和序列化。例如:

UCLASS()class MYPROJECT_API AActorDerived : public AActor
{GENERATED_BODY()public:
// 类的成员函数和属性};

当编译器遇到UCLASS宏时,它会展开一系列的代码,这些代码包含了类的元数据信息,如类名、父类、属性等。这些元数据信息被存储在UE5的反射系统中,使得引擎能够在运行时动态地访问和操作类的成员。

接下来讲解GENERATED_BODY()的代码生成原理。GENERATED_BODY()是一个宏,它会在编译时生成一系列的代码,这些代码主要用于实现类的反射和序列化功能。具体来说,它会生成类的构造函数、属性访问函数、序列化函数等。以下是一个简化的GENERATED_BODY()展开示例:


#define GENERATED_BODY()static UClass* StaticClass();virtual UClass* GetClass() const override;// 其他生成的代码...
// 展开后的代码示例static UClass* AActorDerived::StaticClass()
{static UClass* Class = nullptr;if (!Class){// 初始化类的元数据Class = ...;}return Class;
}UClass* AActorDerived::GetClass() const
{return StaticClass();
}

通过这种方式,GENERATED_BODY()确保了类的反射和序列化功能的正确实现。

下面是AActor类继承体系的结构图:

类继承关系表

基类派生类1派生类2
UObject
UObjectAActor
UObjectAActorAActorDerived

Actor组件存储结构

在UE5中,Actor可以包含多个组件,这些组件通过TArray<UActorComponent*>组件容器进行存储。TArray是UE5中常用的动态数组容器,它提供了高效的元素存储和访问功能。以下是TArray<UActorComponent*>的源码片段:

template<class T>class TArray
{// 数组的元素存储T* Data;// 数组的元素数量int32 Num;// 数组的容量int32 Capacity;// 其他成员函数...
};// 在AActor类中使用TArray存储组件class AActor : public UObject
{// ...TArray<UActorComponent*> Components;// ...};

通过TArray<UActorComponent*>,Actor可以动态地添加、删除和访问组件。组件的动态加载机制使得Actor能够在运行时根据需要加载和卸载组件,提高了游戏的灵活性和性能。

SceneComponent是一种特殊的组件,它在Actor的组件体系中扮演着重要的角色。SceneComponent具有树状组织原理,即一个SceneComponent可以有多个子组件,这些子组件的位置和变换相对于父组件进行定义。以下是SceneComponent的树状组织示例:

组件层级结构表

根组件左子组件右子组件
RootComponentChildComponent1ChildComponent2

在这个示例中,RootComponent是根组件,ChildComponent1和ChildComponent2是它的子组件。子组件的位置和变换相对于RootComponent进行计算。

CreateDefaultSubobject是一个重要的函数,用于在Actor的构造函数中创建默认的子组件。以下是CreateDefaultSubobject的实现逻辑:

template<class T

相关文章:

UE5Actor模块源码深度剖析:从核心架构到实践应用

UE5 Actor模块源码深度剖析:从核心架构到实践应用 a. UE5 Actor模块架构概述 在UE5引擎中,Actor扮演着至关重要的角色,它是整个游戏世界中各类可交互对象的基础抽象。从本质上来说,所有能够被放置到关卡中的对象都属于Actor的范畴,像摄像机、静态网格体以及玩家起始位置…...

【3.软件工程】3.6 W开发模型

W模型全解析&#xff1a;开发与测试并行的质量保障框架 ⚡ 一、W模型核心流程图 #mermaid-svg-YfU8WQvqa6iDUKz3 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-YfU8WQvqa6iDUKz3 .error-icon{fill:#552222;}#merm…...

基于大模型的主动脉瓣病变预测及治疗方案研究报告

目录 一、引言 1.1 研究背景 1.2 研究目的 1.3 研究意义 二、大模型预测主动脉瓣病变原理 2.1 大模型介绍 2.2 数据收集与处理 2.3 模型训练与优化 三、术前预测与评估 3.1 主动脉瓣病变类型及程度预测 3.2 患者整体状况评估 3.3 手术风险预测 四、术中应用与监测…...

CSRF跨站请求伪造——入门篇【DVWA靶场low级别writeup】

CSRF跨站请求伪造——入门篇 0. 前言1. 什么是CSRF2. 一次完整的CSRF攻击 0. 前言 本文将带你实现一次完整的CSRF攻击&#xff0c;内容较为基础。需要你掌握的基础知识有&#xff1a; 了解cookie&#xff1b;已经安装了DVWA的靶场环境&#xff08;本地的或云的&#xff09;&am…...

拦截、限流,针对场景详细信息(一)

以下是一个基于Java Spring Boot Redis 的完整限流实现案例&#xff0c;针对同一接口前缀&#xff08;如 /one/ &#xff09;的IP访问频率控制&#xff1a; 场景&#xff1a;用户不用登录即可访问接口&#xff0c;网站会有被攻击的风险 URL&#xff1a;one/two/three one/…...

Qt基础:主界面窗口类QMainWindow

QMainWindow 1. QMainWindow1.1 菜单栏添加菜单项菜单项信号槽 1.2 工具栏添加工具按钮工具栏的属性设置 1.3 状态栏1.4 停靠窗口&#xff08;Dock widget&#xff09; 1. QMainWindow QMainWindow是标准基础窗口中结构最复杂的窗口, 其组成如下: 提供了菜单栏, 工具栏, 状态…...

第十四届蓝桥杯大赛软件赛省赛Python 研究生组:4.互质数的个数

题目1 互质数的个数 给定 a,b&#xff0c;求 1≤x<ab 中有多少个 x 与 ab 互质。 由于答案可能很大&#xff0c;你只需要输出答案对 998244353 取模的结果。 输入格式 输入一行包含两个整数分别表示 a,b&#xff0c;用一个空格分隔。 输出格式 输出一行包含一个整数表…...

32f4,usart2fifo,2025

usart2fifo.h #ifndef __USART2FIFO_H #define __USART2FIFO_H#include "stdio.h" #include "stm32f4xx_conf.h" #include "sys.h" #include "fifo_usart2.h"//extern u8 RXD2_TimeOut;//超时检测//extern u8 Timer6_1ms_flag;exte…...

激光模拟单粒子效应试验如何验证CANFD芯片的辐照阈值?

在现代航天电子系统中&#xff0c;CANFD&#xff08;Controller Area Network with Flexible Data-rate&#xff09;芯片作为关键的通信接口元件&#xff0c;其可靠性与抗辐射性能直接关系到整个系统的稳定运行。由于宇宙空间中存在的高能粒子辐射&#xff0c;芯片可能遭受单粒…...

从零构建大语言模型全栈开发指南:第五部分:行业应用与前沿探索-5.2.1模型偏见与安全对齐(Red Teaming实践)

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 大语言模型全栈开发指南:伦理与未来趋势 - 第五部分:行业应用与前沿探索5.2.1 模型偏见与安全对齐(Red Teaming实践)一、模型偏见的来源与影响1. 偏见的定义与分类2. 偏见的实际影响案例二、安全对齐…...

Docker安装开源项目x-ui详细图文教程

本章教程,主要介绍如何使用Docker部署开源项目x-ui 详细教程。 一、拉取镜像 docker pull enwaiax/x-ui:latest二、运行容器 mkdir x-ui && cd x-ui docker run -itd --network=host \-v $PWD<...

检索增强生成(RAG) 优化策略

检索增强生成(RAG) 优化策略篇 一、RAG基础功能篇 1.1 RAG 工作流程 二、RAG 各模块有哪些优化策略&#xff1f;三、RAG 架构优化有哪些优化策略&#xff1f; 3.1 如何利用 知识图谱&#xff08;KG&#xff09;进行上下文增强&#xff1f; 3.1.1 典型RAG架构中&#xff0c;向…...

Educational Codeforces Round 172 (Rated for Div. 2)

AB略 C 答案没有单调性&#xff0c;无法用二分答案写。b比a多的得分s1*0s2*1.......sn*(n-1)&#xff0c;s代表这一段中b比a多的数量。这里s的处理可以想到用前缀和来&#xff0c;于是得到(s1-0)*0(s2-s1)*1(s3-s2)*2......(sn-sn-1)*(n-1)-s1-s2-s3.....sn*(n-1)&#xff0c…...

前端:v-html和v-text在使用上的区别

v-html 和 v-text 在 Vue 中的核心区别如下&#xff1a; 一、解析机制 ‌v-text‌ 将数据作为纯文本渲染&#xff0c;‌不解析 HTML 标签‌。 例如数据 <strong>Hello</strong> 会直接输出为字符串 <strong>Hello</strong>‌。‌v-html‌ 将数据解析为…...

【面试篇】Kafka

一、基础概念类 问题&#xff1a;请简述 Kafka 是什么&#xff0c;以及它的主要应用场景有哪些&#xff1f; 答案&#xff1a;Kafka 是一个分布式流处理平台&#xff0c;它以高吞吐量、可持久化、可水平扩展等特性而闻名。其主要应用场景包括&#xff1a; 日志收集&#xff1a…...

零基础玩转树莓派5!从系统安装到使用VNC远程控制树莓派桌面实战

文章目录 前言1.什么是Appsmith2.Docker部署3.Appsmith简单使用4.安装cpolar内网穿透5. 配置公网地址6. 配置固定公网地址总结 前言 你是否曾因公司内部工具的开发周期长、成本高昂而头疼不已&#xff1f;或是突然灵感爆棚想给团队来点新玩意儿&#xff0c;却苦于没有专业的编…...

SAP CEO引领云端与AI转型

在现任首席执行官克里斯蒂安克莱因&#xff08;Christian Klein&#xff09;的领导下&#xff0c;德国软件巨头 SAP 正在经历一场深刻的数字化转型&#xff0c;重点是向云计算和人工智能方向发展。他提出的战略核心是“RISE with SAP”计划&#xff0c;旨在帮助客户从传统本地部…...

【MyBatis】深入解析 MyBatis:关于注解和 XML 的 MyBatis 开发方案下字段名不一致的的查询映射解决方案

注解查询映射 我们再来调用下面的 selectAll() 这个接口&#xff0c;执行的 SQL 是 select* from user_info&#xff0c;表示全列查询&#xff1a; 运行测试类对应方法&#xff0c;在日志中可以看到&#xff0c;字段名一致&#xff0c;Mybatis 就成功从数据库对应的字段中拿到…...

图像退化对目标检测的影响 !!

文章目录 引言 1、理解图像退化 2、目标检测中的挑战 3、应对退化的自适应方法 4、新兴技术与研究方向 5、未来展望 6、代码 7、结论 引言 在计算机视觉领域&#xff0c;目标检测是一项关键任务&#xff0c;它使计算机能够识别和定位数字图像中的物体。这项技术支撑着从自动驾…...

《AI大模型应知应会100篇》第57篇:LlamaIndex使用指南:构建高效知识库

第57篇&#xff1a;LlamaIndex使用指南&#xff1a;构建高效知识库 摘要 在大语言模型&#xff08;LLM&#xff09;驱动的智能应用中&#xff0c;如何高效地管理和利用海量知识数据是开发者面临的核心挑战之一。LlamaIndex&#xff08;原 GPT Index&#xff09; 是一个专为构建…...

目标检测中COCO评估指标中每个指标的具体含义说明:AP、AR

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…...

鸿蒙应用元服务开发-Account Kit概述

Account Kit&#xff08;华为账号服务&#xff09;提供简单、快速、安全的登录功能&#xff0c;让用户快捷地使用华为账号登录元服务。用户授权后&#xff0c;Account Kit可提供头像、手机号码等信息&#xff0c;帮助元服务更了解用户。Account Kit提供的SampleCode示例工程体现…...

如何利用ATECLOUD测试平台的芯片测试解决方案实现4644芯片的测试?

作为多通道 DC-DC 电源管理芯片的代表产品&#xff0c;4644 凭借 95% 以上的转换效率、1% 的输出精度及多重保护机制&#xff0c;广泛应用于航天航空&#xff08;卫星电源系统&#xff09;、医疗设备&#xff08;MRI 梯度功放&#xff09;、工业控制&#xff08;伺服驱动单元&a…...

SpringBoot集成OAuth2.0

文章目录 OAuth 2.0 介绍概念与传统认证方式的对比常见应用场景 OAuth 2.0 原理核心角色授权流程 Spring Boot 集成 OAuth 2.01. 添加依赖2. 配置 OAuth 2.0 客户端3. 配置 Spring Security4. 创建控制器5. 主应用类 代码解释 OAuth 2.0 介绍 概念 OAuth 2.0 是一个开放标准的…...

《继电器:机械骑士的电磁战甲》

点击下面图片带您领略全新的嵌入式学习路线 &#x1f525;爆款热榜 88万阅读 1.6万收藏 第一章&#xff1a;千年契约的青铜誓言 在电气王国的熔炉深处&#xff0c;电磁铁与簧片的盟约已镌刻千年。电磁铁身披螺旋铜线编织的斗篷&#xff0c;其胸膛中沉睡着一道可召唤磁力的古…...

c++中cin.ignore()的作用

在 C 中&#xff0c;cin.ignore() 是用于忽略&#xff08;丢弃&#xff09;输入流中的字符的函数&#xff0c;通常用来清除输入缓冲区中的残留内容&#xff08;如换行符、多余输入等&#xff09;&#xff0c;以避免影响后续的输入操作。 基本用法 cin.ignore(n, delim);n&…...

python如何获取html中附件链接,并下载保存附件

在Python中&#xff0c;要获取HTML中的附件链接并下载保存附件&#xff0c;你通常需要执行以下步骤&#xff1a; 解析HTML内容&#xff1a;使用像BeautifulSoup这样的库来解析HTML并找到包含附件链接的标签&#xff08;例如<a>标签&#xff0c;它们通常有一个href属性指向…...

【计算机相关学习】R语言

在Python统治数据科学的时代&#xff0c;我意外推开了R语言的大门。这个诞生于统计学家之手的编程语言&#xff0c;像一把精巧的手术刀&#xff0c;改变了我对数据处理的认知边界。 ​​语法里的统计基因​​令人惊艳。当我第一次用<-符号完成变量赋值时&#xff0c;这个源…...

JavaScript DOM 节点操作

目录 一、DOM 节点 节点类型&#xff08;Node Types&#xff09; 二、查找节点 1.查找父节点 1. parentNode 2. parentElement 2.查找子节点 1. childNodes 2. children 3. firstChild / lastChild 4. firstElementChild / lastElementChild 3.查找兄弟节点 1. pre…...

快速求平方根

1. 前置知识 建议首先阅读我的另外一篇文章《雷神之锤 III 竞技场》快速求平方根倒数的计算探究》。建议大家自己看过《雷神之锤 III 竞技场》快速求平方根倒数的计算探究》学会快速求平方根倒数算法后&#xff0c;不看我这篇文章&#xff0c;自己推导一篇快速求平方根的算法&…...