Trying to access function from another actor using Nvidia WaveWorks. Compiles Successfully but crashes on play

Hello. I am pretty new to the C++ side of Unreal, but I’ve been trying hard to learn it.

I have an Nvidia WaveWorks build integrated into my UE4, and have been trying to adjust the source code to work more for what I am trying to accomplish. By default WaveWorks buoyancy works with static meshes, but not actors or blueprints that have static mesh components. I have a boat actor that houses a static mesh and a function to return that static mesh.

I have been attempting to access the uStaticMeshComponent of my boat inside of the WaveWorksFloatingComponent.cpp in order to pass it into the BuoyancyBodyComponent and calculate its buoyancy. I created a function with an object iterator in the WaveWorksFloatingComponent that is supposed to access the function that returns the uStaticMeshComponent. I thought I had maybe finally figured out the correct solution because everything compiles successfully, but unfortunately crashes without log when trying to play or simulate. I am thinking my logic with object iterator might be off as I don’t 100% understand it.

Any help, whether its logic fixing or troubleshooting, is greatly appreciated. Thank you.

This is my boat actor and its components. (MyActor.cpp)

 AMyActor::AMyActor()
    {
     	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    	PrimaryActorTick.bCanEverTick = true;
    	Root = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
    	RootComponent = Root;
    
    	Mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
    	Mesh->AttachTo(Root);
    }
    UStaticMeshComponent* AMyActor::GetSM()
    {
    	return Mesh;
    }

Here are functions and properties in header (MyActor.h)

UPROPERTY()
		USceneComponent* Root;

	UPROPERTY(EditAnywhere)
		UStaticMeshComponent* Mesh;

	UFUNCTION()
		UStaticMeshComponent* GetSM();

This is function I am using to try to access GetSM() from MyActor. (WaveWorksFloatingComponent.cpp)

void UWaveWorksFloatingComponent::AccessFunction()
{
	for (TObjectIterator<AMyActor> Itr; Itr; ++Itr)
	{
		if (Itr->IsA(AMyActor::StaticClass()))
		{
			AMyActor* actorClass = *Itr;
			actorClass->GetSM();
		}
	}
}

Here is where I am using that function. The commented out section was the original code. (WaveWorksFloatingComponent.cpp)

if (nullptr != WaveWorksActor)
	{
		WaveWorksComponent = Cast<UWaveWorksComponent>(WaveWorksActor->GetComponentByClass(UWaveWorksComponent::StaticClass()));
		WaveWorksStaticMeshComponent = Cast<UWaveWorksStaticMeshComponent>(WaveWorksActor->GetComponentByClass(UWaveWorksStaticMeshComponent::StaticClass()));
		WaveWorksRecieveDisplacementDelegate = FWaveWorksSampleDisplacementsDelegate::CreateUObject(this, &UWaveWorksFloatingComponent::OnRecievedWaveWorksDisplacements);

		AccessFunction();
		BuoyancyBodyComponent = Mesh;

		//BuoyancyBodyComponent = Cast<UStaticMeshComponent>(GetOwner()->GetComponentByClass(UStaticMeshComponent::StaticClass()));

And here is the AccessFunction() in header. (WaveWorksFloatingComponent.h)

UFUNCTION()
		void AccessFunction();

And the variables in header. (WaveWorksFloatingComponent.h)

	class UStaticMeshComponent* BuoyancyBodyComponent;
	class UStaticMeshComponent* Mesh;

I am 99% sure the problem is isolated in the above code, but if you think I am leaving a relevant code snippet out please tell me. Again, any help is greatly appreciated. Thank you.

edit1: left out variables for WWFC header.

Hi OtherBarry717,

Based on the code you provided, it looks like your AccessFunction isn’t returning anything, so you’re not actually returning the mesh tied to your actor. You should return the UStaticMesh from AccessFunction so you can say “BuoyancyBodyComponent = AccessFunction();” in WaveWorksFloatingComponent.

Hey DarkwindRichard, thanks for answering. So should my AccessFunction look more like this

UStaticMeshComponent UWaveWorksFloatingComponent::AccessFunction()
{
	for (TObjectIterator<AMyActor> Itr; Itr; ++Itr)
	{
		if (Itr->IsA(AMyActor::StaticClass()))
		{
			AMyActor* actorClass = *Itr;
			actorClass->GetSM();
		}
	}
}

Hi OtherBarry717,

You should be returning the static mesh component if found, so line 8 in that snippet should be return actorClass->GetSM();. You should also return nullptr at the end to denote that a mesh component was not found

Hi OtherBarry717,

You don’t want to return nullptr immediately if the first actor you find isn’t an AMyActor instance because then you won’t be able to check any other actors. The error message is also caused by doing that: you’re technically not returning anything if the loop doesn’t execute at all. Here is that your function should look like:

UStaticMeshComponent* UWaveWorksFloatingComponent::AccessFunction()
{
    for (TObjectIterator<AMyActor> Itr; Itr; ++Itr)
    {
        AMyActor* actorClass = *Itr;
        // Potentially do some kind of check to see if "actorClass" is actually the instance you want
        return actorClass->GetSM();
    }
    return nullptr;
}

Hey DarkwindRichard, Thank you for fixing my logic and showing me how to properly use the TObjectIterator. Everything successfully compiles, but now I am back to the crashing without a crash log when I press play.

Not sure how much help this is but here is a pastebin link to the waveworksTester.log from the minute it crashed: crash log

Hi OtherBarry717,

Try switching your configuration to be DebugGame Editor (instead of Development Editor) and then launch it from Visual Studio with the debugger attached (defaults to F5). When the crash occurs, it should jump to the line in your source that is causing it. If the crash occurs somewhere in the engine source and you’re getting a message about symbols not found, you might need to edit your engine installation to include the engine debug symbols.

Hey DarkwindRichard, Thanks for all the help, I figured out the problem and editor is working again, however it seems the method I am trying to use is not quite compatible with what I need to be accomplishing. I think its time for another ask thread. Regardless, I appreciate all the help and tips. I have learned a ton trying this.

Hey DarkwindRichard, thanks again for the reply. Sorry I have not been more prompt with this reply, it has been a busy week.

UStaticMeshComponent* UWaveWorksFloatingComponent::AccessFunction()
{
	for (TObjectIterator<AMyActor> Itr; Itr; ++Itr)
	{
		if (Itr->IsA(AMyActor::StaticClass()))
		{
			AMyActor* actorClass = *Itr;
				return actorClass->GetSM();
		}
		else
		{
			return nullptr;
		}
		break;
	}
}

This is where I am currently at, but I am now running into this compile error:
waveworksfloatingcomponent.cpp(214) : error C4715: ‘UWaveWorksFloatingComponent::AccessFunction’: not all control paths return a value.
Which I think means there is an error in my logic and an exception is possible?

Thanks again for taking the time to assist me.

Hi OtherBarry717,

Not a problem, happy to help!