vault backup: 2024-10-12 17:19:45
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
# AllowAnyActor
|
||||
|
||||
- **功能描述:** 用在ComponentReference属性上,在UseComponentPicker的情况下使得组件选取器扩大到场景里其他Actor下的其他组件。
|
||||
- **使用位置:** UPROPERTY
|
||||
- **引擎模块:** Component Property
|
||||
- **元数据类型:** bool
|
||||
- **限制类型:** FComponentReference,FSoftComponentReference
|
||||
- **关联项:** [UseComponentPicker](UseComponentPicker/UseComponentPicker.md)
|
||||
- **常用程度:** ★★
|
||||
|
||||
用在ComponentReference属性上,在UseComponentPicker的情况下使得组件选取器扩大到场景里其他Actor下的其他组件。
|
||||
|
||||
- 也要注意到,这个AllowAnyActor影响的只是UI上的组件选择。一个ComponentReference即使不加AllowAnyActor,也可以通过ReferencedActor引用到别的Actor,然后手填其属下的组件名字。然后可以正常的在C++里GetComponent里出来正确的组件对象。因此AllowAnyActor跟逻辑无关。
|
||||
|
||||
测试代码和效果见UseComponentPicker。
|
||||
|
||||
## 原理:
|
||||
|
||||
主要是FComponentReferenceCustomization。根据源码查看,bAllowAnyActor 只在已经有bUseComponentPicker的情况下生效,且用来对Actor列表进行过滤。
|
||||
|
||||
```cpp
|
||||
void FComponentReferenceCustomization::CustomizeHeader(TSharedRef<IPropertyHandle> InPropertyHandle, FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& CustomizationUtils)
|
||||
{
|
||||
PropertyHandle = InPropertyHandle;
|
||||
|
||||
CachedComponent.Reset();
|
||||
CachedFirstOuterActor.Reset();
|
||||
CachedPropertyAccess = FPropertyAccess::Fail;
|
||||
|
||||
bAllowClear = false;
|
||||
bAllowAnyActor = false;
|
||||
bUseComponentPicker = PropertyHandle->HasMetaData(NAME_UseComponentPicker);
|
||||
bIsSoftReference = false;
|
||||
|
||||
if (bUseComponentPicker)
|
||||
{
|
||||
FProperty* Property = InPropertyHandle->GetProperty();
|
||||
check(CastField<FStructProperty>(Property) &&
|
||||
(FComponentReference::StaticStruct() == CastFieldChecked<const FStructProperty>(Property)->Struct ||
|
||||
FSoftComponentReference::StaticStruct() == CastFieldChecked<const FStructProperty>(Property)->Struct));
|
||||
|
||||
bAllowClear = !(InPropertyHandle->GetMetaDataProperty()->PropertyFlags & CPF_NoClear);
|
||||
bAllowAnyActor = InPropertyHandle->HasMetaData(NAME_AllowAnyActor);
|
||||
bIsSoftReference = FSoftComponentReference::StaticStruct() == CastFieldChecked<const FStructProperty>(Property)->Struct;
|
||||
|
||||
BuildClassFilters();
|
||||
BuildComboBox();
|
||||
|
||||
InPropertyHandle->SetOnPropertyValueChanged(FSimpleDelegate::CreateSP(this, &FComponentReferenceCustomization::OnPropertyValueChanged));
|
||||
|
||||
// set cached values
|
||||
{
|
||||
CachedComponent.Reset();
|
||||
CachedFirstOuterActor = GetFirstOuterActor();
|
||||
|
||||
FComponentReference TmpComponentReference;
|
||||
CachedPropertyAccess = GetValue(TmpComponentReference);
|
||||
if (CachedPropertyAccess == FPropertyAccess::Success)
|
||||
{
|
||||
CachedComponent = TmpComponentReference.GetComponent(CachedFirstOuterActor.Get());
|
||||
if (!IsComponentReferenceValid(TmpComponentReference))
|
||||
{
|
||||
CachedComponent.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HeaderRow.NameContent()
|
||||
[
|
||||
InPropertyHandle->CreatePropertyNameWidget()
|
||||
]
|
||||
.ValueContent()
|
||||
[
|
||||
ComponentComboButton.ToSharedRef()
|
||||
]
|
||||
.IsEnabled(MakeAttributeSP(this, &FComponentReferenceCustomization::CanEdit));
|
||||
}
|
||||
else
|
||||
{
|
||||
HeaderRow.NameContent()
|
||||
[
|
||||
InPropertyHandle->CreatePropertyNameWidget()
|
||||
]
|
||||
.ValueContent()
|
||||
[
|
||||
InPropertyHandle->CreatePropertyValueWidget()
|
||||
]
|
||||
.IsEnabled(MakeAttributeSP(this, &FComponentReferenceCustomization::CanEdit));
|
||||
}
|
||||
}
|
||||
|
||||
bool FComponentReferenceCustomization::IsFilteredActor(const AActor* const Actor) const
|
||||
{
|
||||
return bAllowAnyActor || Actor == CachedFirstOuterActor.Get();
|
||||
}
|
||||
|
||||
```
|
Reference in New Issue
Block a user