UE_LOG, unable to print an FName from FAnimMontageInstance

Hi,

I am starting on UE4, and I am getting crazy trying to log an FName value, for the life of me I cannot get my code to compile : /

void UMyComponent::BeginPlay()
{
	Super::BeginPlay();

	//Register component
	skeletalComponent = (Cast<USkeletalMeshComponent>(GetOwner()->GetComponentByClass(USkeletalMeshComponent::StaticClass())));

}
    
// Called every frame
void UMyComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

	UE_LOG(LogTemp, Warning, TEXT("Time fraction %f"), *(*skeletalComponent->GetAnimInstance()->GetActiveMontageInstance()->GetNextSection()));

}

I try moving the * pointer, using .ToString()… nothing works, I get either LNK2019 errors, or C2100 errors… the code provided gives the following error:

error C2100: illegal indirection

The skeletalComponent has been declared like this in my .h:

USkeletalMeshComponent* skeletalComponent;

If anyone can help me, I am really stuck…

You’d write an FName to a log like so:

FName MyName;
UE_LOG(LogTemp, Warning, TEXT("My Name: %s"), *MyName.ToString());

Please note that you need to use %s for printing out a string of characters, rather than %f which you’re using in your example above. http://www.cplusplus.com/reference/cstdio/printf/

9 Likes

Wow, thanks a lot for you quick answer. I missed this one, but sadly I still get issues, I tried:

UE_LOG(LogTemp, Warning, TEXT("Time fraction %s"), *skeletalComponent->GetAnimInstance()->GetActiveMontageInstance()->GetNextSection().ToString());

Which gives me:

error LNK2019: unresolved external
symbol "public: class FName __cdecl
FAnimMontageInstance::GetNextSection(void)const
"
(?GetNextSection@FAnimMontageInstance@@QEBA?AVFName@@XZ)
referenced in function “public:
virtual void __cdecl
UTimeReversableSkeletonComponent::TickComponent(float,enum
ELevelTick,struct
FActorComponentTickFunction *)”
(?TickComponent@UTimeReversableSkeletonComponent@@UEAAXMW4ELevelTick@@PEAUFActorComponentTickFunction@@@Z)

I also tried:

UE_LOG(LogTemp, Warning, TEXT("Time fraction %s"), *(*skeletalComponent->GetAnimInstance()->GetActiveMontageInstance()->GetNextSection()).ToString());

Which gives:

error C2100: illegal indirection

I know my pointer knowledge is not good, but I am trying to wrap my head around what is not working here and still no luck : /

It seems that GetNextSection isn’t actually exposed from FAnimMontageInstance (neither FAnimMontageInstance nor GetNextSection are marked with ENGINE_API), which is why you get a linker error when you try and use it.

I don’t know why that type would be so badly exposed given that it’s public, I’ll defer that question to the team who owns it… regardless, there’s nothing you can do about that linker error unless you’re using a source build?

I do not really know what a “source build” is, basically I am trying to get information about the current animation running on a skeleton, something like:

  • Current Animation
  • Target Animation
  • Step it is at between Current & Target

My aim is to be able to store the current “form” of the skeleton to rebuild it in this exact state at a later point in time. These information in the FAnimMontageInstance seemed to be what I was looking for, but then maybe there is another way to get that in C++?

FWIW, a “source build” is where you are building your own engine from GitHub source code, rather than a project via the launcher. This gives you the opportunity to modify engine source and add pull requests so we can take your source modifications and integrate them into the engine for others to use.

As mentioned by Jamie above, those functions in FAnimMontageInstance are not exposed to other modules via the ENGINE_API macro, so are only usable inside of the Engine module itself at the moment.

It sounds like you are trying to record the blend state of a UAnimInstance to then play it back at some later point, possibly in reverse (your naming your component “UTimeReversableSkeletonComponent” seems to suggest that)?

For the moment I can suggest a few possible avenues of investigation:

  • If you are happy with a lot of data being recorded, just capture the bone state of the skeleton each frame (the space bases) and replay that later on somehow, possibly using some custom animation node, or some UAnimInstance-derived class.
  • Add ENGINE_API to the functions you need to expose and build your own engine. If this gets you what you need then fine, although capturing all the data could prove tricky depending on how your animation graph is set up (as its not just montages that can affect your skeletal mesh).

I think I will try to go the first route. You are correct in what I am trying to do: store the “pose” of a skeleton and later, when time has been reversed, replay it from this pose at the stored time, and relaunch the animation it was in at this moment.

I think storing the bone state would work, but it looks to be heavy… and I would like to “rewind” back as much as possible so I am trying to optimize early :slight_smile:

Currently I am looking at extending UAnimInstance and reparent it in editor, to see if I can catch when the animation changes somehow.

I will try to avoid compiling my own source engine, since I have only just started working on UE4, I do not want to go overkill so soon :slight_smile:

Thanks a lot for your answers