void FPropertyEditor::SyncToObjectsInNode( const TWeakPtr< FPropertyNode >& WeakPropertyNode ) { #if WITH_EDITOR if ( !GUnrealEd ) { return; } TSharedPtr< FPropertyNode > PropertyNode = WeakPropertyNode.Pin(); check(PropertyNode.IsValid()); UProperty* NodeProperty = PropertyNode->GetProperty(); UObjectPropertyBase* ObjectProperty = Cast<UObjectPropertyBase>( NodeProperty ); UInterfaceProperty* IntProp = Cast<UInterfaceProperty>( NodeProperty ); { UClass* PropertyClass = UObject::StaticClass(); if( ObjectProperty ) { PropertyClass = ObjectProperty->PropertyClass; } else if( IntProp ) { PropertyClass = IntProp->InterfaceClass; } // Get a list of addresses for objects handled by the property window. FReadAddressList ReadAddresses; PropertyNode->GetReadAddress( !!PropertyNode->HasNodeFlags(EPropertyNodeFlags::SingleSelectOnly), ReadAddresses, false ); // GetReadAddresses will only provide a list of addresses if the property was properly formed, objects were selected, and only one object was selected if the node has the SingleSelectOnly flag. // If a list of addresses is provided, GetReadAddress may still return false but we can operate on the property addresses even if they have different values. check( ReadAddresses.Num() > 0 ); // Create a list of object names. TArray<FString> ObjectNames; ObjectNames.Empty( ReadAddresses.Num() ); // Copy each object's object property name off into the name list. for ( int32 AddrIndex = 0 ; AddrIndex < ReadAddresses.Num() ; ++AddrIndex ) { new( ObjectNames ) FString(); uint8* Address = ReadAddresses.GetAddress(AddrIndex); if( Address ) { NodeProperty->ExportText_Direct(ObjectNames[AddrIndex], Address, Address, NULL, PPF_Localized ); } } // Create a list of objects to sync the generic browser to. TArray<UObject*> Objects; for ( int32 ObjectIndex = 0 ; ObjectIndex < ObjectNames.Num() ; ++ObjectIndex ) { UObject* Package = ANY_PACKAGE; if( ObjectNames[ObjectIndex].Contains( TEXT(".")) ) { // Formatted text string, use the exact path instead of any package Package = NULL; } UObject* Object = StaticFindObject( PropertyClass, Package, *ObjectNames[ObjectIndex] ); if( !Object && Package != ANY_PACKAGE ) { Object = StaticLoadObject(PropertyClass, Package, *ObjectNames[ObjectIndex]); } if ( Object ) { // If the selected object is a blueprint generated class, then browsing to it in the content browser should instead point to the blueprint // Note: This code needs to change once classes are the top level asset in the content browser and/or blueprint classes are displayed in the content browser if (UClass* ObjectAsClass = Cast<UClass>(Object)) { if (ObjectAsClass->ClassGeneratedBy != NULL) { Object = ObjectAsClass->ClassGeneratedBy; } } Objects.Add( Object ); } } // If a single actor is selected, sync to its location in the level editor viewport instead of the content browser. if( Objects.Num() == 1 && Objects[0]->IsA(AActor::StaticClass()) ) { TArray<AActor*> Actors; Actors.Add(Cast<AActor>(Objects[0])); GEditor->SelectNone(/*bNoteSelectionChange=*/false, /*bDeselectBSPSurfs=*/true); GEditor->SelectActor(Actors[0], /*InSelected=*/true, /*bNotify=*/true, /*bSelectEvenIfHidden=*/true); // Jump to the location of the actor GEditor->MoveViewportCamerasToActor( Actors, /*bActiveViewportOnly=*/false ); } else if ( Objects.Num() > 0 ) { GEditor->SyncBrowserToObjects(Objects); } } #endif }