98 lines
3.5 KiB
Markdown
Raw Normal View History

2024-10-12 17:19:46 +08:00
# AllowAnyActor
- **功能描述:** 用在ComponentReference属性上在UseComponentPicker的情况下使得组件选取器扩大到场景里其他Actor下的其他组件。
- **使用位置:** UPROPERTY
- **引擎模块:** Component Property
- **元数据类型:** bool
- **限制类型:** FComponentReferenceFSoftComponentReference
- **关联项:** [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();
}
```