void UChildActorComponent::DestroyChildActor()
{
	// If we own an Actor, kill it now unless we don't have authority on it, for that we rely on the server
	// If the level that the child actor is being removed then don't destory the child actor so re-adding it doesn't
	// need to create a new actor
	if (ChildActor && ChildActor->HasAuthority() && !GetOwner()->GetLevel()->bIsBeingRemoved)
	{
		if (!GExitPurge)
		{
			// if still alive, destroy, otherwise just clear the pointer
			if (!ChildActor->IsPendingKillOrUnreachable())
			{
#if WITH_EDITOR
				if (CachedInstanceData)
				{
					delete CachedInstanceData;
					CachedInstanceData = nullptr;
				}
#else
				check(!CachedInstanceData);
#endif
				// If we're already tearing down we won't be needing this
				if (!HasAnyFlags(RF_BeginDestroyed) && !IsUnreachable())
				{
					CachedInstanceData = new FChildActorComponentInstanceData(this);
				}

				UWorld* World = ChildActor->GetWorld();
				// World may be nullptr during shutdown
				if (World != nullptr)
				{
					UClass* ChildClass = ChildActor->GetClass();

					// We would like to make certain that our name is not going to accidentally get taken from us while we're destroyed
					// so we increment ClassUnique beyond our index to be certain of it.  This is ... a bit hacky.
					int32& ClassUnique = ChildActor->GetOutermost()->ClassUniqueNameIndexMap.FindOrAdd(ChildClass->GetFName());
					ClassUnique = FMath::Max(ClassUnique, ChildActor->GetFName().GetNumber());

					// If we are getting here due to garbage collection we can't rename, so we'll have to abandon this child actor name and pick up a new one
					if (!IsGarbageCollecting())
					{
						const FString ObjectBaseName = FString::Printf(TEXT("DESTROYED_%s_CHILDACTOR"), *ChildClass->GetName());
						const ERenameFlags RenameFlags = ((GetWorld()->IsGameWorld() || IsLoading()) ? REN_DoNotDirty | REN_ForceNoResetLoaders : REN_DoNotDirty);
						ChildActor->Rename(*MakeUniqueObjectName(ChildActor->GetOuter(), ChildClass, *ObjectBaseName).ToString(), nullptr, RenameFlags);
					}
					else
					{
						ChildActorName = NAME_None;
						if (CachedInstanceData)
						{
							CachedInstanceData->ChildActorName = NAME_None;
						}
					}
					World->DestroyActor(ChildActor);
				}
			}
		}

		ChildActor = nullptr;
	}
}
FPropertyAccess::Result SPropertyEditorAsset::GetValue( FObjectOrAssetData& OutValue ) const
{
	// Potentially accessing the value while garbage collecting or saving the package could trigger a crash.
	// so we fail to get the value when that is occuring.
	if ( GIsSavingPackage || IsGarbageCollecting() )
	{
		return FPropertyAccess::Fail;
	}

	FPropertyAccess::Result Result = FPropertyAccess::Fail;

	if( PropertyEditor.IsValid() && PropertyEditor->GetPropertyHandle()->IsValidHandle() )
	{
		UObject* Object = NULL;
		Result = PropertyEditor->GetPropertyHandle()->GetValue(Object);

		if (Object == NULL)
		{
			// Check to see if it's pointing to an unloaded object
			FString CurrentObjectPath;
			PropertyEditor->GetPropertyHandle()->GetValueAsFormattedString( CurrentObjectPath );

			if (CurrentObjectPath.Len() > 0 && CurrentObjectPath != TEXT("None"))
			{
				if( !CachedAssetData.IsValid() || CachedAssetData.ObjectPath.ToString() != CurrentObjectPath )
				{
					static FName AssetRegistryName("AssetRegistry");

					FAssetRegistryModule& AssetRegistryModule = FModuleManager::Get().LoadModuleChecked<FAssetRegistryModule>(AssetRegistryName);
					CachedAssetData = AssetRegistryModule.Get().GetAssetByObjectPath( *CurrentObjectPath );
				}

				Result = FPropertyAccess::Success;
				OutValue = FObjectOrAssetData( CachedAssetData );

				return Result;
			}
		}

		OutValue = FObjectOrAssetData( Object );
	}
	else
	{
		UObject* Object = NULL;
		if (PropertyHandle.IsValid())
		{
			Result = PropertyHandle->GetValue(Object);
		}

		if (Object != NULL)
		{
			OutValue = FObjectOrAssetData(Object);
		}
		else
		{
			const FString CurrentObjectPath = ObjectPath.Get();
			Result = FPropertyAccess::Success;

			if (CurrentObjectPath != TEXT("None") && (!CachedAssetData.IsValid() || CachedAssetData.ObjectPath.ToString() != CurrentObjectPath))
			{
				static FName AssetRegistryName("AssetRegistry");

				FAssetRegistryModule& AssetRegistryModule = FModuleManager::Get().LoadModuleChecked<FAssetRegistryModule>(AssetRegistryName);
				CachedAssetData = AssetRegistryModule.Get().GetAssetByObjectPath(*CurrentObjectPath);

				if (PropertyHandle.IsValid())
				{
					// No property editor was specified so check if multiple property values are associated with the property handle
					TArray<FString> ObjectValues;
					PropertyHandle->GetPerObjectValues(ObjectValues);

					if (ObjectValues.Num() > 1)
					{
						for (int32 ObjectIndex = 1; ObjectIndex < ObjectValues.Num() && Result == FPropertyAccess::Success; ++ObjectIndex)
						{
							if (ObjectValues[ObjectIndex] != ObjectValues[0])
							{
								Result = FPropertyAccess::MultipleValues;
							}
						}
					}
				}
			}
			else if (CurrentObjectPath == TEXT("None"))
			{
				CachedAssetData = FAssetData();
			}

			OutValue = FObjectOrAssetData(CachedAssetData);
		}
	}

	return Result;
}