阿赵UE引擎C++编程学习笔记——GameMode和生命周期

  大家好,我是阿赵。
  之前在介绍HelloWorld的时候,我们很创建了一个MyGameModeBase的c++类,然后就可以在BeginPlay函数里面写打印的HelloWorld。这一篇主要是说一下,GameMode究竟是一个什么东西,然后UE里面的生命周期是怎样的。

一、 GameMode和关卡蓝图

1、C++程序的Main函数

  如果是纯粹的C++项目,按道理都是有一个Main函数作为整个项目的启动入口。UE的C++项目实际上也是有的。不过那个是引擎本身启动的时候调用的,具体的位置在Engine\Source\Runtime\Launch\Private\Launch.cpp里面的GuardedMain函数
在这里插入图片描述

  在这个主入口的函数里面,引擎会做很多事情,比如初始化引擎功能之类。
  所以,写UE的C++不能以Main函数作为我们逻辑的入口。那应该怎么办呢?

2、关卡蓝图

  用过Unity引擎的朋友,可以对比一下Unity引擎的启动方式。在Unity引擎里面的做法,一般是指定一个场景,然后在上面建一个空节点,然后挂一个继承了MonoBehaviour的脚本,通过MonoBehaviour脚本的生命周期自动运行的函数,来进入游戏实际的逻辑。
  和Unity引擎一样,UE引擎在刚开始运行的时候,也是需要指定一个默认的关卡(Level)的。当这个Level被载入并运行的时候,就可以运行这个关卡对应的代码。如果从蓝图的角度看,UE有一个叫做“关卡蓝图”的东西:
在这里插入图片描述

  打开了之后,会看见里面默认有Event BeginPlay和EventTick两个节点,然后我们就可以在里面编写逻辑。
在这里插入图片描述

  UE的每一个Level,都会有一个对应的关卡蓝图。

3、 GameMode

  GameMode的概念和关卡蓝图有点类似,它也是在游戏启动的时候会自动运行的。不过有个区别是,GameMode可以设置一个默认的,如果关卡本身不指定单独的GameMode,那么每个关卡在载入的时候,都会运行默认的同一个GameMode代码,然后每一个Level也可以单独指定属于自己的一个特殊的GameMode。
在这里插入图片描述

  这样的操作,就有点类似于在Unity引擎的关卡里面挂一个空物体再挂一个MonoBehaviour的情况,反正这个关卡载入成功后,就会自动调用这个指定的GameMode里面的代码,并且运行生命周期。
  所以,关卡蓝图和GameMode是可以同时存在的,但两者做的事情有点类似。

二、 Actor和GameModeBase

1、 Actor

  如果我们创建一个蓝图类,会看到可以让我们选择父级:
在这里插入图片描述
在这里插入图片描述

  然后最基础的父类,就是Actor,这个东西,对比Unity引擎来说,其实就是类似于GameObject,它是一个可以放置在场景里面的对象,包含着一些基础的Transform属性,还有生命周期。
  双击打开Actor的蓝图,会看到里面有EVent BeginPlay、Event ActorBeginOverlap和Event Tick三个默认的节点。这和之前的关卡蓝图有点类似,其实都是代表着这个Actor的生命周期,比如BeginPlay就是在Actor被载入的时候会运行一次。
在这里插入图片描述

  实际上创建其他蓝图类型,他们的基类都是Actor。

2、 GameModeBase

  再来创建一个游戏模式基础的蓝图看看:
在这里插入图片描述

  这里我把这个游戏模式的蓝图命名为”GameModeBaseBP”:
在这里插入图片描述

  可以发现,在之前指定游戏模式的地方,会同时出现之前用C++写的MyGameModeBase,和用蓝图创建的GameModeBaseBP。
在这里插入图片描述

  所以,这个GameModeBase,既可以用C++实现,又可以用蓝图实现。
  双击打开这个GameModeBaseBP蓝图,会看到和Actor是差不多的,也是有BeginPlay和Tick的生命周期。
在这里插入图片描述

  当然,Actor的生命周期不止这两个,还有其他,比如可以添加一个EndPlay的生命周期。
在这里插入图片描述
在这里插入图片描述

  又来对比一下Unity引擎,Unity引擎里面的生命周期,都是由MonoBehaviour而来的,所以继承MonoBehaviour的所有类都可以使用Awake、Start、Update、OnDestroy之类的生命周期。
那么UE这边,因为都是基础Actor的,所以Actor的生命周期,比如BeginPlay、Tick和EndPlay之类的,其他继承Actor的类都能使用,包括GameModeBase。

三、 生命周期说明

  如果用C++来编写GameModeBase,那么需要这样声明生命周期:
MyGameModeBase.h

#pragma once#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "MyGameModeBase.generated.h"/*** */
UCLASS()
class UECPPTEST_API AMyGameModeBase : public AGameModeBase
{GENERATED_BODY()
public:AMyGameModeBase();
public:virtual void BeginPlay();virtual void Tick(float DeltaTime);virtual void EndPlay(const EEndPlayReason::Type EndPlayReason);
};

MyGameModeBase.cpp

#include "MyGameModeBase.h"
AMyGameModeBase::AMyGameModeBase()
{PrimaryActorTick.bCanEverTick = true;
}void AMyGameModeBase::BeginPlay()
{Super::BeginPlay();UE_LOG(LogTemp, Display, TEXT("On level Start"));
}void AMyGameModeBase::Tick(float DeltaTime)
{Super::Tick(DeltaTime);UE_LOG(LogTemp, Display,TEXT("OnUpdate:%f"),DeltaTime);
}void AMyGameModeBase::EndPlay(const EEndPlayReason::Type EndPlayReason)
{	Super::EndPlay(EndPlayReason);FString str = StaticEnum<EEndPlayReason::Type>()->GetNameStringByValue((int64)EndPlayReason);UE_LOG(LogTemp, Display, TEXT("End Play:%s"), *str);
}

说明:
BeginPlay
相当于Unity的Start,在Actor对象刚开始播放时调用
Tick
相当于Unity的Update,但默认是不会调用的,需要在构造函数的时候开启:

PrimaryActorTick.bCanEverTick = true;

EndPlay
相当于Unity的OnDestroy,在Actor对象被销毁的时候调用,其中EndPlayReason是销毁的原因。
对应的枚举EEndPlayReason::Type

enum Type : int
{/** When the Actor or Component is explicitly destroyed. */Destroyed,/** When the world is being unloaded for a level transition. */LevelTransition,/** When the world is being unloaded because PIE is ending. */EndPlayInEditor,/** When the level it is a member of is streamed out. */RemovedFromWorld,/** When the application is being exited. */Quit,
};

如果要打印这个枚举,可以:

FString str = StaticEnum<EEndPlayReason::Type>()->GetNameStringByValue((int64)EndPlayReason);UE_LOG(LogTemp, Display, TEXT("End Play:%s"), *str);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/18201.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HashMap在Go与Java的底层实现与区别

在Java中 在Java中hash表的底层数据结构与扩容等已经是面试集合类问题中几乎必问的点了。网上有对源码的解析已经非常详细了我们这里还是说说其底层实现。 基础架构 public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable,…

Cesium For Unity 在Unity中无法下载的问题

Unity 下载失败&#xff0c;提供百度网盘“com.cesium.unity-1.10.0.tgz”下载链接 链接&#xff1a;https://pan.baidu.com/s/1PybXQ8EvkRofOKD6rSN66g?pwd1234 提取码&#xff1a;1234 导入方法&#xff1a; 1.打开PackageManager;Window-PackageManager 2.在PackageMan…

从机械尘埃到智能星河:探索从工业心脏到AI大脑的世纪跨越(一点个人感想)...

全文预计1400字左右&#xff0c;预计阅读需要8分钟。 近期&#xff0c;人工智能领域呈现出前所未有的活跃景象&#xff0c;各类创新成果如雨后春笋般涌现&#xff0c;不仅推动了科技的边界&#xff0c;也为全球经济注入了新的活力。 这不&#xff0c;最近报道16家国内外企业在A…

优思学院:质量工程师必备技能清单,你具备了吗?

想要了解质量工程师需要具备哪些技能和知识&#xff0c;最直接且实际的方法就是分析招聘广告中的关键词&#xff0c;这比道听途说更加有效。为此&#xff0c;优思学院搜集了大量关于质量工程师职位的招聘信息&#xff0c;并为大家进行详细分析。我们通常选择中高级职位进行分析…

嵌入式C语言指针详细解说

各位伙伴大家好,在实现操作系统的控制的时候,经常需要使用到指针,利用这次详细分析一下指针的用法。 C语言指针真正精髓的地方在于指针可以进行加减法,这一点极大的提升了程序对指针使用的灵活性,同时也带来了不小的学习负担。正是因为C语言指针可运算,才奠定了如今C语言…

「Element-UI表头添加带Icon的提示信息」

一、封装全局组件 &#x1f353; 注意&#xff1a;可以直接复制该文件 <!-- // 写一个PromptMessage的组件&#xff0c;并全局注册 --> <template><div class"tooltip"><el-tooltip effect"dark" placement"right">&l…

MySQL select for update 加锁

背景 当多人操作同一个客户下账号的时候&#xff0c;希望顺序执行&#xff0c;某个时刻只有一个人在操作&#xff1b;当然可以通过引入redis这种中间件实现&#xff0c;但考虑到并发不会很多&#xff0c;所以不想再引入别的中间件。 表结构 create table jiankunking_accoun…

基于Python flask的豆瓣电影数据分析可视化系统,功能多,LSTM算法+注意力机制实现情感分析,准确率高达85%

研究背景 随着数字化时代的到来&#xff0c;电影产业正迎来新的发展机遇和挑战。基于Python Flask的豆瓣电影数据分析可视化系统的研究背景凸显了对电影数据的深度分析和情感挖掘的需求。该系统功能丰富&#xff0c;不仅实现了多样化的数据分析功能&#xff0c;还结合了LSTM算…

CTF| 格式化字符串漏洞

格式化字符串漏洞是PWN题常见的考察点&#xff0c;仅次于栈溢出漏洞。漏洞原因&#xff1a;程序使用了格式化字符串作为参数&#xff0c;并且格式化字符串为用户可控。其中触发格式化字符串漏洞函数主要是printf、sprintf、fprintf、prin等C库中print家族的函数 0x01 格式化字符…

如何深入理解、应用及扩展 Twemproxy?no.15

Twemproxy 架构及应用 Twemproxy 是 Twitter 的一个开源架构&#xff0c;它是一个分片资源访问的代理组件。如下图所示&#xff0c;它可以封装资源池的分布及 hash 规则&#xff0c;解决后端部分节点异常后的探测和重连问题&#xff0c;让 client 访问尽可能简单&#xff0c;同…

C语言之宏详解(超级详细!)

目录 一、用宏前须知-#define相关知识 大致结构&#xff1a; 对预定义符号的补充&#xff1a; 二、用#define定义宏 什么是宏&#xff1f; #define的替换规则&#xff1a; 三、常用的宏定义 1、宏定义常量 2、定义一个宏语句 3、宏定义函数 宏与函数的对比&#xff1a; …

29【PS 作图】宫灯 夜景转换

夜景转化 1 原图 2 选中要变换的图层,然后点击“颜色查找” 再3DLUT文件中,选择moonlight.3DL,可以快速把图层变成偏夜景的颜色 结果如下: 3 选择“曲线” 把曲线 右边往上调【亮的更亮】,左边往下调【暗的更暗】 4 添加灯光 新建一个图层

HTML+CSS+JS简易计算器

HTMLCSSJS简易计算器 index.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>简易计算器</t…

AAA实验配置

一、实验目的 掌握AAA本地认证的配置方法 掌握AAA本地授权的配置方法 掌握AAA维护的方法 1.搭建实验拓扑图 2.完成基础配置&#xff1a; 3.使用ping命令测试两台设备的连通性&#xff1a; 二、配置AAA 1.打开R1&#xff1a;配置AAA方案 这两个方框内的可以改名&#xff0c…

百度页面奔跑的白熊html、css

一、相关知识-动画 1.基本使用&#xff1a;先定义再调用 2. 调用动画 用keyframes定义动画&#xff08;类似定义类选择器&#xff09; keyframes动画名称{ 0%{ width:100px&#xff1b; } 100%{ width:200px; } } 使用动画 div { width:200px; height:200px; background-…

Pytorch线性模型(Linear Model)

基本步骤 ①首先准备好数据集&#xff08;DataSet&#xff09; ②模型的选择或者设计&#xff08;Model&#xff09; ③进行训练&#xff08;Train&#xff09;大部分模型都需要训练&#xff0c;有些不需要。这一步后我们会确定不同特征的权重 ④推理&#xff08;inferring…

【Python安全攻防】【网络安全】一、常见被动信息搜集手段

一、IP查询 原理&#xff1a;通过目标URL查询目标的IP地址。 所需库&#xff1a;socket Python代码示例&#xff1a; import socketip socket.gethostbyname(www.163.com) print(ip)上述代码中&#xff0c;使用gethostbyname函数。该函数位于Python内置的socket库中&#xf…

广场舞团|基于SprinBoot+vue的广场舞团系统(源码+数据库+文档)

广场舞团系统 目录 基于SprinBootvue的广场舞团系统 一、前言 二、系统设计 三、系统功能设计 1 系统功能模块 2 后台登录模块 5.2.1管理员功能模块 5.2.2社团功能模块 5.2.3用户功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推…

Android 项目Gradle文件讲解(Groovy和Kotlin)

Android 项目Gradle文件讲解&#xff08;Groovy和Kotlin&#xff09; 前言正文一、Gradle的作用二、Gradle的种类① 工程build.gradle② 项目build.gradle③ settings.gradle④ gradle.properties⑤ gradle-wrapper.properties⑥ local.properties 三、Groovy和Kotlin的语言对比…

装饰模式:鸡腿堡

文章目录 UML类图目录结构Humburger.javaChickenBurger.javaCondiment.javaChuilli.javaLettuce.javaTest.java深度理解test怎么写 UML类图 目录结构 我们从指向最多的开始写 Humburger.java package zsms;public abstract class Humburger {protected String name;public S…