vault backup: 2024-10-12 17:19:45
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
# DefaultToInstanced
|
||||
|
||||
- **功能描述:** 指定该类的所有实例属性都默认是UPROPERTY(instanced),即都默认创建新的实例,而不是对对象的引用。
|
||||
- **引擎模块:** Instance
|
||||
- **元数据类型:** bool
|
||||
- **作用机制:** 在ClassFlags中添加[CLASS_DefaultToInstanced](../../../../Flags/EClassFlags/CLASS_DefaultToInstanced.md)
|
||||
- **常用程度:★★★★**
|
||||
|
||||
指定该类的所有实例属性都默认是UPROPERTY(instanced),即都默认创建新的实例,而不是对对象的引用。
|
||||
|
||||
UPROPERTY(instanced)的含义是造成Property的CPF_InstancedReference,即为该属性创建对象实例。
|
||||
|
||||
所谓实例指的是为该UObject指针创建一个对象,而不是默认的去找到引擎内已有的对象的来引用。
|
||||
|
||||
也常常和EditInlineNew配合使用,以便在细节面板中可以创建对象实例。
|
||||
|
||||
UActorComponent本身就是带有DefaultToInstanced的。
|
||||
|
||||
## 示例代码:
|
||||
|
||||
```cpp
|
||||
UCLASS(Blueprintable)
|
||||
class INSIDER_API UMyClass_NotDefaultToInstanced :public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
int32 MyProperty;
|
||||
};
|
||||
|
||||
// ClassFlags: CLASS_MatchedSerializers | CLASS_Native | CLASS_RequiredAPI | CLASS_DefaultToInstanced | CLASS_TokenStreamAssembled | CLASS_Intrinsic | CLASS_Constructed
|
||||
UCLASS(Blueprintable, DefaultToInstanced)
|
||||
class INSIDER_API UMyClass_DefaultToInstanced :public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
int32 MyProperty;
|
||||
};
|
||||
|
||||
// ClassFlags: CLASS_MatchedSerializers | CLASS_Native | CLASS_EditInlineNew | CLASS_RequiredAPI | CLASS_DefaultToInstanced | CLASS_TokenStreamAssembled | CLASS_Intrinsic | CLASS_Constructed
|
||||
UCLASS(Blueprintable, DefaultToInstanced, EditInlineNew)
|
||||
class INSIDER_API UMyClass_DefaultToInstanced_EditInlineNew :public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
int32 MyProperty;
|
||||
};
|
||||
|
||||
UCLASS(Blueprintable, EditInlineNew)
|
||||
class INSIDER_API UMyClass_NotDefaultToInstanced_EditInlineNew :public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
int32 MyProperty;
|
||||
};
|
||||
|
||||
UCLASS(Blueprintable, BlueprintType)
|
||||
class INSIDER_API UMyClass_DefaultToInstanced_Test :public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "NormalProperty")
|
||||
UMyClass_NotDefaultToInstanced* MyObject_NotDefaultToInstanced;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "NormalProperty")
|
||||
UMyClass_DefaultToInstanced* MyObject_DefaultToInstanced;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced, Category = "NormalProperty | Instanced")
|
||||
UMyClass_NotDefaultToInstanced* MyObject_NotDefaultToInstanced_Instanced;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced, Category = "NormalProperty | Instanced")
|
||||
UMyClass_DefaultToInstanced* MyObject_DefaultToInstanced_Instanced;
|
||||
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EditInlineNew")
|
||||
UMyClass_NotDefaultToInstanced_EditInlineNew* MyObject_NotDefaultToInstanced_EditInlineNew;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EditInlineNew")
|
||||
UMyClass_DefaultToInstanced_EditInlineNew* MyObject_DefaultToInstanced_EditInlineNew;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced, Category = "EditInlineNew | Instanced")
|
||||
UMyClass_NotDefaultToInstanced_EditInlineNew* MyObject_NotDefaultToInstanced_EditInlineNew_Instanced;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced, Category = "EditInlineNew | Instanced")
|
||||
UMyClass_DefaultToInstanced_EditInlineNew* MyObject_DefaultToInstanced_EditInlineNew_Instanced;
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
## 示例效果:
|
||||
|
||||
- MyObject_NotDefaultToInstanced和MyObject_NotDefaultToInstanced_EditInlineNew因为属性没有instanced的标记,因此打开是一个选择对象引用的列表。
|
||||
- MyObject_DefaultToInstanced因为类上有DefaultToInstanced,因此该属性是Instanced。当然我们也可以手动给属性加上Instanced标记,正如MyObject_NotDefaultToInstanced_Instanced和MyObject_DefaultToInstanced_Instanced。出现了创建实例的窗口,但是还不能创建在细节面板里直接创建对象。
|
||||
- MyObject_DefaultToInstanced_EditInlineNew,MyObject_NotDefaultToInstanced_EditInlineNew_Instanced,MyObject_DefaultToInstanced_EditInlineNew_Instanced这3个都可以直接在细节面板创建对象实例。是因为这个类本身要有EditInlineNew,另外这个属性要有Instanced(要嘛在该类上设置DefaultToInstanced以此该类的所有属性都自动是Instanced,或者在属性上单个设置Instanced)
|
||||
|
||||

|
||||
|
||||
## 原理:
|
||||
|
||||
```cpp
|
||||
UObject* FObjectInstancingGraph::InstancePropertyValue(UObject* SubObjectTemplate, UObject* CurrentValue, UObject* Owner, EInstancePropertyValueFlags Flags)
|
||||
{
|
||||
if (CurrentValue->GetClass()->HasAnyClassFlags(CLASS_DefaultToInstanced))
|
||||
{
|
||||
bCausesInstancing = true; // these are always instanced no matter what
|
||||
}
|
||||
}
|
||||
```
|
Binary file not shown.
After Width: | Height: | Size: 240 KiB |
@@ -0,0 +1,80 @@
|
||||
# EditInlineNew
|
||||
|
||||
- **功能描述:** 指定该类的对象可以在属性细节面板里直接内联创建,要和属性的Instanced配合。
|
||||
- **引擎模块:** Instance
|
||||
- **元数据类型:** bool
|
||||
- **作用机制:** 在ClassFlags中添加[CLASS_EditInlineNew](../../../../Flags/EClassFlags/CLASS_EditInlineNew.md)
|
||||
- **关联项:** NotEditInlineNew (NotEditInlineNew.md)
|
||||
- **常用程度:★★★★★**
|
||||
|
||||
指定该类的对象可以在属性细节面板里直接内联创建。
|
||||
|
||||
如果想在细节面板里直接创建对象,属性上也必须先标记Instanced或ShowInnerProperties。
|
||||
|
||||
EditInlineNew主要是用在UObject的子类上,一般不标EditInlineNew的是用在Actor或资产的引用上。注意EditInlineNew是表明增加从属性细节面板里直接创建对象实例的能力,而非限制只能在属性细节面板里创建,当然也可以自己手动NewObject再赋值给对象引用属性。
|
||||
|
||||
这个跟UPROPERTY上的Instanced能力是独立的。如果UCLASS上不加EditInlineNew,但是属性上加上Instanced,则在手动NewObject赋值该属性后,该属性也会展开内部属性来提供编辑功能。因为Instanced的属性会自动的在property上加上EditInline的meta。
|
||||
|
||||
此说明符会传播到所有子类;子类可通过 NotEditInlineNew 说明符覆盖它。
|
||||
|
||||
## 示例代码:
|
||||
|
||||
```cpp
|
||||
UCLASS(Blueprintable, EditInlineNew)
|
||||
class INSIDER_API UMyClass_EditInlineNew :public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
int32 MyProperty;
|
||||
};
|
||||
|
||||
UCLASS(Blueprintable, NotEditInlineNew)
|
||||
class INSIDER_API UMyClass_NotEditInlineNew :public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
int32 MyProperty;
|
||||
};
|
||||
|
||||
UCLASS(Blueprintable, BlueprintType)
|
||||
class INSIDER_API UMyClass_Edit_Test :public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced, Category = InstancedProperty)
|
||||
UMyClass_EditInlineNew* MyEditInlineNew;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced, Category = InstancedProperty)
|
||||
UMyClass_NotEditInlineNew* MyNotEditInlineNew;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = NormalProperty)
|
||||
UMyClass_EditInlineNew* MyEditInlineNew_NotInstanced;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = NormalProperty)
|
||||
UMyClass_NotEditInlineNew* MyNotEditInlineNew_NotInstanced;
|
||||
};
|
||||
```
|
||||
|
||||
## 示例效果:
|
||||
|
||||
EditInlineNew支持直接C++或BP子类创建对象实例,然后在上面编辑实例。
|
||||
|
||||
而NotEditInlineNew的属性则无法找到支持的类来创建对象。
|
||||
|
||||
如果属性上没有Instanced则只能尝试去引用(找不到对象)。
|
||||
|
||||

|
||||
|
||||
## 原理:
|
||||
|
||||
判断该类是否有CLASS_EditInlineNew来决定是否可内联创建编辑。
|
||||
|
||||
```cpp
|
||||
template <typename TClass, typename TIsChildOfFunction>
|
||||
bool FPropertyEditorInlineClassFilter::IsClassAllowedHelper(TClass InClass, TIsChildOfFunction IsClassChildOf, TSharedRef< FClassViewerFilterFuncs > InFilterFuncs)
|
||||
{
|
||||
const bool bMatchesFlags = InClass->HasAnyClassFlags(CLASS_EditInlineNew) &&
|
||||
!InClass->HasAnyClassFlags(CLASS_Hidden | CLASS_HideDropDown | CLASS_Deprecated) &&
|
||||
(bAllowAbstract || !InClass->HasAnyClassFlags(CLASS_Abstract));
|
||||
}
|
||||
```
|
Binary file not shown.
After Width: | Height: | Size: 214 KiB |
@@ -0,0 +1,8 @@
|
||||
# NotEditInlineNew
|
||||
|
||||
- **功能描述:** 不能通过EditInline按钮创建
|
||||
- **引擎模块:** Instance
|
||||
- **元数据类型:** bool
|
||||
- **作用机制:** 在ClassFlags中移除[CLASS_EditInlineNew](../../../Flags/EClassFlags/CLASS_EditInlineNew.md)
|
||||
- **关联项:** EditInlineNew (EditInlineNew.md)
|
||||
- **常用程度:★**
|
@@ -0,0 +1,70 @@
|
||||
# Within
|
||||
|
||||
- **功能描述:** 指定对象创建的时候必须依赖于OuterClassName的对象作为Outer。
|
||||
- **引擎模块:** Instance
|
||||
- **元数据类型:** string="abc"
|
||||
- **作用机制:** 保存在UClass* UClass::ClassWithin=XXX的XXX中
|
||||
- **常用程度:★★★**
|
||||
|
||||
指定对象创建的时候必须依赖于OuterClassName的对象作为Outer。
|
||||
|
||||
此类的对象无法在OuterClassName对象的实例之外存在。这意味着,要创建此类的对象,需要提供OuterClassName的一个实例作为其Outer对象。
|
||||
|
||||
本类在这种情况一般是用来当做子对象来使用的。
|
||||
|
||||
## 示例代码:
|
||||
|
||||
```cpp
|
||||
UCLASS(Within= MyClass_Within_Outer)
|
||||
class INSIDER_API UMyClass_Within :public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
};
|
||||
|
||||
UCLASS()
|
||||
class INSIDER_API UMyClass_Within_Outer :public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
};
|
||||
|
||||
|
||||
```
|
||||
|
||||
## 示例结果:
|
||||
|
||||
```cpp
|
||||
//错误!Fatal error: Object MyClass_Within None created in Package instead of MyClass_Within_Outer
|
||||
UMyClass_Within* obj=NewObject<UMyClass_Within>();
|
||||
|
||||
//正确:
|
||||
UMyClass_Within_Outer* objOuter = NewObject<UMyClass_Within_Outer>();
|
||||
UMyClass_Within* obj=NewObject<UMyClass_Within>(objOuter);
|
||||
```
|
||||
|
||||
## 原理:
|
||||
|
||||
生成的UClass的字段:UClass* ClassWithin会保存这个信息,然后在创建的时候StaticAllocateObject会测试 check(bCreatingCDO || !InOuter || InOuter->IsA(InClass->ClassWithin))。因此需要先创建Within的对象。
|
||||
|
||||
```cpp
|
||||
bool StaticAllocateObjectErrorTests( const UClass* InClass, UObject* InOuter, FName InName, EObjectFlags InFlags)
|
||||
{
|
||||
if ( (InFlags & (RF_ClassDefaultObject|RF_ArchetypeObject)) == 0 )
|
||||
{
|
||||
if ( InOuter != NULL && !InOuter->IsA(InClass->ClassWithin) )
|
||||
{
|
||||
UE_LOG(LogUObjectGlobals, Fatal, TEXT("%s"), *FString::Printf( TEXT("Object %s %s created in %s instead of %s"), *InClass->GetName(), *InName.ToString(), *InOuter->GetClass()->GetName(), *InClass->ClassWithin->GetName()) );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
在源码里可以搜索到很多Within的用法
|
||||
|
||||
UCLASS(Within=Engine, config=Engine, transient)
|
||||
class ENGINE_API ULocalPlayer
|
||||
|
||||
UCLASS(Abstract, DefaultToInstanced, Within=UserWidget)
|
||||
class UMG_API UUserWidgetExtension : public UObject
|
||||
{
|
Reference in New Issue
Block a user