本文章由cartzhang编写,转载请注明出处。 所有权利保留。

文章链接:http://blog.csdn.net/cartzhang/article/details/73189272

作者:cartzhang

一、 UE4 C++ 代码自动生成流程

1. 界面点击生成C++类

图1

先调用 SMenuEntryBlock::OnClicked ,然后调用UI_COMMAND(AddCodeToProject) —-> FMainFrameActionCallbacks::AddCodeToProject(),—-> OpenAddCodeToProjectDialog来打开基类选择界面。

2. 点击Create Class按钮

图2

OnFinished(this, &SNewClassDialog::FinishClicked)

调用函数SNewClassDialog::FinishClicked()—>AddCodeToProject —>GameProjectUtils::AddCodeToProject_Internal(核心都在这里实现)

3. 头文件生成

拼接文件路径信息,GameProjectUtils::GenerateClassHeaderFile来生成头文件的内容。

FinalOutput = "

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameFramework/Pawn.h"
#include "MyPawn.generated.h"

UCLASS()
class HOWTO_VTE_API AMyPawn : public APawn
{
    GENERATED_BODY()

public:
    // Sets default values for this pawn's properties
    AMyPawn();

protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public:
    // Called every frame
    virtual void Tick(float DeltaTime) override;

    // Called to bind functionality to input
    virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

};
"

4. 生成CPP文件

GenerateClassCPPFile

CPP = // Fill out your copyright notice in the Description page of Project Settings.

#include "HowTo_VTE.h"
#include "MyPawn.h"

// Sets default values
AMyPawn::AMyPawn()
{
    // Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;

}

// Called when the game starts or when spawned
void AMyPawn::BeginPlay()
{
    Super::BeginPlay();
    %CURSORFOCUSLOCATION%
}

// Called every frame
void AMyPawn::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

}

// Called to bind functionality to input
void AMyPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    Super::SetupPlayerInputComponent(PlayerInputComponent);

}

5. 编译

检测是否可避免全部编译工程,自动热加载,代码首次编译,RecompileModule —>

CheckForFinishedModuleDLLCompile

图3

6. 工程重新加载。

代码生成完毕。

二、 一张图

图4

一图千言

三、 文件生成模板

UE4 代码写的很精妙!

看模板头文件生成:

FString FinalOutput = Template.Replace(TEXT("%COPYRIGHT_LINE%"), *MakeCopyrightLine(), ESearchCase::CaseSensitive);
    FinalOutput = FinalOutput.Replace(TEXT("%UNPREFIXED_CLASS_NAME%"), *UnPrefixedClassName, ESearchCase::CaseSensitive);
    FinalOutput = FinalOutput.Replace(TEXT("%CLASS_MODULE_API_MACRO%"), *ModuleAPIMacro, ESearchCase::CaseSensitive);
    FinalOutput = FinalOutput.Replace(TEXT("%UCLASS_SPECIFIER_LIST%"), *MakeCommaDelimitedList(ClassSpecifierList, false), ESearchCase::CaseSensitive);
    FinalOutput = FinalOutput.Replace(TEXT("%PREFIXED_CLASS_NAME%"), *PrefixedClassName, ESearchCase::CaseSensitive);
    FinalOutput = FinalOutput.Replace(TEXT("%PREFIXED_BASE_CLASS_NAME%"), *PrefixedBaseClassName, ESearchCase::CaseSensitive);
    FinalOutput = FinalOutput.Replace(TEXT("%EVENTUAL_CONSTRUCTOR_DECLARATION%"), *EventualConstructorDeclaration, ESearchCase::CaseSensitive);
    FinalOutput = FinalOutput.Replace(TEXT("%CLASS_PROPERTIES%"), *ClassProperties, ESearchCase::CaseSensitive);
    FinalOutput = FinalOutput.Replace(TEXT("%CLASS_FUNCTION_DECLARATIONS%"), *ClassFunctionDeclarations, ESearchCase::CaseSensitive);
    FinalOutput = FinalOutput.Replace(TEXT("%BASE_CLASS_INCLUDE_DIRECTIVE%"), *BaseClassIncludeDirective, ESearchCase::CaseSensitive);

CPP文件也类似的。

其中,Tmplate得到是某个继承类的模板字符串,然后通过特定符号来进行替换,生成文件。

模板文件的路径在:UE4_source\UnrealEngine\Engine\Content\Editor\Templates\

比如测试的继承基类为Pawn,他们的模板头文件和CPP文件分别为: PawnClass.h.template 和PawnClass.cpp.template 。

可以自行打开和修改文件。

PawnClass.h.template

%COPYRIGHT_LINE%

#pragma once
%BASE_CLASS_INCLUDE_DIRECTIVE%
#include "%UNPREFIXED_CLASS_NAME%.generated.h"

UCLASS(%UCLASS_SPECIFIER_LIST%)
class %CLASS_MODULE_API_MACRO%%PREFIXED_CLASS_NAME% : public %PREFIXED_BASE_CLASS_NAME%
{
    GENERATED_BODY()

public:
    // Sets default values for this pawn's properties
    %PREFIXED_CLASS_NAME%();

protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public:
    // Called every frame
    virtual void Tick(float DeltaTime) override;

    // Called to bind functionality to input
    virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

    %CLASS_FUNCTION_DECLARATIONS%
    %CLASS_PROPERTIES%
};

PawnClass.cpp.template

%COPYRIGHT_LINE%

#include "%MODULE_INCLUDE_PATH%"
#include "%UNPREFIXED_CLASS_NAME%.h"
%ADDITIONAL_INCLUDE_DIRECTIVES%

// Sets default values
%PREFIXED_CLASS_NAME%::%PREFIXED_CLASS_NAME%()
{
    // Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;

}

// Called when the game starts or when spawned
void %PREFIXED_CLASS_NAME%::BeginPlay()
{
    Super::BeginPlay();
    %CURSORFOCUSLOCATION%
}

// Called every frame
void %PREFIXED_CLASS_NAME%::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

}

// Called to bind functionality to input
void %PREFIXED_CLASS_NAME%::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    Super::SetupPlayerInputComponent(PlayerInputComponent);

}

%ADDITIONAL_MEMBER_DEFINITIONS%

是不是可以自定义头文件呢,估计可以。暂时没有研究。

UE4 工程量太大了,什么样脑子才能架构这玩意啊,他们都是天才!


UE4Paragon游戏人物截图!

谢谢浏览,欢迎点赞!!!

UE4中类自动生成代码解析的更多相关文章

  1. 【MyBatis】MyBatis自动生成代码查询之爬坑记

    前言 项目使用SSM框架搭建Web后台服务,前台后使用restful api,后台使用MyBatisGenerator自动生成代码,在前台使用关键字进行查询时,遇到了一些很宝贵的坑,现记录如下.为展示 ...

  2. 02 使用Mybatis的逆向工程自动生成代码

    1.逆向工程的作用 Mybatis 官方提供了逆向工程,可以针对数据库表自动生成Mybatis执行所需要的代码(包括mapper.xml.Mapper.java.pojo). 2.逆向工程的使用方法 ...

  3. 使用mybatis-generator-core自动生成代码

    SSM框架可以使用mybatis-generator-core-1.3.2.jar来自动生成代码,以下是配置和使用的代码. generatorConfig.xml <?xml version=& ...

  4. Maven mybatis-generator自动生成代码

    mybatis-generator可以自动生成代码,不管你是否喜欢它生成的代码的风格,它确实有助于我们更快速便捷的生成代码. Maven pom文件配置: <build> <plug ...

  5. springboot mybatis 自动生成代码(maven+IntelliJ IDEA)

    1.在pom文件中加入需要的依赖(mybatis-generator-core) 和 插件(mybatis-generator-maven-plugin) <dependency> < ...

  6. IDEA Maven Mybatis generator 自动生成代码(实例讲解)(转)

    IDEA Maven Mybatis generator 自动生成代码(实例讲解) MyBatis Generator • 简称MBG,是一个专门为MyBatis框架使用者定制的代码生成器,可以快速的 ...

  7. (转)MyBatis框架的学习(七)——MyBatis逆向工程自动生成代码

    http://blog.csdn.net/yerenyuan_pku/article/details/71909325 什么是逆向工程 MyBatis的一个主要的特点就是需要程序员自己编写sql,那么 ...

  8. 使用Mybatis的逆向工程自动生成代码

    1.逆向工程的作用 Mybatis 官方提供了逆向工程,可以针对数据库表自动生成Mybatis执行所需要的代码(包括mapper.xml.Mapper.java.pojo). 2.逆向工程的使用方法 ...

  9. MyBatis框架之mybatis逆向工程自动生成代码

    http://www.jb51.net/article/82062.htm Mybatis属于半自动ORM,在使用这个框架中,工作量最大的就是书写Mapping的映射文件,由于手动书写很容易出错,我们 ...

随机推荐

  1. java语言学习笔记1

    最近也在春节的节假日里,总是会有各种各样的事情出现,没有很完整的时间来学习java以及其他方面的知识. 从昨天开始有了完整的学习体系,我去娄老师推荐的极客学院网站开始学习java语言的语法.在假期之初 ...

  2. 聊一聊HTML <!DOCTYPE> 标签

    一般一个基本html页面的结构,如下代码所示: <html> <head> <title>我是基本的页面结构</title> </head> ...

  3. CentOS 7 Firewalld 常用操作

    1.简介 Zone 级别 drop: 丢弃所有进入的包,而不给出任何响应block: 拒绝所有外部发起的连接,允许内部发起的连接public: 允许指定的进入连接external: 同上,对伪装的进入 ...

  4. 同余定理简单应用 - poj2769 - hdu 1021 - hdu 2035

    同余问题 基本定理: 若a,b,c,d是整数,m是正整数, a = b(mod m), c = d(mod m) a+c = b+c(mod m) ac = bc(mod m) ax+cy = bx+ ...

  5. 北京联通光猫 F427 路由改桥接的方法

    最近安装了一个联通的宽带,赠送的光猫是 中兴 F427,然后联通小哥给安装的时候,直接开启了光猫的路由功能. 不过联通这个光猫实在是太弱了,起码默认的帐号开启的功能实在是太弱了,没法完成以下几个功能: ...

  6. Codeforces Round #365 (Div. 2) D - Mishka and Interesting sum(离线树状数组)

    http://codeforces.com/contest/703/problem/D 题意: 给出一行数,有m次查询,每次查询输出区间内出现次数为偶数次的数字的异或和. 思路: 这儿利用一下异或和的 ...

  7. HDU 5773 The All-purpose Zero(O(nlgn)求LIS)

    http://acm.hdu.edu.cn/showproblem.php?pid=5773 题意: 求LIS,其中的0可以看做任何数. 思路: 因为0可以看做任何数,所以我们可以先不管0,先求一遍L ...

  8. linux与window的\r与\n

    应用程序 void niuniu(void) { char buf[16]; char *p[6]; int i; led_init(); uart_init(); while(1) { puts(& ...

  9. zabbix自动化运维学习笔记(服务器安装)

    最近博主开始接触自动化运维.首先就是zabbix这个开源的监控系统 一开始博主只是在自己的虚拟机上尝试安装.最后终于开始在公司的服务器上正式安装,教程博主也是通过度娘找的 这是原文:链接 安装环境:C ...

  10. MVVM模式的3种command总结[1]--DelegateCommand

    MVVM模式的3种command总结[1]--DelegateCommand 查了不少资料,大概理清楚的就是有3种.当然类名可以自己取了,不过为了便于记忆和区分,还是和看到的文章里面用一样的类名. 1 ...