示例#1
0
void UUnrealEdEngine::NoteSelectionChange()
{
	// The selection changed, so make sure the pivot (widget) is located in the right place
	UpdatePivotLocationForSelection( true );

	// Clear active editing visualizer on selection change
	GUnrealEd->ComponentVisManager.ClearActiveComponentVis();

	TArray<FEdMode*> ActiveModes;
	GLevelEditorModeTools().GetActiveModes( ActiveModes );
	for( int32 ModeIndex = 0; ModeIndex < ActiveModes.Num(); ++ModeIndex )
	{
		ActiveModes[ModeIndex]->ActorSelectionChangeNotify();
	}

	const bool bComponentSelectionChanged = GetSelectedComponentCount() > 0;
	USelection* Selection = bComponentSelectionChanged ? GetSelectedComponents() : GetSelectedActors();
	USelection::SelectionChangedEvent.Broadcast(Selection);
	
	if (!bComponentSelectionChanged)
	{
		//whenever selection changes, recompute whether the selection contains a locked actor
		bCheckForLockActors = true;

		//whenever selection changes, recompute whether the selection contains a world info actor
		bCheckForWorldSettingsActors = true;

		UpdateFloatingPropertyWindows();
	}

	RedrawLevelEditingViewports();
}
示例#2
0
bool UUnrealEdEngine::IsComponentSelected(const UPrimitiveComponent* PrimComponent)
{
	bool bIsSelected = false;
	if (GetSelectedComponentCount() > 0)
	{
		bIsSelected = GetSelectedComponents()->IsSelected(PrimComponent->IsEditorOnly() ? PrimComponent->AttachParent : PrimComponent);
	}

	return bIsSelected;
}
示例#3
0
void UUnrealEdEngine::SelectComponent(UActorComponent* Component, bool bInSelected, bool bNotify, bool bSelectEvenIfHidden)
{
	// Don't do any work if the component's selection state matches the target selection state
	const bool bComponentSelected = GetSelectedComponents()->IsSelected(Component);
	if (( bComponentSelected && !bInSelected ) || ( !bComponentSelected && bInSelected ))
	{
		if (bInSelected)
		{
			UE_LOG(LogEditorSelectUtils, Verbose, TEXT("Selected Component: %s"), *Component->GetClass()->GetName());
		}
		else
		{
			UE_LOG(LogEditorSelectUtils, Verbose, TEXT("Deselected Component: %s"), *Component->GetClass()->GetName());
		}

		GetSelectedComponents()->Select(Component, bInSelected);

		// Make sure the override delegate is bound properly
		auto SceneComponent = Cast<USceneComponent>(Component);
		if (SceneComponent)
		{
			FComponentEditorUtils::BindComponentSelectionOverride(SceneComponent, true);
		}

		// Update the selection visualization
		AActor* ComponentOwner = Component->GetOwner();
		if (ComponentOwner != nullptr)
		{
			TInlineComponentArray<UPrimitiveComponent*> PrimitiveComponents;
			ComponentOwner->GetComponents(PrimitiveComponents);

			for (int32 Idx = 0; Idx < PrimitiveComponents.Num(); ++Idx)
			{
				PrimitiveComponents[Idx]->PushSelectionToProxy();
			}
		}

		if (bNotify)
		{
			NoteSelectionChange();
		}
	}
}
示例#4
0
	void EditorSelection::OnHierarchyListSelectionChange(const PODVector<UIElement*>& items, const PODVector<unsigned>& indices)
	{
		ClearSelection();

		for (unsigned int i = 0; i < indices.Size(); ++i)
		{
			unsigned int index = indices[i];
			UIElement* item = items[index];
			int type = item->GetVar(TYPE_VAR).GetInt();
			if (type == ITEM_COMPONENT)
			{
				Component* comp = editor_->GetListComponent(item);

				AddSelectedComponent(comp);
			}
			else if (type == ITEM_NODE)
			{
				Node* node = editor_->GetListNode(item);

				AddSelectedNode(node);
			}
			else if (type == ITEM_UI_ELEMENT)
			{
				UIElement* element = editor_->GetListUIElement(item);
				AddSelectedUIElement(element);
			}
		}

		// If only one node/UIElement selected, use it for editing
		if (GetNumSelectedNodes() == 1)
			editNode_ = selectedNodes_[0];

		
		if (GetNumSelectedUIElements() == 1)
			editUIElement_ = selectedUIElements_[0];
		

		// If selection contains only components, and they have a common node, use it for editing
		if (selectedNodes_.Empty() && !selectedComponents_.Empty())
		{
			Node* commonNode = NULL;
			for (unsigned int i = 0; i < GetNumSelectedComponents(); ++i)
			{
				if (i == 0)
					commonNode = GetSelectedComponents()[i]->GetNode();
				else
				{
					if (selectedComponents_[i]->GetNode() != commonNode)
						commonNode = NULL;
				}
			}
			editNode_ = commonNode;
		}

		// Now check if the component(s) can be edited. If many selected, must have same type or have same edit node
		if (!selectedComponents_.Empty())
		{
			if (editNode_ == NULL)
			{
				StringHash compType = selectedComponents_[0]->GetType();
				bool sameType = true;
				for (unsigned int i = 1; i < GetNumSelectedComponents(); ++i)
				{
					if (selectedComponents_[i]->GetType() != compType)
					{
						sameType = false;
						break;
					}
				}
				if (sameType)
					editComponents_ = selectedComponents_;
			}
			else
			{
				editComponents_ = selectedComponents_;
				numEditableComponentsPerNode_ = GetNumSelectedComponents();
			}
		}

		// If just nodes selected, and no components, show as many matching components for editing as possible
		if (!selectedNodes_.Empty() && selectedComponents_.Empty() && selectedNodes_[0]->GetNumComponents() > 0)
		{
			unsigned int count = 0;
			for (unsigned int j = 0; j < selectedNodes_[0]->GetNumComponents(); ++j)
			{
				StringHash compType = selectedNodes_[0]->GetComponents()[j]->GetType();
				bool sameType = true;
				for (unsigned int i = 1; i < GetNumSelectedNodes(); ++i)
				{
					if (selectedNodes_[i]->GetNumComponents() <= j || selectedNodes_[i]->GetComponents()[j]->GetType() != compType)
					{
						sameType = false;
						break;
					}
				}

				if (sameType)
				{
					++count;
					for (unsigned int i = 0; i < GetNumSelectedNodes(); ++i)
						AddEditComponent(selectedNodes_[i]->GetComponents()[j]);
				}
			}
			if (count > 1)
				numEditableComponentsPerNode_ = count;
		}

		if (selectedNodes_.Empty() && editNode_ != NULL)
			AddEditNode(editNode_);
		else
		{
			editNodes_ = selectedNodes_;

			// Cannot multi-edit on scene and node(s) together as scene and node do not share identical attributes,
			// editing via gizmo does not make too much sense either
			if (editNodes_.Size() > 1 && editNodes_[0] == editor_->GetScene())
				editNodes_.Erase(0);
		}

		if (selectedUIElements_.Empty() && editUIElement_ != NULL)
			AddEditUIElement(editUIElement_);
		else
			editUIElements_ = selectedUIElements_;


	}
示例#5
0
void UUnrealEdEngine::SelectActor(AActor* Actor, bool bInSelected, bool bNotify, bool bSelectEvenIfHidden, bool bForceRefresh)
{
	const bool bWarnIfLevelLocked = true;
	if( !CanSelectActor( Actor, bInSelected, bSelectEvenIfHidden, bWarnIfLevelLocked ) )
	{
		return;
	}

	bool bSelectionHandled = false;

	TArray<FEdMode*> ActiveModes;
	GLevelEditorModeTools().GetActiveModes( ActiveModes );
	for( int32 ModeIndex = 0; ModeIndex < ActiveModes.Num(); ++ModeIndex )
	{
		bSelectionHandled |= ActiveModes[ModeIndex]->Select( Actor, bInSelected );
	}

	// Select the actor and update its internals.
	if( !bSelectionHandled )
	{
		if(bInSelected)
		{
			// If trying to select an Actor spawned by a ChildACtorComponent, instead select Actor that spawned us
			if(Actor->ParentComponentActor.IsValid())
			{
				Actor = Actor->ParentComponentActor.Get();
			}
		}

		if (GEditor->bGroupingActive)
		{
			// if this actor is a group, do a group select/deselect
			AGroupActor* SelectedGroupActor = Cast<AGroupActor>(Actor);
			if (SelectedGroupActor)
			{
				SelectGroup(SelectedGroupActor, true, bInSelected, bNotify);
			}
			else
			{
				// Select/Deselect this actor's entire group, starting from the top locked group.
				// If none is found, just use the actor.
				AGroupActor* ActorLockedRootGroup = AGroupActor::GetRootForActor(Actor, true);
				if (ActorLockedRootGroup)
				{
					SelectGroup(ActorLockedRootGroup, false, bInSelected, bNotify);
				}
			}
		}

		// Don't do any work if the actor's selection state is already the selected state.
		const bool bActorSelected = Actor->IsSelected();
		if ( (bActorSelected && !bInSelected) || (!bActorSelected && bInSelected) )
		{
			if(bInSelected)
			{
				UE_LOG(LogEditorSelectUtils, Verbose,  TEXT("Selected Actor: %s"), *Actor->GetClass()->GetName());
			}
			else
			{
				UE_LOG(LogEditorSelectUtils, Verbose,  TEXT("Deselected Actor: %s"), *Actor->GetClass()->GetName() );
			}

			GetSelectedActors()->Select( Actor, bInSelected );
			if (!bInSelected)
			{
				if (GetSelectedComponentCount() > 0)
				{
					GetSelectedComponents()->Modify();
				}

				for (UActorComponent* Component : Actor->GetComponents())
				{
					GetSelectedComponents()->Deselect( Component );

					// Remove the selection override delegates from the deselected components
					auto SceneComponent = Cast<USceneComponent>(Component);
					FComponentEditorUtils::BindComponentSelectionOverride(SceneComponent, false);
				}
			}
			else
			{
				// Bind the override delegates for the components in the selected actor
				for (UActorComponent* Component : Actor->GetComponents())
				{
					auto SceneComponent = Cast<USceneComponent>(Component);
					FComponentEditorUtils::BindComponentSelectionOverride(SceneComponent, true);
				}
			}

			//A fast path to mark selection rather than reconnecting ALL components for ALL actors that have changed state
			SetActorSelectionFlags (Actor);

			if( bNotify )
			{
				NoteSelectionChange();
			}

			//whenever selection changes, recompute whether the selection contains a locked actor
			bCheckForLockActors = true;

			//whenever selection changes, recompute whether the selection contains a world info actor
			bCheckForWorldSettingsActors = true;
		}
		else
		{
			if (bNotify || bForceRefresh)
			{
				//reset the property windows.  In case something has changed since previous selection
				UpdateFloatingPropertyWindows(bForceRefresh);
			}
		}
	}
}
示例#6
0
void UUnrealEdEngine::UpdatePivotLocationForSelection( bool bOnChange )
{
	// Pick a new common pivot, or not.
	AActor* SingleActor = nullptr;
	USceneComponent* SingleComponent = nullptr;

	if (GetSelectedComponentCount() > 0)
	{
		for (FSelectedEditableComponentIterator It(*GetSelectedComponents()); It; ++It)
		{
			UActorComponent* Component = CastChecked<UActorComponent>(*It);
			AActor* ComponentOwner = Component->GetOwner();

			if (ComponentOwner != nullptr)
			{
				auto SelectedActors = GetSelectedActors();
				const bool bIsOwnerSelected = SelectedActors->IsSelected(ComponentOwner);
				check(bIsOwnerSelected);

				if (ComponentOwner->GetWorld() == GWorld)
				{
					SingleActor = ComponentOwner;
					if (Component->IsA<USceneComponent>())
					{
						SingleComponent = CastChecked<USceneComponent>(Component);
					}

					const bool IsTemplate = ComponentOwner->IsTemplate();
					const bool LevelLocked = !FLevelUtils::IsLevelLocked(ComponentOwner->GetLevel());
					check(IsTemplate || LevelLocked);
				}
			}
		}
	}
	else
	{
		for (FSelectionIterator It(GetSelectedActorIterator()); It; ++It)
		{
			AActor* Actor = static_cast<AActor*>(*It);
			checkSlow(Actor->IsA(AActor::StaticClass()));

			if (Actor->GetWorld() == GWorld)
			{
				const bool IsTemplate = Actor->IsTemplate();
				const bool LevelLocked = !FLevelUtils::IsLevelLocked(Actor->GetLevel());
				check(IsTemplate || LevelLocked);

				SingleActor = Actor;
			}
		}
	}
	
	if (SingleComponent != NULL)
	{
		SetPivot(SingleComponent->GetComponentLocation(), false, true);
	}
	else if( SingleActor != NULL ) 
	{		
		// For geometry mode use current pivot location as it's set to selected face, not actor
		FEditorModeTools& Tools = GLevelEditorModeTools();
		if( Tools.IsModeActive(FBuiltinEditorModes::EM_Geometry) == false || bOnChange == true )
		{
			// Set pivot point to the actor's location
			FVector PivotPoint = SingleActor->GetActorLocation();

			// If grouping is active, see if this actor is part of a locked group and use that pivot instead
			if(GEditor->bGroupingActive)
			{
				AGroupActor* ActorGroupRoot = AGroupActor::GetRootForActor(SingleActor, true, true);
				if(ActorGroupRoot)
				{
					PivotPoint = ActorGroupRoot->GetActorLocation();
				}
			}
			SetPivot( PivotPoint, false, true );
		}
	}
	else
	{
		ResetPivot();
	}
}