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;
}