4.12 Transition Guide

Dear Community,

Yay it is that happy time again!

This is a thread where you can post compile errors you’ve solved during 4.12 upgrade, issues you have questions about regarding 4.12, and generally share anything you’re learning as you do the upgrade process!

I contributed this BP nodes which you can check out the C++ for in the relevant classes:

Actor Functions

Was Recently Rendered: Extremely powerful node to let you perform game code optimizations based on whether you know the actor is being rendered, or has been rendered recently. Actors that have not been rendered for awhile can stop running functionality that is important, but not if the actor has been out of view for a long time!



bool AActor::WasRecentlyRendered(float Tolerance) const
{  
	UWorld* World = GetWorld();
	return (World) ? World->GetTimeSeconds() - GetLastRenderTime() <= Tolerance : false;
}


Get Time Since Creation: This is very useful for actors that you create during runtime and want to know how long they’ve been around for! Their runtime-lifetime basically :slight_smile:



float AActor::GetGameTimeSinceCreation()
{
	if(GetWorld() != nullptr)
	{
		return GetWorld()->GetTimeSeconds() - CreationTime;		
	}
	// return 0.f if GetWorld return's null
	else
	{
		return 0.f;
	}
}


:heart:

Rama

New Way To Attach Components

Dear Community,

In 4.12, in EngineTypes.h



/** Rules for attaching components */
struct ENGINE_API FAttachmentTransformRules
{
	/** Various preset attachment rules. Note that these default rules do NOT by default weld simulated bodies */
	static FAttachmentTransformRules KeepRelativeTransform;
	static FAttachmentTransformRules KeepWorldTransform;
	static FAttachmentTransformRules SnapToTargetNotIncludingScale;
	static FAttachmentTransformRules SnapToTargetIncludingScale;

	//.... (legal)
	
	/** Whether to weld simulated bodies together when attaching */
	bool bWeldSimulatedBodies;
};


So now you could specify to attach and keep world position like this:



YourComp->AttachToComponent(OtherComp, FAttachmentTransformRules::KeepWorldTransform)


instead of this:



YourComp->AttachToComponent(OtherComp, NAME_None, EAttachLocation::KeepWorldPosition)



**This Change is Great!**

**One great thing about this change** is the order of parameters has changed to prioritize the attach rule over the socket name, which was usually NAME_None for me anyway, that's why the 4.12 version only has 2 parameters in my use case!

Yay!

Thank you Epic!

Rama

Did something change with the AddDynamic() macro? I have a project in 4.11 where I use something like this:


Component->OnComponentBeginOverlap.AddDynamic(this, &MyClass::ComponentOnOverlapBegin);

It works just fine. I converted it to 4.12 and compiling fails with the error “no instance of function template “FComponentBeginOverlapSignature::__Internal_AddDynamic” matches the argument list”

After looking at the compiler errors, it seems like the signature has changed. I switch mine to


OverlapFunction(class UPrimitiveComponent* ThisComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult &SweepResult)

where the first item is the new one, and represents the component that is detecting the overlap. Now it works with no issue.

They changed the signature:

The quote is about Actors but clearly Epic did the same at the component level, because the logic is the same. The idea is that the component who is broadcasting the event is now returning itself as a ptr so subscribers (binders) outside of the component can know which component is initiating the event.

Imagine you had some sort of central overlap-manager actor class, and this class binded to many components. The manager would need to know not just who a component overlapped with, but who the component itself is that is triggering the event, so the manager can take action for that specific component.

4.11



/** Delegate for notification of start of overlap with a specific component */
DECLARE_DYNAMIC_MULTICAST_DELEGATE_**FiveParams**( FComponentBeginOverlapSignature,class AActor*, OtherActor, class UPrimitiveComponent*, OtherComp, int32, OtherBodyIndex, bool, bFromSweep, const FHitResult &, SweepResult);


4.12



/** Delegate for notification of start of overlap with a specific component */
DECLARE_DYNAMIC_MULTICAST_DELEGATE_**SixParams**( FComponentBeginOverlapSignature, UPrimitiveComponent*, OverlappedComponent, AActor*, OtherActor, UPrimitiveComponent*, OtherComp, int32, OtherBodyIndex, bool, bFromSweep, const FHitResult &, SweepResult);


So your function that gets called from your dynamic binding needs to have this new parameter added :slight_smile:



UFUNCTION()
void YourFunct(UPrimitiveComponent* OverlappedComponent, ... rest of current)


:heart:

Rama

That did it, thanks!

Yep, I ran into this as well. The problem is that the function signatures have changed. Here is my workflow for fixing this:

  1. Click on the function you’re adding a dynamic delegate for. In this case, “OnComponentBeginOverlap”. Then press F12 and let intellisense find it.
  2. Carefully examine the new function signature and compare it to your existing function signature.
  3. Update your header file function signature to match the new one
  4. Update your CPP file function signature to match the header file
  5. Compile

Upgrade time. Just to clarify the attachment change that Rama mentioned. If you were accessing the AttachParent directly inside of a constructor you should use “SetupAttachment(RootComponent)”.

From the release notes:
“SetupAttachment has been added and is intended to be used in constructors instead of setting AttachParent and AttachSocketName directly.”

Rama, just to clarify a typo in your solution, it should be:

YourComp->AttachToComponent(OtherComp, FAttachmentTransformRules::KeepWorldTransform)

instead of the KeepWorldPosition incase that confuses people =)

Thanks for this thread guys. The sharing community is why i love this engine so much! :slight_smile: <3

I don’t know if anyone else has run into this, but if you get linker errors relating to IGameplayTaskOwnerInterface if you’re not even using the GameplayTasks module in your project, you have to include it in your Build.cs file anyways.

It looks like Anim notifies no longer work in C++?



//BeginPlay
Animation = Cast<UAnimInstance>(Mesh->GetAnimInstance());

//Tick
Animation->AnimNotifies.Num();
Animation->NotifyQueue.AnimNotifies.Num();


Both of these now return 0 at all times, despite how many notifies are happening in my animations.
No notifies in the entire game are triggering anymore.

Any ideas why?

Anyone else getting a package error when they try to build a project that includes OnlineSubsystem? https://answers.unrealengine.com/questions/427833/packaging-error-412p5.html#answer-428934

Compiling on a Mac is giving me an error…



/jj/Dev/epoch_collab/epoch_4_12/Plugins/VictoryPlugin/Source/VictoryBPLibrary/Public/TKMathFunctionLibrary.h
../../../../../jj/Dev/epoch_collab/epoch_4_12/Plugins/VictoryPlugin/Source/VictoryBPLibrary/Public/TKMathFunctionLibrary.h:56:2: error: use of undeclared identifier 'P_NATIVE_BEGIN'

../../../../../jj/Dev/epoch_collab/epoch_4_12/Plugins/VictoryPlugin/Source/VictoryBPLibrary/Public/TKMathFunctionLibrary.h:56:2: error: use of undeclared identifier 'P_NATIVE_END'


This looks like it should be something easy to fix but I don’t wanna go poking around in things I don’t properly understand. Any guidance? And once more, thanks for all the time and effort you’ve put into both this plugin and this community. Cheers,

This is using the source from the .zip file provided above, BTW.

J^2

It looks to me like those macros / definitions you’re trying to refer to no longer exist. Although, that looks like a modified version of the plug-in perhaps?

Yeah, looks like I hadn’t saved the project from 4.12 before creating the xcode project so it was linking to the 4.11 source, instead of the 4.12. Builds fine now. Cheers!

J^2

I can’t seem to be able to get AddDynamic to work. It seems that it’s including the wrong engine version? :-/
Here is my code:



OnActorBeginOverlap.AddDynamic(this, &AMech::OnOverlapBegin);


any my overlap function:



void OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor);


And these are the signatures for the OnActorBeginOverlap delegate:



DECLARE_DYNAMIC_MULTICAST_DELEGATE_FiveParams( FTakeAnyDamageSignature, AActor*, DamagedActor, float, Damage, const class UDamageType*, DamageType, class AController*, InstigatedBy, AActor*, DamageCauser );
DECLARE_DYNAMIC_MULTICAST_DELEGATE_NineParams( FTakePointDamageSignature, AActor*, DamagedActor, float, Damage, class AController*, InstigatedBy, FVector, HitLocation, class UPrimitiveComponent*, FHitComponent, FName, BoneName, FVector, ShotFromDirection, const class UDamageType*, DamageType, AActor*, DamageCauser );
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams( FActorBeginOverlapSignature, AActor*, OverlappedActor, AActor*, OtherActor );
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams( FActorEndOverlapSignature, AActor*, OverlappedActor, AActor*, OtherActor );
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FourParams( FActorHitSignature, AActor*, SelfActor, AActor*, OtherActor, FVector, NormalImpulse, const FHitResult&, Hit );

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam( FActorBeginCursorOverSignature, AActor*, TouchedActor );
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam( FActorEndCursorOverSignature, AActor*, TouchedActor );
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams( FActorOnClickedSignature, AActor*, TouchedActor , FKey, ButtonPressed );
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams( FActorOnReleasedSignature, AActor*, TouchedActor , FKey, ButtonReleased );
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams( FActorOnInputTouchBeginSignature, ETouchIndex::Type, FingerIndex, AActor*, TouchedActor );
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams( FActorOnInputTouchEndSignature, ETouchIndex::Type, FingerIndex, AActor*, TouchedActor );
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams( FActorBeginTouchOverSignature, ETouchIndex::Type, FingerIndex, AActor*, TouchedActor );
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams( FActorEndTouchOverSignature, ETouchIndex::Type, FingerIndex, AActor*, TouchedActor );


I have deleted the xcode project, cleaned Build, Binaries, Intermediate and Saved directories, but nothing. Still doesn’t work.
Can someone help me?

Thanks in advance

Just a heads up: If you are attaching components in the constructor AttachToComponent will throw a warning. Instead you use SetupAttachment(OtherComp).

Hee hee!

:heart:

Rama

Ahh thanks for that, another lesson to never write pseudo code and hope the compiler in my head will notice every detail!

:slight_smile:

You’re welcome!

:slight_smile:

Rama

This was great, thanks for posting this!

Spared me even a moment of having to actually look or think, cause I remembered glancing over your post, before doing an upgrade of a project that encountered this issue.

:slight_smile:

Rama