/** * Applies settings to an object by finding UProperties by name and calling ImportText * * @param InObject - The object to search for matching properties * @param PropertyChain - The list UProperty names recursively to search through * @param Value - The value to import on the found property */ void ApplyCustomFactorySetting(UObject* InObject, TArray<FString>& PropertyChain, const FString& Value) { const FString PropertyName = PropertyChain[0]; PropertyChain.RemoveAt(0); UProperty* TargetProperty = FindField<UProperty>(InObject->GetClass(), *PropertyName); if (TargetProperty) { if (PropertyChain.Num() == 0) { TargetProperty->ImportText(*Value, TargetProperty->ContainerPtrToValuePtr<uint8>(InObject), 0, InObject); } else { UStructProperty* StructProperty = Cast<UStructProperty>(TargetProperty); UObjectProperty* ObjectProperty = Cast<UObjectProperty>(TargetProperty); UObject* SubObject = NULL; bool bValidPropertyType = true; if (StructProperty) { SubObject = StructProperty->Struct; } else if (ObjectProperty) { SubObject = ObjectProperty->GetObjectPropertyValue(ObjectProperty->ContainerPtrToValuePtr<UObject>(InObject)); } else { //Unknown nested object type bValidPropertyType = false; UE_LOG(LogAutomationEditorCommon, Error, TEXT("ERROR: Unknown nested object type for property: %s"), *PropertyName); } if (SubObject) { ApplyCustomFactorySetting(SubObject, PropertyChain, Value); } else if (bValidPropertyType) { UE_LOG(LogAutomationEditorCommon, Error, TEXT("Error accessing null property: %s"), *PropertyName); } } } else { UE_LOG(LogAutomationEditorCommon, Error, TEXT("ERROR: Could not find factory property: %s"), *PropertyName); } }
void GetEditableComponents( const AActor* InActor, TArray<UActorComponent*>& OutEditableComponents ) { for( TFieldIterator<UObjectProperty> PropIt(InActor->GetClass(), EFieldIteratorFlags::IncludeSuper); PropIt; ++PropIt ) { UObjectProperty* ObjectProp = *PropIt; if( ObjectProp->HasAnyPropertyFlags(CPF_Edit) ) { UObject* ObjPtr = ObjectProp->GetObjectPropertyValue(ObjectProp->ContainerPtrToValuePtr<void>(InActor)); if( ObjPtr && ObjPtr->IsA<UActorComponent>() ) { OutEditableComponents.Add( CastChecked<UActorComponent>( ObjPtr ) ); } } } }
FComponentVisualizer::FPropertyNameAndIndex FComponentVisualizer::GetComponentPropertyName(const UActorComponent* Component) { if (Component) { const AActor* CompOwner = Component->GetOwner(); if (CompOwner) { // Iterate over UObject* fields of this actor UClass* ActorClass = CompOwner->GetClass(); for (TFieldIterator<UObjectProperty> It(ActorClass); It; ++It) { // See if this property points to the component in question UObjectProperty* ObjectProp = *It; for (int32 Index = 0; Index < ObjectProp->ArrayDim; ++Index) { UObject* Object = ObjectProp->GetObjectPropertyValue(ObjectProp->ContainerPtrToValuePtr<void>(CompOwner, Index)); if (Object == Component) { // It does! Return this name return FPropertyNameAndIndex(ObjectProp->GetFName(), Index); } } } // If nothing found, look in TArray<UObject*> fields for (TFieldIterator<UArrayProperty> It(ActorClass); It; ++It) { UArrayProperty* ArrayProp = *It; if (UObjectProperty* InnerProp = Cast<UObjectProperty>(It->Inner)) { FScriptArrayHelper ArrayHelper(ArrayProp, ArrayProp->ContainerPtrToValuePtr<void>(CompOwner)); for (int32 Index = 0; Index < ArrayHelper.Num(); ++Index) { UObject* Object = InnerProp->GetObjectPropertyValue(ArrayHelper.GetRawPtr(Index)); if (Object == Component) { return FPropertyNameAndIndex(ArrayProp->GetFName(), Index); } } } } } } // Didn't find actor property referencing this component return FPropertyNameAndIndex(); }
FName FComponentEditorUtils::FindVariableNameGivenComponentInstance(UActorComponent* ComponentInstance) { check(ComponentInstance != nullptr); // First see if the name just works if (AActor* OwnerActor = ComponentInstance->GetOwner()) { UClass* OwnerActorClass = OwnerActor->GetClass(); if (UObjectProperty* TestProperty = FindField<UObjectProperty>(OwnerActorClass, ComponentInstance->GetFName())) { if (ComponentInstance->GetClass()->IsChildOf(TestProperty->PropertyClass)) { return TestProperty->GetFName(); } } } // Name mismatch, try finding a differently named variable pointing to the the component (the mismatch should only be possible for native components) if (UActorComponent* Archetype = Cast<UActorComponent>(ComponentInstance->GetArchetype())) { if (AActor* OwnerActor = Archetype->GetOwner()) { UClass* OwnerClass = OwnerActor->GetClass(); AActor* OwnerCDO = CastChecked<AActor>(OwnerClass->GetDefaultObject()); check(OwnerCDO->HasAnyFlags(RF_ClassDefaultObject)); for (TFieldIterator<UObjectProperty> PropIt(OwnerClass, EFieldIteratorFlags::IncludeSuper); PropIt; ++PropIt) { UObjectProperty* TestProperty = *PropIt; if (Archetype->GetClass()->IsChildOf(TestProperty->PropertyClass)) { void* TestPropertyInstanceAddress = TestProperty->ContainerPtrToValuePtr<void>(OwnerCDO); UObject* ObjectPointedToByProperty = TestProperty->GetObjectPropertyValue(TestPropertyInstanceAddress); if (ObjectPointedToByProperty == Archetype) { // This property points to the component archetype, so it's an anchor even if it was named wrong return TestProperty->GetFName(); } } } } } return NAME_None; }
void FAnimBlueprintNodeOptionalPinManager::PostInitNewPin(UEdGraphPin* Pin, FOptionalPinFromProperty& Record, int32 ArrayIndex, UProperty* Property, uint8* PropertyAddress) const { check(PropertyAddress != NULL); check(Record.bShowPin); if (OldPins == NULL) { // Initial construction of a visible pin; copy values from the struct FBlueprintEditorUtils::ExportPropertyToKismetDefaultValue(Pin, Property, PropertyAddress, BaseNode); } else if (Record.bCanToggleVisibility) { if (UEdGraphPin* OldPin = OldPinMap.FindRef(Pin->PinName)) { // Was already visible } else { // Showing a pin that was previously hidden, during a reconstruction UObjectProperty* ObjectProperty = Cast<UObjectProperty>(Property); UAnimGraphNode_AssetPlayerBase* AssetPlayerNode = Cast<UAnimGraphNode_AssetPlayerBase>(BaseNode); const bool bIsAnimationAsset = AssetPlayerNode != nullptr && ObjectProperty != nullptr && ObjectProperty->PropertyClass->IsChildOf<UAnimationAsset>(); // Store the old reference to an animation asset in the node's asset reference if (bIsAnimationAsset) { AssetPlayerNode->SetAssetReferenceForPinRestoration(ObjectProperty->GetObjectPropertyValue(PropertyAddress)); } // Convert the struct property into DefaultValue/DefaultValueObject FBlueprintEditorUtils::ExportPropertyToKismetDefaultValue(Pin, Property, PropertyAddress, BaseNode); // clear the asset reference on the node if (bIsAnimationAsset) { ObjectProperty->SetObjectPropertyValue(PropertyAddress, nullptr); } } } }