Esempio n. 1
0
void AActor::PreEditUndo()
{
	// Since child actor components will rebuild themselves get rid of the Actor before we make changes
	TInlineComponentArray<UChildActorComponent*> ChildActorComponents;
	GetComponents(ChildActorComponents);

	for (UChildActorComponent* ChildActorComponent : ChildActorComponents)
	{
		if (ChildActorComponent->IsCreatedByConstructionScript())
		{
			ChildActorComponent->DestroyChildActor();
		}
	}

	// let navigation system know to not care about this actor anymore
	UNavigationSystem::ClearNavOctreeAll(this);

	Super::PreEditUndo();
}
Esempio n. 2
0
 static unsigned BuildNativeDeclaration(
     D3D11_SO_DECLARATION_ENTRY nativeDeclaration[], unsigned nativeDeclarationCount,
     const GeometryShader::StreamOutputInitializers& soInitializers)
 {
     auto finalCount = std::min(nativeDeclarationCount, soInitializers._outputElementCount);
     for (unsigned c=0; c<finalCount; ++c) {
         auto& ele = soInitializers._outputElements[c];
         nativeDeclaration[c].Stream = 0;
         nativeDeclaration[c].SemanticName = ele._semanticName.c_str();
         nativeDeclaration[c].SemanticIndex = ele._semanticIndex;
         nativeDeclaration[c].StartComponent = 0;
         nativeDeclaration[c].ComponentCount = (BYTE)GetComponentCount(GetComponents(ele._nativeFormat));
             // hack -- treat "R16G16B16A16_FLOAT" as a 3 dimensional vector
         if (ele._nativeFormat == NativeFormat::Enum::R16G16B16A16_FLOAT)
             nativeDeclaration[c].ComponentCount = 3;
         nativeDeclaration[c].OutputSlot = (BYTE)ele._inputSlot;
         assert(nativeDeclaration[c].OutputSlot < soInitializers._outputBufferCount);
     }
     return finalCount;
 }
Esempio n. 3
0
//-------------------------------------------------------------
// Task    : Append a subdirectory 2 path's directory
//-------------------------------------------------------------
void CPath::AppendDirectory(const char * lpszSubDirectory)
{
    std::string	Drive;
    std::string	Directory;
    std::string	SubDirectory =lpszSubDirectory;
    std::string	Name;
    std::string	Extension;

    if(SubDirectory.empty())
        return;

    // Strip out any preceeding backslash
    StripLeadingBackslash(SubDirectory);
    EnsureTrailingBackslash(SubDirectory);

    GetComponents(&Drive,&Directory,&Name,&Extension);
    EnsureTrailingBackslash(Directory);
    Directory +=SubDirectory;

    SetComponents(Drive.c_str(),Directory.c_str(),Name.c_str(),Extension.c_str());
}
//* Destroys the constructed components.
void AActor::DestroyConstructedComponents()
{
	// Remove all existing components
	TArray<UActorComponent*> PreviouslyAttachedComponents;
	GetComponents(PreviouslyAttachedComponents);
	for (int32 i = 0; i < PreviouslyAttachedComponents.Num(); i++)
	{
		UActorComponent*& Component = PreviouslyAttachedComponents[i];
		if (Component && Component->bCreatedByConstructionScript)
		{
			if (Component == RootComponent)
			{
				RootComponent = NULL;
			}

			Component->DestroyComponent();

			// Rename component to avoid naming conflicts in the case where we rerun the SCS and name the new components the same way.
			FName const NewBaseName( *(FString::Printf(TEXT("TRASH_%s"), *Component->GetClass()->GetName())) );
			FName const NewObjectName = MakeUniqueObjectName(this, GetClass(), NewBaseName);
			Component->Rename(*NewObjectName.ToString(), this, REN_ForceNoResetLoaders);
		}
	}
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeSingleIndexedComponent::Add( const CDmeSingleIndexedComponent &rhs )
{
	int nLhs = Count();
	const int nRhs = rhs.Count();

	int l = 0;
	int r = 0;

	if ( IsComplete() )
	{
		if ( rhs.IsComplete() && nRhs > nLhs )
		{
			m_CompleteCount.Set( nRhs );
		}
		else
		{
			while ( r < nRhs )
			{
				if ( rhs.m_Components[ r ] >= nLhs )
				{
					// Got one that's greater than the complete count of this one

					CUtlVector< int > newComponents;
					newComponents.EnsureCapacity( nLhs + nRhs - r );

					CUtlVector< float > newWeights;
					newWeights.EnsureCapacity( nLhs  + nRhs - r );

					GetComponents( newComponents, newWeights );

					while ( r < nRhs )
					{
						newComponents.AddToTail( rhs.m_Components[ r ] );
						newWeights.AddToTail( rhs.m_Weights[ r ] );
						++r;
					}

					m_Components.CopyArray( newComponents.Base(), newComponents.Count() );
					m_Weights.CopyArray( newWeights.Base(), newWeights.Count() );

					m_CompleteCount.Set( 0 );
					m_bComplete.Set( false );

					break;
				}

				++r;
			}
		}
	}
	else
	{
		CUtlVector< int > newComponents;
		newComponents.EnsureCapacity( nLhs + nRhs * 0.5 );	// Just an estimate assuming 50% of the components in rhs aren't in lhs
		CUtlVector< float > newWeights;
		newWeights.EnsureCapacity( nLhs  + nRhs * 0.5 );	// Just an estimate

		while ( l < nLhs || r < nRhs )
		{
			while ( l < nLhs && ( r >= nRhs || m_Components[ l ] < rhs.m_Components[ r ] ) )
			{
				newComponents.AddToTail( m_Components[ l ] );
				newWeights.AddToTail( m_Weights[ l ] );
				++l;
			}

			// In RHS but not LHS
			while ( r < nRhs && ( l >= nLhs || m_Components[ l ] > rhs.m_Components[ r ] ) )
			{
				newComponents.AddToTail( rhs.m_Components[ r ] );
				newWeights.AddToTail( rhs.m_Weights[ r ] );
				++r;
			}

			// In Both LHS & RHS
			while ( l < nLhs && r < nRhs && m_Components[ l ] == rhs.m_Components[ r ] )
			{
				newComponents.AddToTail( m_Components[ l ] );
				newWeights.AddToTail( m_Weights[ l ] );
				++l;
				++r;
			}
		}

		m_Components.CopyArray( newComponents.Base(), newComponents.Count() );
		m_Weights.CopyArray( newWeights.Base(), newWeights.Count() );
	}

	m_CompleteCount.Set( 0 );
	m_bComplete.Set( false );
}
Esempio n. 6
0
void AActor::ExecuteConstruction(const FTransform& Transform, const FComponentInstanceDataCache* InstanceDataCache, bool bIsDefaultTransform)
{
	check(!IsPendingKill());
	check(!HasAnyFlags(RF_BeginDestroyed|RF_FinishDestroyed));

	// ensure that any existing native root component gets this new transform
	// we can skip this in the default case as the given transform will be the root component's transform
	if (RootComponent && !bIsDefaultTransform)
	{
		RootComponent->SetWorldTransform(Transform);
	}

	// Generate the parent blueprint hierarchy for this actor, so we can run all the construction scripts sequentially
	TArray<const UBlueprintGeneratedClass*> ParentBPClassStack;
	const bool bErrorFree = UBlueprintGeneratedClass::GetGeneratedClassesHierarchy(GetClass(), ParentBPClassStack);

	// If this actor has a blueprint lineage, go ahead and run the construction scripts from least derived to most
	if( (ParentBPClassStack.Num() > 0)  )
	{
		if( bErrorFree )
		{
			// Prevent user from spawning actors in User Construction Script
			TGuardValue<bool> AutoRestoreISCS(GetWorld()->bIsRunningConstructionScript, true);
			for( int32 i = ParentBPClassStack.Num() - 1; i >= 0; i-- )
			{
				const UBlueprintGeneratedClass* CurrentBPGClass = ParentBPClassStack[i];
				check(CurrentBPGClass);
				if(CurrentBPGClass->SimpleConstructionScript)
				{
					CurrentBPGClass->SimpleConstructionScript->ExecuteScriptOnActor(this, Transform, bIsDefaultTransform);
				}
				// Now that the construction scripts have been run, we can create timelines and hook them up
				CurrentBPGClass->CreateComponentsForActor(this);
			}

			// If we passed in cached data, we apply it now, so that the UserConstructionScript can use the updated values
			if(InstanceDataCache)
			{
				InstanceDataCache->ApplyToActor(this, ECacheApplyPhase::PostSimpleConstructionScript);
			}

#if WITH_EDITOR
			bool bDoUserConstructionScript;
			GConfig->GetBool(TEXT("Kismet"), TEXT("bTurnOffEditorConstructionScript"), bDoUserConstructionScript, GEngineIni);
			if (!GIsEditor || !bDoUserConstructionScript)
#endif
			{
				// Then run the user script, which is responsible for calling its own super, if desired
				ProcessUserConstructionScript();
			}

			// Since re-run construction scripts will never be run and we want to keep dynamic spawning fast, don't spend time
			// determining the UCS modified properties in game worlds
			if (!GetWorld()->IsGameWorld())
			{
				for (UActorComponent* Component : GetComponents())
				{
					if (Component)
					{
						Component->DetermineUCSModifiedProperties();
					}
				}
			}

			// Bind any delegates on components			
			((UBlueprintGeneratedClass*)GetClass())->BindDynamicDelegates(this); // We have a BP stack, we must have a UBlueprintGeneratedClass...

			// Apply any cached data procedural components
			// @TODO Don't re-apply to components we already applied to above
			if (InstanceDataCache)
			{
				InstanceDataCache->ApplyToActor(this, ECacheApplyPhase::PostUserConstructionScript);
			}
		}
		else
		{
			// Disaster recovery mode; create a dummy billboard component to retain the actor location
			// until the compile error can be fixed
			if (RootComponent == NULL)
			{
				UBillboardComponent* BillboardComponent = NewObject<UBillboardComponent>(this);
				BillboardComponent->SetFlags(RF_Transactional);
				BillboardComponent->CreationMethod = EComponentCreationMethod::SimpleConstructionScript;
#if WITH_EDITOR
				BillboardComponent->Sprite = (UTexture2D*)(StaticLoadObject(UTexture2D::StaticClass(), NULL, TEXT("/Engine/EditorResources/BadBlueprintSprite.BadBlueprintSprite"), NULL, LOAD_None, NULL));
#endif
				BillboardComponent->SetRelativeTransform(Transform);

				SetRootComponent(BillboardComponent);
				FinishAndRegisterComponent(BillboardComponent);
			}
		}
	}

	GetWorld()->UpdateCullDistanceVolumes(this);

	// Now run virtual notification
	OnConstruction(Transform);
}
Esempio n. 7
0
void AActor::RerunConstructionScripts()
{
	checkf(!HasAnyFlags(RF_ClassDefaultObject), TEXT("RerunConstructionScripts should never be called on a CDO as it can mutate the transient data on the CDO which then propagates to instances!"));

	FEditorScriptExecutionGuard ScriptGuard;
	// don't allow (re)running construction scripts on dying actors
	bool bAllowReconstruction = !IsPendingKill() && !HasAnyFlags(RF_BeginDestroyed|RF_FinishDestroyed);
#if WITH_EDITOR
	if(bAllowReconstruction && GIsEditor)
	{
		// Generate the blueprint hierarchy for this actor
		TArray<UBlueprint*> ParentBPStack;
		bAllowReconstruction = UBlueprint::GetBlueprintHierarchyFromClass(GetClass(), ParentBPStack);
		if(bAllowReconstruction)
		{
			for(int i = ParentBPStack.Num() - 1; i > 0 && bAllowReconstruction; --i)
			{
				const UBlueprint* ParentBP = ParentBPStack[i];
				if(ParentBP && ParentBP->bBeingCompiled)
				{
					// don't allow (re)running construction scripts if a parent BP is being compiled
					bAllowReconstruction = false;
				}
			}
		}
	}
#endif
	if(bAllowReconstruction)
	{
		// Set global flag to let system know we are reconstructing blueprint instances
		TGuardValue<bool> GuardTemplateNameFlag(GIsReconstructingBlueprintInstances, true);

		// Temporarily suspend the undo buffer; we don't need to record reconstructed component objects into the current transaction
		ITransaction* CurrentTransaction = GUndo;
		GUndo = NULL;
		
		// Create cache to store component data across rerunning construction scripts
#if WITH_EDITOR
		FActorTransactionAnnotation* ActorTransactionAnnotation = CurrentTransactionAnnotation.Get();
#endif
		FComponentInstanceDataCache* InstanceDataCache;
		
		FTransform OldTransform = FTransform::Identity;
		FName  SocketName;
		AActor* Parent = NULL;
		USceneComponent* ParentComponent = NULL;

		bool bUseRootComponentProperties = true;

		// Struct to store info about attached actors
		struct FAttachedActorInfo
		{
			AActor* AttachedActor;
			FName AttachedToSocket;
			bool bSetRelativeTransform;
			FTransform RelativeTransform;
		};

		// Save info about attached actors
		TArray<FAttachedActorInfo> AttachedActorInfos;

#if WITH_EDITOR
		if (ActorTransactionAnnotation)
		{
			InstanceDataCache = &ActorTransactionAnnotation->ComponentInstanceData;

			if (ActorTransactionAnnotation->bRootComponentDataCached)
			{
				OldTransform = ActorTransactionAnnotation->RootComponentData.Transform;
				Parent = ActorTransactionAnnotation->RootComponentData.AttachedParentInfo.Actor.Get();
				if (Parent)
				{
					USceneComponent* AttachParent = ActorTransactionAnnotation->RootComponentData.AttachedParentInfo.AttachParent.Get();
					ParentComponent = (AttachParent ? AttachParent : FindObjectFast<USceneComponent>(Parent, ActorTransactionAnnotation->RootComponentData.AttachedParentInfo.AttachParentName));
					SocketName = ActorTransactionAnnotation->RootComponentData.AttachedParentInfo.SocketName;
					DetachRootComponentFromParent();
				}

				for (const auto& CachedAttachInfo : ActorTransactionAnnotation->RootComponentData.AttachedToInfo)
				{
					AActor* AttachedActor = CachedAttachInfo.Actor.Get();
					if (AttachedActor)
					{
						FAttachedActorInfo Info;
						Info.AttachedActor = AttachedActor;
						Info.AttachedToSocket = CachedAttachInfo.SocketName;
						Info.bSetRelativeTransform = true;
						Info.RelativeTransform = CachedAttachInfo.RelativeTransform;
						AttachedActorInfos.Add(Info);

						AttachedActor->DetachRootComponentFromParent();
					}
				}

				bUseRootComponentProperties = false;
			}
		}
		else
#endif
		{
			InstanceDataCache = new FComponentInstanceDataCache(this);

			// If there are attached objects detach them and store the socket names
			TArray<AActor*> AttachedActors;
			GetAttachedActors(AttachedActors);

			for (AActor* AttachedActor : AttachedActors)
			{
				USceneComponent* EachRoot = AttachedActor->GetRootComponent();
				// If the component we are attached to is about to go away...
				if (EachRoot && EachRoot->AttachParent && EachRoot->AttachParent->IsCreatedByConstructionScript())
				{
					// Save info about actor to reattach
					FAttachedActorInfo Info;
					Info.AttachedActor = AttachedActor;
					Info.AttachedToSocket = EachRoot->AttachSocketName;
					Info.bSetRelativeTransform = false;
					AttachedActorInfos.Add(Info);

					// Now detach it
					AttachedActor->Modify();
					EachRoot->DetachFromParent(true);
				}
			}
		}

		if (bUseRootComponentProperties && RootComponent != nullptr)
		{
			// Do not need to detach if root component is not going away
			if (RootComponent->AttachParent != NULL && RootComponent->IsCreatedByConstructionScript())
			{
				Parent = RootComponent->AttachParent->GetOwner();
				// Root component should never be attached to another component in the same actor!
				if (Parent == this)
				{
					UE_LOG(LogActor, Warning, TEXT("RerunConstructionScripts: RootComponent (%s) attached to another component in this Actor (%s)."), *RootComponent->GetPathName(), *Parent->GetPathName());
					Parent = NULL;
				}
				ParentComponent = RootComponent->AttachParent;
				SocketName = RootComponent->AttachSocketName;
				//detach it to remove any scaling 
				RootComponent->DetachFromParent(true);
			}

			OldTransform = RootComponent->ComponentToWorld;
			OldTransform.SetTranslation(RootComponent->GetComponentLocation()); // take into account any custom location
		}

#if WITH_EDITOR
		// Save the current construction script-created components by name
		TMap<const FName, UObject*> DestroyedComponentsByName;
		TInlineComponentArray<UActorComponent*> PreviouslyAttachedComponents;
		GetComponents(PreviouslyAttachedComponents);
		for (auto Component : PreviouslyAttachedComponents)
		{
			if (Component)
			{
				if (Component->IsCreatedByConstructionScript())
				{

					DestroyedComponentsByName.Add(Component->GetFName(), Component);
				}
				else
				{
					UActorComponent* OuterComponent = Component->GetTypedOuter<UActorComponent>();
					while (OuterComponent)
					{
						if (OuterComponent->IsCreatedByConstructionScript())
						{
							DestroyedComponentsByName.Add(Component->GetFName(), Component);
							break;
						}
						OuterComponent = OuterComponent->GetTypedOuter<UActorComponent>();
					}
				}
			}
		}
#endif

		// Destroy existing components
		DestroyConstructedComponents();

		// Reset random streams
		ResetPropertiesForConstruction();

		// Exchange net roles before running construction scripts
		UWorld *OwningWorld = GetWorld();
		if (OwningWorld && !OwningWorld->IsServer())
		{
			ExchangeNetRoles(true);
		}

		// Run the construction scripts
		ExecuteConstruction(OldTransform, InstanceDataCache);

		if(Parent)
		{
			USceneComponent* ChildRoot = GetRootComponent();
			if (ParentComponent == NULL)
			{
				ParentComponent = Parent->GetRootComponent();
			}
			if (ChildRoot != NULL && ParentComponent != NULL)
			{
				ChildRoot->AttachTo(ParentComponent, SocketName, EAttachLocation::KeepWorldPosition);
			}
		}

		// If we had attached children reattach them now - unless they are already attached
		for(FAttachedActorInfo& Info : AttachedActorInfos)
		{
			// If this actor is no longer attached to anything, reattach
			if (!Info.AttachedActor->IsPendingKill() && Info.AttachedActor->GetAttachParentActor() == NULL)
			{
				USceneComponent* ChildRoot = Info.AttachedActor->GetRootComponent();
				if (ChildRoot && ChildRoot->AttachParent != RootComponent)
				{
					ChildRoot->AttachTo(RootComponent, Info.AttachedToSocket, EAttachLocation::KeepWorldPosition);
					if (Info.bSetRelativeTransform)
					{
						ChildRoot->SetRelativeTransform(Info.RelativeTransform);
					}
					ChildRoot->UpdateComponentToWorld();
				}
			}
		}

		// Restore the undo buffer
		GUndo = CurrentTransaction;

#if WITH_EDITOR
		// Create the mapping of old->new components and notify the editor of the replacements
		TMap<UObject*, UObject*> OldToNewComponentMapping;

		TInlineComponentArray<UActorComponent*> NewComponents;
		GetComponents(NewComponents);
		for (auto NewComp : NewComponents)
		{
			const FName NewCompName = NewComp->GetFName();
			if (DestroyedComponentsByName.Contains(NewCompName))
			{
				OldToNewComponentMapping.Add(DestroyedComponentsByName[NewCompName], NewComp);
			}
		}

		if (GEditor && (OldToNewComponentMapping.Num() > 0))
		{
			GEditor->NotifyToolsOfObjectReplacement(OldToNewComponentMapping);
		}

		if (ActorTransactionAnnotation)
		{
			CurrentTransactionAnnotation = NULL;
		}
		else
#endif
		{
			delete InstanceDataCache;
		}

	}
}
void ADebugCameraHUD::PostRender()
{
	Super::PostRender();

	if (bShowHUD)
	{
		ADebugCameraController* DCC = Cast<ADebugCameraController>( PlayerOwner );
		UFont* RenderFont = GEngine->GetSmallFont();
		if( DCC != NULL )
		{
			FFontRenderInfo FontRenderInfo = Canvas->CreateFontRenderInfo(false, true);

			Canvas->SetDrawColor(64, 64, 255, 255);
			FString MyText = TEXT("Debug Camera");
			float xl, yl;
			Canvas->StrLen(RenderFont, MyText, xl, yl);
			float X = Canvas->SizeX * 0.05f;
			float Y = yl;//*1.67;
			yl += 2*Y;
			Canvas->DrawText(RenderFont, MyText, X, yl, 1.f, 1.f, FontRenderInfo);

			Canvas->SetDrawColor(200, 200, 128, 255);

			FVector const CamLoc = DCC->PlayerCameraManager->GetCameraLocation();
			FRotator const CamRot = DCC->PlayerCameraManager->GetCameraRotation();
			float const CamFOV = DCC->PlayerCameraManager->GetFOVAngle();

			yl += Y;
			
			FString const LocRotString = FString::Printf(TEXT("Loc=(%.1f, %.1f, %.1f) Rot=(%.1f, %.1f, %.1f)"), CamLoc.X, CamLoc.Y, CamLoc.Z, CamRot.Pitch, CamRot.Yaw, CamRot.Roll);
			Canvas->DrawText(RenderFont, LocRotString, X, yl, 1.f, 1.f, FontRenderInfo);
			yl += Y;
			
			FString const FOVString = FString::Printf(TEXT("HFOV=%.1f"), CamFOV);
			Canvas->DrawText(RenderFont, FOVString, X, yl, 1.f, 1.f, FontRenderInfo);
			yl += Y;
			
			FString const SpeedScaleString = FString::Printf(TEXT("SpeedScale=%.2fx"), DCC->SpeedScale);
			Canvas->DrawText(RenderFont, SpeedScaleString, X, yl, 1.f, 1.f, FontRenderInfo);
			yl += Y;
			
			FString const SpeedString = FString::Printf(TEXT("MaxSpeed=%.1f"), DCC->GetSpectatorPawn() && DCC->GetSpectatorPawn()->GetMovementComponent() ? DCC->GetSpectatorPawn()->GetMovementComponent()->GetMaxSpeed() : 0.f);
			Canvas->DrawText(RenderFont, SpeedString, X, yl, 1.f, 1.f, FontRenderInfo);
			yl += Y;

			//Canvas->DrawText(FString::Printf(TEXT("CamLoc:%s CamRot:%s"), *CamLoc.ToString(), *CamRot.ToString() ));

			const TCHAR* CVarComplexName = TEXT("g.DebugCameraTraceComplex");
			bool bTraceComplex = true;

#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
			bTraceComplex = CVarDebugCameraTraceComplex.GetValueOnGameThread() != 0;
#endif

			FCollisionQueryParams TraceParams(NAME_None, bTraceComplex, this);
			FHitResult Hit;
			bool bHit = GetWorld()->LineTraceSingleByChannel(Hit, CamLoc, CamRot.Vector() * 100000.f + CamLoc, ECC_Pawn, TraceParams);

			yl += Y;
			Canvas->DrawText(RenderFont, FString::Printf(TEXT("Trace info (%s = %d):"), CVarComplexName, bTraceComplex ? 1 : 0), X, yl, 1.f, 1.f, FontRenderInfo);

			if( bHit )
			{
				AActor* HitActor = Hit.GetActor();
				yl += Y;
				Canvas->DrawText(RenderFont, FString::Printf(TEXT("HitLoc:%s HitNorm:%s"), *Hit.Location.ToString(), *Hit.Normal.ToString() ), X, yl, 1.f, 1.f, FontRenderInfo);
				yl += Y;
				Canvas->DrawText(RenderFont, FString::Printf(TEXT("HitDist: %f"), Hit.Distance), X, yl, 1.f, 1.f, FontRenderInfo);
				yl += Y;
				Canvas->DrawText(RenderFont, FString::Printf(TEXT("HitActor: '%s'"), HitActor ? *HitActor->GetFName().ToString() : TEXT("<NULL>")), X, yl, 1.f, 1.f, FontRenderInfo);
				yl += Y;
				Canvas->DrawText(RenderFont, FString::Printf(TEXT("HitComponent: '%s'"), Hit.Component.Get() ? *Hit.Component.Get()->GetFName().ToString() : TEXT("<NULL>")), X, yl, 1.f, 1.f, FontRenderInfo);
				yl += Y;
				Canvas->DrawText(RenderFont, FString::Printf(TEXT("HitActor Class: '%s'"), HitActor && HitActor->GetClass() ? *HitActor->GetClass()->GetName() : TEXT("<Not Found>") ), X, yl, 1.f, 1.f, FontRenderInfo);
				yl += Y;
				Canvas->DrawText(RenderFont, FString::Printf(TEXT("HitActorPath: '%s'"), HitActor ? *HitActor->GetPathName() : TEXT("<Not Found>")), X, yl, 1.f, 1.f, FontRenderInfo);
				yl += Y;

				bool bFoundMaterial = false;
				if ( Hit.Component != NULL )
				{
					bFoundMaterial = DisplayMaterials( X, yl, Y, Cast<UMeshComponent>(Hit.Component.Get()) );
				}
				else
				{
					TInlineComponentArray<UMeshComponent*> Components;
					GetComponents(Components);

					for ( int32 i=0; i<Components.Num(); i++ )
					{
						UMeshComponent* MeshComp = Components[i];
						if ( MeshComp->IsRegistered() )
						{
							bFoundMaterial = bFoundMaterial || DisplayMaterials( X, yl, Y, MeshComp );	
						}
					}
				}
				if ( bFoundMaterial == false )
				{
					yl += Y;
					Canvas->DrawText(RenderFont, "Material: NULL", X + Y, yl, 1.f, 1.f, FontRenderInfo );
				}
				DrawDebugLine( GetWorld(), Hit.Location, Hit.Location+Hit.Normal*30.f, FColor::White );
			}
			else
			{
				yl += Y;
				Canvas->DrawText( RenderFont, TEXT("No trace Hit"), X, yl, 1.f, 1.f, FontRenderInfo);
			}

			if ( DCC->bShowSelectedInfo && DCC->SelectedActor != NULL )
			{
				yl += Y;
				Canvas->DrawText(RenderFont,  FString::Printf(TEXT("Selected actor: '%s'"), *DCC->SelectedActor->GetFName().ToString()), X, yl, 1.f, 1.f, FontRenderInfo);
				DisplayMaterials( X, yl, Y, Cast<UMeshComponent>(DCC->SelectedComponent) );
			}


			// controls display
			yl += Y*15;
			
			Canvas->SetDrawColor(64, 64, 255, 255);
			Canvas->DrawText(RenderFont, TEXT("Controls"), X, yl, 1.f, 1.f, FontRenderInfo);
			yl += Y;
			
			Canvas->SetDrawColor(200, 200, 128, 255);
			Canvas->DrawText(RenderFont, TEXT("FOV +/-: ,/. or DPad Up/Down"), X, yl, 1.f, 1.f, FontRenderInfo);
			yl += Y;
			
			Canvas->DrawText(RenderFont, TEXT("Speed +/-: MouseWheel or +/- or LB/RB"), X, yl, 1.f, 1.f, FontRenderInfo);
			yl += Y;
			
			Canvas->DrawText(RenderFont, TEXT("Freeze Rendering: F or YButton"), X, yl, 1.f, 1.f, FontRenderInfo);
			yl += Y;			
			
			Canvas->DrawText(RenderFont, TEXT("Toggle Display: BackSpace or XButton"), X, yl, 1.f, 1.f, FontRenderInfo);
			yl += Y;
		}
	}
}
void AActor::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
	UProperty* PropertyThatChanged = PropertyChangedEvent.Property;
	FName PropertyName = PropertyThatChanged != NULL ? PropertyThatChanged->GetFName() : NAME_None;
	
	const bool bTransformationChanged = (PropertyName == Name_RelativeLocation || PropertyName == Name_RelativeRotation || PropertyName == Name_RelativeScale3D);

	// During SIE, allow components to reregistered and reconstructed in PostEditChangeProperty.
	// This is essential as construction is deferred during spawning / duplication when in SIE.
	if ((GEditor && GEditor->bIsSimulatingInEditor) || ReregisterComponentsWhenModified())
	{
		// In the Undo case we have an annotation storing information about constructed components and we do not want
		// to improperly apply out of date changes so we need to skip registration of all blueprint created components
		// and defer instance components attached to them until after rerun
		if (CurrentTransactionAnnotation.IsValid())
		{
			UnregisterAllComponents();

			TInlineComponentArray<UActorComponent*> Components;
			GetComponents(Components);

			Components.Sort([](UActorComponent& A, UActorComponent& B)
			{
				if (&B == B.GetOwner()->GetRootComponent())
				{
					return false;
				}
				if (USceneComponent* ASC = Cast<USceneComponent>(&A))
				{
					if (ASC->GetAttachParent() == &B)
					{
						return false;
					}
				}
				return true;
			});

			bool bRequiresReregister = false;
			for (UActorComponent* Component : Components)
			{
				if (Component->CreationMethod == EComponentCreationMethod::Native)
				{
					Component->RegisterComponent();
				}
				else if (Component->CreationMethod == EComponentCreationMethod::Instance)
				{
					USceneComponent* SC = Cast<USceneComponent>(Component);
					if (SC == nullptr || SC == RootComponent || (SC->GetAttachParent() && SC->GetAttachParent()->IsRegistered()))
					{
						Component->RegisterComponent();
					}
					else
					{
						bRequiresReregister = true;
					}
				}
				else
				{
					bRequiresReregister = true;
				}
			}

			RerunConstructionScripts();

			if (bRequiresReregister)
			{
				ReregisterAllComponents();
			}
		}
		else
		{
			UnregisterAllComponents();
			RerunConstructionScripts();
			ReregisterAllComponents();
		}
	}

	// Let other systems know that an actor was moved
	if (bTransformationChanged)
	{
		GEngine->BroadcastOnActorMoved( this );
	}

	if (GetWorld())
	{
		GetWorld()->bDoDelayedUpdateCullDistanceVolumes = true;
	}

	FEditorSupportDelegates::UpdateUI.Broadcast();
	Super::PostEditChangeProperty(PropertyChangedEvent);
}
Esempio n. 10
0
std::string CPath::GetExtension(void) const
{
    std::string rExtension;
    GetComponents(NULL,NULL,NULL,&rExtension);
    return rExtension;
}
Esempio n. 11
0
//-------------------------------------------------------------
// Task    : Get file extension from path
//-------------------------------------------------------------
void CPath::GetExtension(std::string& rExtension) const
{
    GetComponents(NULL,NULL,NULL,&rExtension);
}
Esempio n. 12
0
std::string CPath::GetName(void) const
{
    std::string rName;
    GetComponents(NULL,NULL,&rName);
    return rName;
}
Esempio n. 13
0
//-------------------------------------------------------------
// Task    : Get filename from path
//-------------------------------------------------------------
void CPath::GetName(std::string& rName) const
{
    GetComponents(NULL,NULL,&rName);
}
Esempio n. 14
0
std::string CPath::GetDirectory(void) const
{
    std::string rDirectory;
    GetComponents(NULL,&rDirectory);
    return rDirectory;
}
Esempio n. 15
0
//-------------------------------------------------------------
// Task    : Get directory from path
//-------------------------------------------------------------
void CPath::GetDirectory(std::string& rDirectory) const
{
    GetComponents(NULL,&rDirectory);
}
void ACameraRig_Rail::UpdatePreviewMeshes()
{
	if (RailSplineComponent)
	{
		if (PreviewRailStaticMesh)
		{
			int32 const NumSplinePoints = RailSplineComponent->GetNumberOfSplinePoints();
			int32 const NumNeededPreviewMeshes = NumSplinePoints - 1;

			// make sure our preview mesh array is correctly sized and populated
			{
				int32 const NumExistingPreviewMeshes = PreviewRailMeshSegments.Num();
				if (NumExistingPreviewMeshes > NumNeededPreviewMeshes)
				{
					// we have too many meshes, remove some
					int32 const NumToRemove = NumExistingPreviewMeshes - NumNeededPreviewMeshes;
					for (int Idx = 0; Idx < NumToRemove; ++Idx)
					{
						USplineMeshComponent* const ElementToRemove = PreviewRailMeshSegments.Pop();
						ElementToRemove->UnregisterComponent();
					}
				}
				else if (NumExistingPreviewMeshes < NumNeededPreviewMeshes)
				{
					int32 const NumToAdd = NumNeededPreviewMeshes - NumExistingPreviewMeshes;

					for (int32 Idx = 0; Idx < NumToAdd; ++Idx)
					{
						USplineMeshComponent* PreviewMesh = CreateSplinePreviewSegment();
						PreviewRailMeshSegments.Add(PreviewMesh);
					}
				}
				check(PreviewRailMeshSegments.Num() == NumNeededPreviewMeshes);
			}

			for (int PtIdx = 0; PtIdx < NumSplinePoints - 1; ++PtIdx)
			{
				FVector StartLoc, StartTangent, EndLoc, EndTangent;
				RailSplineComponent->GetLocationAndTangentAtSplinePoint(PtIdx, StartLoc, StartTangent, ESplineCoordinateSpace::Local);
				RailSplineComponent->GetLocationAndTangentAtSplinePoint(PtIdx + 1, EndLoc, EndTangent, ESplineCoordinateSpace::Local);

				USplineMeshComponent* const SplineMeshComp = PreviewRailMeshSegments[PtIdx];
				if (SplineMeshComp)
				{
					SplineMeshComp->SetForwardAxis(ESplineMeshAxis::Z);
					SplineMeshComp->SetStartAndEnd(StartLoc, StartTangent, EndLoc, EndTangent, true);
				}
			}

			// Unregister any owned components that aren't in PreviewRailMeshSegments
			TArray<USplineMeshComponent*> OwnedSplineMeshComponents;
			GetComponents(OwnedSplineMeshComponents);
			for (auto OwnedComponent : OwnedSplineMeshComponents)
			{
				if (!PreviewRailMeshSegments.Contains(OwnedComponent))
				{
					OwnedComponent->UnregisterComponent();
				}
			}
		}

		// make visualization of the mount follow the contour of the rail
		if (PreviewMesh_Mount)
		{
			float const SplineLen = RailSplineComponent->GetSplineLength();
			FQuat const RailRot = RailSplineComponent->GetQuaternionAtDistanceAlongSpline(CurrentPositionOnRail*SplineLen, ESplineCoordinateSpace::World);
			PreviewMesh_Mount->SetWorldRotation(RailRot);
		}
	}
}