vault backup: 2024-10-12 17:19:45
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
# Atomic
|
||||
|
||||
- **功能描述:** 指定该结构在序列化的时候总是一整个输出全部属性,而不是只输出改变的属性。
|
||||
- **元数据类型:** bool
|
||||
- **引擎模块:** UHT
|
||||
- **作用机制:** 在StructFlags中加入[STRUCT_Atomic](../../../../Flags/EStructFlags/STRUCT_Atomic.md)
|
||||
- **常用程度:** ★
|
||||
|
||||
指定该结构在序列化的时候总是一整个输出全部属性,而不是只输出改变的属性。
|
||||
|
||||
所谓的原子化序列化指的是如果该结构的某个字段属性同默认值不同,但是其他字段相同,也要一次性的序列化整个结构,而不是拆开。注意这个只在普通的SerializeVersionedTaggedProperties下有效,因为是对比默认值。在Bin下无效。其实作用机理是当采用原子化序列化的时候,就不检查内部属性的默认值,从而无论什么情况都会序列化进整个属性。
|
||||
|
||||
UE的noexporttype.h中有大量的atomic的基础结构,如FVector,因为Immutable也会同时设置STRUCT_Atomic,但是没有发现单独设置Atomic的地方。
|
||||
|
||||
## 示例代码:
|
||||
|
||||
```cpp
|
||||
USTRUCT(BlueprintType)
|
||||
struct INSIDER_API FMyStruct_InnerItem
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere)
|
||||
int32 A = 1;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere)
|
||||
int32 B = 2;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere)
|
||||
int32 C = 3;
|
||||
|
||||
bool operator==(const FMyStruct_InnerItem& other)const
|
||||
{
|
||||
return A == other.A;
|
||||
}
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct INSIDER_API FMyStruct_NoAtomic
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere)
|
||||
FMyStruct_InnerItem Item;
|
||||
};
|
||||
|
||||
USTRUCT(Atomic, BlueprintType)
|
||||
struct INSIDER_API FMyStruct_Atomic
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere)
|
||||
FMyStruct_InnerItem Item;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct TStructOpsTypeTraits<FMyStruct_InnerItem> : public TStructOpsTypeTraitsBase2<FMyStruct_InnerItem>
|
||||
{
|
||||
enum
|
||||
{
|
||||
WithIdenticalViaEquality = true,
|
||||
};
|
||||
};
|
||||
|
||||
void USerializationLibrary::SaveStructToMemory(UScriptStruct* structClass, void* structObject, const void* structDefaults, TArray<uint8>& outSaveData, EInsiderSerializationFlags flags/*=EInsiderSerializationFlags::None*/)
|
||||
{
|
||||
FMemoryWriter MemoryWriter(outSaveData, false);
|
||||
MemoryWriter.SetWantBinaryPropertySerialization(EnumHasAnyFlags(flags, EInsiderSerializationFlags::UseBinary));
|
||||
if (!EnumHasAnyFlags(flags, EInsiderSerializationFlags::CheckDefaults))
|
||||
{
|
||||
structDefaults=nullptr;
|
||||
}
|
||||
structClass->SerializeItem(MemoryWriter, structObject, structDefaults);
|
||||
}
|
||||
|
||||
测试代码:
|
||||
FMyStruct_NoAtomic NoAtomicStruct;
|
||||
NoAtomicStruct.Item.A=3;
|
||||
|
||||
FMyStruct_Atomic AtomicStruct;
|
||||
AtomicStruct.Item.A=3;
|
||||
|
||||
TArray<uint8> NoAtomicMemoryChanged;
|
||||
USerializationLibrary::SaveStructToMemory(NoAtomicStruct,NoAtomicMemoryChanged,EInsiderSerializationFlags::CheckDefaults);
|
||||
|
||||
TArray<uint8> AtomicMemoryChanged;
|
||||
USerializationLibrary::SaveStructToMemory(AtomicStruct,AtomicMemoryChanged,EInsiderSerializationFlags::CheckDefaults);
|
||||
```
|
||||
|
||||
## 示例效果:
|
||||
|
||||
可见AtomicMemoryChanged的占用内存大小比AtomicMemoryChanged多,因为这两个结构的属性虽然都改变了,但是AtomicStruct总是会把所有的属性都序列化出来。
|
||||
|
||||

|
||||
|
||||
## 原理:
|
||||
|
||||
作用的机理是,一个外部结构是Atomic的,其内部的属性如果发现有改变,这个时候内部属性得是另一个结构,因为如果只是Int属性,则不会对比内部属性默认值。如果是内部结构属性的话,因为其中一个ID字段不一样,就在对比的时候导致整个结构不等(但同时该内部结构又有其他属性是相同的,所以上面示例代码只改了A,且提供了==的比较函数)。默认的方式是依然会在内部结构的内部属性上继续对比默认值,但原子化后就截断了默认值为null,从而导致孙子属性没有默认值可对比,从而就把整个内部属性就都输出出来。因此Atomic是用在外部结构上的,用在FVector这种不太会继续拆开的结构其实没什么意义。
|
||||
|
||||
```cpp
|
||||
void UStruct::SerializeVersionedTaggedProperties(FStructuredArchive::FSlot Slot, uint8* Data, UStruct* DefaultsStruct, uint8* Defaults, const UObject* BreakRecursionIfFullyLoad) const
|
||||
{
|
||||
//……
|
||||
/** If true, it means that we want to serialize all properties of this struct if any properties differ from defaults */
|
||||
bool bUseAtomicSerialization = false;
|
||||
if (DefaultsScriptStruct)
|
||||
{
|
||||
bUseAtomicSerialization = DefaultsScriptStruct->ShouldSerializeAtomically(UnderlyingArchive);
|
||||
}
|
||||
|
||||
if (bUseAtomicSerialization)
|
||||
{
|
||||
DefaultValue = NULL;
|
||||
}
|
||||
}
|
||||
```
|
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
@@ -0,0 +1,42 @@
|
||||
# HasDefaults
|
||||
|
||||
- **功能描述:** 指定该结构的字段拥有默认值。这样如果本结构作为函数参数或返回值时候,函数则可以为其提供默认值。
|
||||
- **元数据类型:** bool
|
||||
- **引擎模块:** UHT
|
||||
- **限制类型:** 只在NoExportTypes.h供UHT使用
|
||||
- **作用机制:** 在FunctionFlags中加入[FUNC_HasDefaults](../../../Flags/EFunctionFlags/FUNC_HasDefaults.md)
|
||||
- **常用程度:** 0
|
||||
|
||||
指定该结构的字段拥有默认值。
|
||||
|
||||
不是指的是NoExportTypes.h的声明上是否写有默认值,而是指其真正的声明之处,其内部的属性都有初始值。这样如果本结构作为函数参数或返回值时候,函数则可以为其提供默认值。
|
||||
|
||||
NoExportTypes.h里的大部分结构都拥有该结构(88/135),没有的是像FPackedXXX的。
|
||||
|
||||
## 原理:
|
||||
|
||||
如果是一个class中的函数且参数用到了结构,如果该结构拥有HasDefaults,则会造成EFunctionFlags.HasDefaults
|
||||
|
||||
```cpp
|
||||
// The following code is only performed on functions in a class.
|
||||
if (Outer is UhtClass)
|
||||
{
|
||||
foreach (UhtType type in Children)
|
||||
{
|
||||
if (type is UhtProperty property)
|
||||
{
|
||||
if (property.PropertyFlags.HasExactFlags(EPropertyFlags.OutParm | EPropertyFlags.ReturnParm, EPropertyFlags.OutParm))
|
||||
{
|
||||
FunctionFlags |= EFunctionFlags.HasOutParms;
|
||||
}
|
||||
if (property is UhtStructProperty structProperty)
|
||||
{
|
||||
if (structProperty.ScriptStruct.HasDefaults)
|
||||
{
|
||||
FunctionFlags |= EFunctionFlags.HasDefaults;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
@@ -0,0 +1,61 @@
|
||||
# HasNoOpConstructor
|
||||
|
||||
- **功能描述:** 指定该结构拥有ForceInit的构造函数,这样在作为BP function返回值的时候,可以调用来初始化
|
||||
- **元数据类型:** bool
|
||||
- **引擎模块:** UHT
|
||||
- **限制类型:** 只在NoExportTypes.h供UHT使用
|
||||
- **常用程度:** 0
|
||||
|
||||
指定该结构拥有ForceInit的构造函数,这样在作为BP Function返回值或参数的时候,引擎就知道这个结构有这么一个构造函数可以调用来初始化。
|
||||
|
||||
作用的地方是UhtHeaderCodeGenerator中的AppendEventParameter,为了这样的代码,这是一个暴露到BP中的Event,要为它生成一些胶水代码。这里FLinearColor 就是HasNoOpConstructor。例如以下这个函数:
|
||||
|
||||
```cpp
|
||||
UFUNCTION(BlueprintNativeEvent, Category = "Modifier")
|
||||
FLinearColor GetVisualizationColor(FInputActionValue SampleValue, FInputActionValue FinalValue) const;
|
||||
```
|
||||
|
||||
生成的代码:
|
||||
|
||||
```cpp
|
||||
struct InputModifier_eventGetVisualizationColor_Parms
|
||||
{
|
||||
FInputActionValue SampleValue;
|
||||
FInputActionValue FinalValue;
|
||||
FLinearColor ReturnValue;
|
||||
|
||||
/** Constructor, initializes return property only **/
|
||||
InputModifier_eventGetVisualizationColor_Parms()
|
||||
: ReturnValue(ForceInit)//强制初始化
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static FName NAME_UInputModifier_GetVisualizationColor = FName(TEXT("GetVisualizationColor"));
|
||||
FLinearColor UInputModifier::GetVisualizationColor(FInputActionValue SampleValue, FInputActionValue FinalValue) const
|
||||
{
|
||||
InputModifier_eventGetVisualizationColor_Parms Parms;
|
||||
Parms.SampleValue=SampleValue;
|
||||
Parms.FinalValue=FinalValue;
|
||||
const_cast<UInputModifier*>(this)->ProcessEvent(FindFunctionChecked(NAME_UInputModifier_GetVisualizationColor),&Parms);
|
||||
return Parms.ReturnValue;
|
||||
}
|
||||
```
|
||||
|
||||
因此要求该结构拥有ForceInit的构造函数
|
||||
|
||||
```cpp
|
||||
FORCEINLINE explicit FLinearColor(EForceInit)
|
||||
: R(0), G(0), B(0), A(0)
|
||||
{}
|
||||
```
|
||||
|
||||
## 原理:
|
||||
|
||||
```cpp
|
||||
if (ScriptStruct.HasNoOpConstructor)
|
||||
{
|
||||
//If true, the an argument will need to be added to the constructor
|
||||
PropertyCaps |= UhtPropertyCaps.RequiresNullConstructorArg;
|
||||
}
|
||||
```
|
@@ -0,0 +1,120 @@
|
||||
# IsAlwaysAccessible
|
||||
|
||||
- **功能描述:** 指定UHT在生成文件的时候总是可以访问到改结构的声明,否则要在gen.cpp里生成镜像结构定义
|
||||
- **元数据类型:** bool
|
||||
- **引擎模块:** UHT
|
||||
- **限制类型:** 只在NoExportTypes.h供UHT使用
|
||||
- **常用程度:** 0
|
||||
|
||||
指定该结构的声明是否在UHT为NoExportTypes.h生成的gen.cpp里总是可以访问到。
|
||||
|
||||
换句话说其实就是是否这些结构在GeneratedCppIncludes.h的声明里可以找到。如果不可以找到,那在后面生成Z_Construct_UScriptStruct_FMatrix44d_Statics这种类似的时候就得再自己定义一个镜像结构定义。如果可以找到,比如FGuid,则就不需要。
|
||||
|
||||
因此这只是一个手动的内部标记,帮助UHT程序识别哪些结构要再创建镜像结构定义。
|
||||
|
||||
在NoExportTypes.h查看各个结构的时候,会发现有些结构(85/135)会标上IsAlwaysAccessible,而有些没有。这是因为UHT在为NoExportTypes.h生成gen.cpp的时候,
|
||||
|
||||
```cpp
|
||||
\UnrealEngine\Engine\Source\Runtime\CoreUObject\Public\UObject\GeneratedCppIncludes.h
|
||||
#include "UObject/Object.h"
|
||||
#include "UObject/UObjectGlobals.h"
|
||||
#include "UObject/CoreNative.h"
|
||||
#include "UObject/Class.h"
|
||||
#include "UObject/MetaData.h"
|
||||
#include "UObject/UnrealType.h"
|
||||
#include "UObject/EnumProperty.h"
|
||||
#include "UObject/TextProperty.h"
|
||||
#include "UObject/FieldPathProperty.h"
|
||||
|
||||
#if UE_ENABLE_INCLUDE_ORDER_DEPRECATED_IN_5_2
|
||||
#include "CoreMinimal.h"
|
||||
#endif
|
||||
|
||||
\Hello\Intermediate\Build\Win64\HelloEditor\Inc\CoreUObject\UHT\NoExportTypes.gen.cpp:
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
/*===========================================================================
|
||||
Generated code exported from UnrealHeaderTool.
|
||||
DO NOT modify this manually! Edit the corresponding .h files instead!
|
||||
===========================================================================*/
|
||||
|
||||
//以下这两行
|
||||
#include "UObject/GeneratedCppIncludes.h"//A
|
||||
#include "UObject/NoExportTypes.h"//B
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||
void EmptyLinkFunctionForGeneratedCodeNoExportTypes() {}
|
||||
```
|
||||
|
||||
在最开头的两个include里如果可以直接找到该struct的定义,则在gen.cpp中的A和B处需要结构定义的时候,就不需要再额外去找定义了。
|
||||
|
||||
```cpp
|
||||
const UECodeGen_Private::FStructParams Z_Construct_UScriptStruct_FMatrix44f_Statics::ReturnStructParams = {
|
||||
(UObject* (*)())Z_Construct_UPackage__Script_CoreUObject,
|
||||
nullptr,
|
||||
nullptr,
|
||||
"Matrix44f",
|
||||
Z_Construct_UScriptStruct_FMatrix44f_Statics::PropPointers,
|
||||
UE_ARRAY_COUNT(Z_Construct_UScriptStruct_FMatrix44f_Statics::PropPointers),
|
||||
sizeof(FMatrix44f),//这个A
|
||||
alignof(FMatrix44f),//这个B
|
||||
RF_Public|RF_Transient|RF_MarkAsNative,
|
||||
EStructFlags(0x00000038),
|
||||
METADATA_PARAMS(UE_ARRAY_COUNT(Z_Construct_UScriptStruct_FMatrix44f_Statics::Struct_MetaDataParams), Z_Construct_UScriptStruct_FMatrix44f_Statics::Struct_MetaDataParams)
|
||||
};
|
||||
```
|
||||
|
||||
如果找不到,比如FMatrix44f,是定义在Engine\Source\Runtime\Core\Public\Math\Matrix.h,则必须为它生成一个一模一样的定义(不include的作用是加快编译):
|
||||
|
||||
```cpp
|
||||
struct Z_Construct_UScriptStruct_FMatrix44f_Statics
|
||||
{
|
||||
struct FMatrix44f //内存布局一致的定义
|
||||
{
|
||||
FPlane4f XPlane;
|
||||
FPlane4f YPlane;
|
||||
FPlane4f ZPlane;
|
||||
FPlane4f WPlane;
|
||||
};
|
||||
|
||||
static_assert(sizeof(FMatrix44f) < MAX_uint16);
|
||||
static_assert(alignof(FMatrix44f) < MAX_uint8);
|
||||
```
|
||||
|
||||
当然如果子字段或者父类也找不到定义,则只需要把父定义先写在前面就可以了。因此cs里的FindNoExportStructsRecursive就是为了找到其相关的结构。没有标IsAlwaysAccessible则意味着要生成假的结构定义
|
||||
|
||||
```cpp
|
||||
private static void FindNoExportStructsRecursive(List<UhtScriptStruct> outScriptStructs, UhtStruct structObj)
|
||||
{
|
||||
for (UhtStruct? current = structObj; current != null; current = current.SuperStruct)
|
||||
{
|
||||
// Is isn't true for noexport structs
|
||||
if (current is UhtScriptStruct scriptStruct)
|
||||
{
|
||||
if (scriptStruct.ScriptStructFlags.HasAnyFlags(EStructFlags.Native))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// these are a special cases that already exists and if wrong if exported naively
|
||||
if (!scriptStruct.IsAlwaysAccessible)
|
||||
{
|
||||
outScriptStructs.Remove(scriptStruct);
|
||||
outScriptStructs.Add(scriptStruct);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (UhtType type in current.Children)
|
||||
{
|
||||
if (type is UhtProperty property)
|
||||
{
|
||||
foreach (UhtType referenceType in property.EnumerateReferencedTypes())
|
||||
{
|
||||
if (referenceType is UhtScriptStruct propertyScriptStruct)
|
||||
{
|
||||
FindNoExportStructsRecursive(outScriptStructs, propertyScriptStruct);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
@@ -0,0 +1,32 @@
|
||||
# IsCoreType
|
||||
|
||||
- **功能描述:** 指定该结构是核心类,UHT在用它的时候不需要前向声明。
|
||||
- **元数据类型:** bool
|
||||
- **引擎模块:** UHT
|
||||
- **限制类型:** 只在NoExportTypes.h供UHT使用
|
||||
- **常用程度:** 0
|
||||
|
||||
指定该结构是核心类,UHT在用它的时候不需要前向声明。
|
||||
|
||||
## 原理:
|
||||
|
||||
看UHT源码是把struct用在参数或属性等被引用的时候。
|
||||
|
||||
```cpp
|
||||
public override string? UhtStructProperty::GetForwardDeclarations()
|
||||
{
|
||||
if (ScriptStruct.IsCoreType)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (TemplateWrapper != null)
|
||||
{
|
||||
StringBuilder builder = new();
|
||||
TemplateWrapper.AppendForwardDeclarations(builder);
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
return $"struct {ScriptStruct.SourceName};";
|
||||
}
|
||||
```
|
@@ -0,0 +1,158 @@
|
||||
# NoExport
|
||||
|
||||
- **功能描述:** 指定UHT不要用来自动生成注册的代码,而只是进行词法分析提取元数据。
|
||||
- **元数据类型:** bool
|
||||
- **引擎模块:** UHT
|
||||
- **常用程度:★**
|
||||
|
||||
指定UHT不要用来自动生成注册的代码,而只是进行词法分析提取元数据。
|
||||
|
||||
NoExportTypes.h里使用了很多该例子。定义的结构常常用!CPP宏包起来以不在C++中参与编译。因此一般是只给引擎内部使用的。
|
||||
|
||||
实际上我们想使用也可以,只要保持C++中内存布局一样,就可以自己多定义。使用场景:想自己定义一个UHT头喂给UHT分析,然后自己在别处定义实际的C++。一种典型用途是C++里的实际多个类继承于一个模板基类,如FVector2MaterialInput,这样可以每个特化子类定一个UHT类型别名。另一种目的是把UHT要分析的头文件都放在一个文件里,加速UHT分析生成,不用分析多个文件,反正只要UHT信息和内存布局对就行。
|
||||
|
||||
```cpp
|
||||
#if !CPP // begin noexport class
|
||||
USTRUCT(noexport, BlueprintType) //如果不写noexport,会报错:Expected a GENERATED_BODY() at the start of the struct、
|
||||
struct FFloatRK4SpringInterpolator
|
||||
{
|
||||
|
||||
UPROPERTY(EditAnywhere, Category = "FloatRK4SpringInterpolator")
|
||||
float StiffnessConstant;
|
||||
|
||||
/** 0 = Undamped, <1 = Underdamped, 1 = Critically damped, >1 = Over damped */
|
||||
UPROPERTY(EditAnywhere, Category = "FloatRK4SpringInterpolator")
|
||||
float DampeningRatio;
|
||||
|
||||
bool bIsInitialized;
|
||||
bool bIsInMotion;
|
||||
float TimeRemaining;
|
||||
FRK4SpringConstants SpringConstants;
|
||||
|
||||
float LastPosition;
|
||||
RK4Integrator::FRK4State<float> State;
|
||||
};
|
||||
#endif // end noexport class
|
||||
|
||||
//实际应用:
|
||||
template <typename T>
|
||||
struct FRK4SpringInterpolator
|
||||
{
|
||||
protected:
|
||||
float StiffnessConstant;
|
||||
float DampeningRatio;
|
||||
|
||||
bool bIsInitialized;
|
||||
bool bIsInMotion;
|
||||
float TimeRemaining;
|
||||
FRK4SpringConstants SpringConstants;
|
||||
|
||||
T LastPosition;
|
||||
RK4Integrator::FRK4State<T> State;
|
||||
}
|
||||
|
||||
struct FFloatRK4SpringInterpolator : FRK4SpringInterpolator<float>
|
||||
struct FVectorRK4SpringInterpolator : FRK4SpringInterpolator<FVector>
|
||||
```
|
||||
|
||||
不生成的代码包括:
|
||||
|
||||
```cpp
|
||||
USTRUCT(BlueprintType,noexport)
|
||||
struct INSIDER_API FMyStruct_NoExport
|
||||
{
|
||||
//抑制:GENERATED_BODY()解释生成的:
|
||||
//static class UScriptStruct* StaticStruct();
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere)
|
||||
float Score;
|
||||
};
|
||||
|
||||
//抑制:
|
||||
//template<> INSIDER_API UScriptStruct* StaticStruct<struct FMyStruct_NoExport>();
|
||||
```
|
||||
|
||||
.h里不会生成,因此不会在别的模块里使用
|
||||
|
||||
```cpp
|
||||
template<> INSIDER_API UScriptStruct* StaticStruct<struct FMyStruct_NoExport>();
|
||||
```
|
||||
|
||||
但是依然会在Module.init.gen.cpp里生成Z_Construct_UScriptStruct_FMyStruct_NoExport的调用,因此还是会在蓝图里暴露出来。
|
||||
|
||||
```cpp
|
||||
#include "UObject/GeneratedCppIncludes.h"
|
||||
PRAGMA_DISABLE_DEPRECATION_WARNINGS
|
||||
void EmptyLinkFunctionForGeneratedCodeInsider_init() {}
|
||||
INSIDER_API UScriptStruct* Z_Construct_UScriptStruct_FMyStruct_NoExport();
|
||||
static FPackageRegistrationInfo Z_Registration_Info_UPackage__Script_Insider;
|
||||
FORCENOINLINE UPackage* Z_Construct_UPackage__Script_Insider()
|
||||
{
|
||||
if (!Z_Registration_Info_UPackage__Script_Insider.OuterSingleton)
|
||||
{
|
||||
static UObject* (*const SingletonFuncArray[])() = {
|
||||
(UObject* (*)())Z_Construct_UScriptStruct_FMyStruct_NoExport,//这里注入调用
|
||||
};
|
||||
static const UECodeGen_Private::FPackageParams PackageParams = {
|
||||
"/Script/Insider",
|
||||
SingletonFuncArray,
|
||||
UE_ARRAY_COUNT(SingletonFuncArray),
|
||||
PKG_CompiledIn | 0x00000000,
|
||||
0x02A7B98C,
|
||||
0xFA17C3C4,
|
||||
METADATA_PARAMS(0, nullptr)
|
||||
};
|
||||
UECodeGen_Private::ConstructUPackage(Z_Registration_Info_UPackage__Script_Insider.OuterSingleton, PackageParams);
|
||||
}
|
||||
return Z_Registration_Info_UPackage__Script_Insider.OuterSingleton;
|
||||
}
|
||||
static FRegisterCompiledInInfo Z_CompiledInDeferPackage_UPackage__Script_Insider(Z_Construct_UPackage__Script_Insider, TEXT("/Script/Insider"), Z_Registration_Info_UPackage__Script_Insider, CONSTRUCT_RELOAD_VERSION_INFO(FPackageReloadVersionInfo, 0x02A7B98C, 0xFA17C3C4));
|
||||
PRAGMA_ENABLE_DEPRECATION_WARNINGS
|
||||
```
|
||||
|
||||
蓝图里的效果:依然可以当作变量。
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
加上noexport的区别是不能用StaticStruct和没了TCppStructOps,不能做一些优化。其他还是可以正常使用,就像FVector一样。
|
||||
|
||||
缺失的代码,也可以通过手动添加代码来获得。
|
||||
|
||||
```cpp
|
||||
USTRUCT(BlueprintType,noexport)
|
||||
struct INSIDER_API FMyStruct_NoExport
|
||||
{
|
||||
//GENERATED_BODY() //missing type specifier - int assumed,..generated.h里只是定一个StaticStruct()函数
|
||||
|
||||
static class UScriptStruct* StaticStruct(); //可以自己定义
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere)
|
||||
float Score;
|
||||
|
||||
};
|
||||
|
||||
template<> INSIDER_API UScriptStruct* StaticStruct<struct FMyStruct_NoExport>();//可以自己定义
|
||||
|
||||
//.cpp
|
||||
//链入函数声明,在其他的cpp里已经有实现,所以可以正常调用到
|
||||
INSIDER_API UScriptStruct* Z_Construct_UScriptStruct_FMyStruct_NoExport();
|
||||
UPackage* Z_Construct_UPackage__Script_Insider();
|
||||
|
||||
static FStructRegistrationInfo Z_Registration_Info_UScriptStruct_MyStruct_NoExport;
|
||||
|
||||
class UScriptStruct* FMyStruct_NoExport::StaticStruct()
|
||||
{
|
||||
if (!Z_Registration_Info_UScriptStruct_MyStruct_NoExport.OuterSingleton)
|
||||
{
|
||||
Z_Registration_Info_UScriptStruct_MyStruct_NoExport.OuterSingleton = GetStaticStruct(Z_Construct_UScriptStruct_FMyStruct_NoExport, Z_Construct_UPackage__Script_Insider(), TEXT("MyStruct_NoExport"));
|
||||
}
|
||||
return Z_Registration_Info_UScriptStruct_MyStruct_NoExport.OuterSingleton;
|
||||
}
|
||||
|
||||
template<> INSIDER_API UScriptStruct* StaticStruct<FMyStruct_NoExport>()
|
||||
{
|
||||
return FMyStruct_NoExport::StaticStruct();
|
||||
}
|
||||
```
|
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
Reference in New Issue
Block a user