4.7 C++ Transition Guide

In 4.7 AAIController::MoveToActor() doesn’t really automatically updating its target position like it use to.

I’ve tested using AAIController::GetImmediateMoveDestination() and it seems to be updating once it reach the first target.
Wierd yet, after that my AI running back and forth between its original position and next points along its path.

Does someone know why the background of this changes : ‘bReplicateInstigator’ : undeclared identifier?
What happened to this behavior? Is it acting as True or false?

IOnlineFriends - Watch out, the function signature are not all the same. I mean, that some changed with passing a delegate to it to be called once it’s over, and the others still work in the old fashion.
FYI I raised a Answers question on this
It will help to understand where we are going in the future…

bReplicateInstigator got removed from the engine!

It’s in the release notes that they removed certain unused actor replication variables :slight_smile:

Have fun today Elvince!

:slight_smile:

Rama

Bump for those still converting to 4.7

Heh, reminds me of Blade’s Unrealscript upgrade threads before, nice one Rama. Thanks!

Boom!
I didn’t see it the first time I read it… maybe because it was quite a long release notes :smiley:

Thanks,

Thanks guys, really helpful guide :))

You’re welcome! Great to hear from you !

:slight_smile:

Hee hee!

Always fun to see everyone come together to help each other out!

:slight_smile:

Rama

Hi,

Quick question on TimerHandle.
If a TimerHandle has been set private (like Lifespan in Actor.h), I can’t reuse it. So if I set a new timerhandle variable in my class, then set a new timer on the same function. What will happen?
Do we have now 2 separate timer on the same function or is it behave like before so the timer is clear and set to the new value and we end with 2 timerhandle on the same timerdata?

It tried to read the cpp part, but I’m usure about the conclusion, I hope you will know :smiley:
My opinion is that we end up with 2 separate timer as I didn’t see any code checking for the “inDelegate” to see if it is already set.

Anyone fallen foul of this one yet?



USTRUCT(BlueprintType)
struct FImpactInfo
{
	GENERATED_USTRUCT_BODY();

	UPROPERTY(BlueprintReadOnly, Category = "Impact Info")
	FHitResult HitInfo;

	UPROPERTY(BlueprintReadOnly, Category = "Impact Info")
	float BulletEnergy;
};




TArray<FImpactInfo> ImpactHits = WeaponType.GetDefaultObject()->GetImpactHitLocations(FFOwner, SpawnLocation, TargetLoc);

			if (ImpactHits.Num() > 0)
			{
				TArray<FImpactInfo>::TIterator ImpactHit = ImpactHits.CreateIterator();
				for (; ImpactHit != NULL; ++ImpactHit)
				{


It throws the following errors that I’m currently trying to decipher…



1>D:\Users\stuart\Documents\Unreal Projects\FireFight\Source\FireFight\Private\FFWeaponAttachment.cpp(234): error C2678: binary '!=' : no operator found which takes a left-hand operand of type 'TIndexedContainerIterator<TArray<FImpactInfo,FDefaultAllocator>,FImpactInfo,int32>' (or there is no acceptable conversion)
1>          D:\Program Files\Unreal Engine\4.7\Engine\Source\Runtime\Engine\Classes\Sound/DialogueWave.h(37): could be 'bool operator !=(const FDialogueContextMapping &,const FDialogueContextMapping &)'
1>          D:\Program Files\Unreal Engine\4.7\Engine\Source\Runtime\Engine\Classes\Sound/DialogueTypes.h(57): or       'bool operator !=(const FDialogueContext &,const FDialogueContext &)'
1>          D:\Program Files\Unreal Engine\4.7\Engine\Source\Runtime\Engine\Classes\Engine/StaticMesh.h(210): or       'bool operator !=(const FMeshSectionInfo &,const FMeshSectionInfo &)'
1>          C:\Program Files (x86)\Windows Kits\8.1\include\shared\guiddef.h(197): or       'bool operator !=(const GUID &,const GUID &)'
1>          D:\Program Files\Unreal Engine\4.7\Engine\Source\Runtime\Core\Public\Containers\Array.h(121): or       'bool TIndexedContainerIterator<TArray<FImpactInfo,FDefaultAllocator>,FImpactInfo,int32>::operator !=(const TIndexedContainerIterator<TArray<FImpactInfo,FDefaultAllocator>,FImpactInfo,int32> &,const TIndexedContainerIterator<TArray<FImpactInfo,FDefaultAllocator>,FImpactInfo,int32> &)' [found using argument-dependent lookup]
1>          while trying to match the argument list '(TIndexedContainerIterator<TArray<FImpactInfo,FDefaultAllocator>,FImpactInfo,int32>, int)'


Remove the != NULL part of your check and do *for(;ImpactHit;++ImpactHit) *.

**I’m pretty sure that the TimerManager will recognize that the timer was already running **and restart the existing timer, because none of the timers in my project got broken by upgrading to 4.7

However if you want to be absolutely sure you can just clear the timer yourself before restarting :slight_smile:

The only thing that changed for me in 4.7 timers was just how to keep track of them to clear them / check if they are running from a function other than the one in which they were created.

The behavior of restarting the same timer by just calling it again seems to be unchanged!

.h



FTimerHandle MyLoopingTimerHandle;


.cpp



//some func that starts timer
{
  GetWorldTimerManager().ClearTimer(MyLoopingTimerHandle);
  GetWorldTimerManager().SetTimer(MyLoopingTimerHandle, &YourClass::YourFunc, 0.01,true );
}

//some func that stops the timer normally
{
  GetWorldTimerManager().ClearTimer(MyLoopingTimerHandle);
}


You could test both ways, calling the clear yourself as above, and then just omitting that first clear, let us know what happens!

Again all my research so far leads me to believe that if the timer manager is already running a timer and gets a request to start that same timer again, it will just restart the current one.

If 4.7 timers worked differently than 4.6 and prior it would have broken a lot of code that relied on non-duplication of timers, so I think the extra ClearTimer is unnecessary but might be emotionally comforting (which is always nice when not inefficient).

:slight_smile:

Rama

Thanks for the answer Rama.

I can’t called ClearTimer in this particular case because the TimerHandle has been hidden by Epic Team by setting it Private. This is why I need to create my own variable, but I have no clue of the side effect like if the private timerhandle is set back to null due to the fact that I’m settings a new handle on the same function so if there is code relying on this, it won’t work… etc…

I know I can change this and compile it by myself, but it would be great to be sure on how things work on the backend. I will open a Answer question to get Epic feedback on this.

Thanks,

Do you have to restart / alter the timer directly?

Can you just reset / change the LifeSpan itself?

Rama

Yes I have to alter the current timer to change the lifespan to a different one than the default during the gameplay.
I can’t just change the value on the variable as the timer will be still based on the DefaultLifespan.

This is why I need to have acces to this timer. But I can’t retrive it, I can’t access it… My only option was to create a new timer handle with potential side effects. I opened the answer question here. I will keep you updated.

Thanks,

Thank you :D. Im up and running with 4.7 now :stuck_out_tongue:

ATriggerBox won’t be recognized as identifier.

Hi!

I am making Unreal Plugin based on 3DBUZZ learning course “Creating Plugins with Unreal 4”.

I meet a problem with using ATriggerBox actor.

VS won’t recognize it and offered to use UActorFactoryTriggerBox instead.

Can you help me please and push into right direction?

Thank you in advance!

Dear RoadStar,

If you search the code base you will find TriggerBox.h, so its definitely there :slight_smile:



/** A box shaped trigger, used to generate overlap events in the level */
UCLASS(MinimalAPI)
class ATriggerBox : public ATriggerBase
{
	GENERATED_UCLASS_BODY()



**Include**

Try adding this include to your .h file, above your .generated #include!



```


#include "Engine/TriggerBox.h"


```



Let us know!

:)

Rama

Thank you, dear Rama!

Sure, that’s why I’ve been wonder - my projects contains TriggerBox in Engine’s source code.

So, I made included in my .h file anyway, thank you for advise!

But now I have another question, related to same code (sorry, I just trying to come back to C++ from 2 years working with JavaScript only)

This is re-declaration problem. Can you advise me please, how to use IsActorSelected right in this code? (I made one-to-one as in learning video)

Thank you in advance!

Hi RoadStar

Without seeing the error you are asking about, its hard to understand what you want as an answer :slight_smile: I read your question two different ways so here are two answers

  1. Read as “why do I see this twice?”

the .h file contains the definition (the syntax of the function/method)
the .cpp file contains the implementation (the logic that actually does something)

  1. Read as “There is some sort of error about redefinition, but you didnt paste the error”

If you want to make your own version of a file in the parent the parent has to have first created it as “virtual”, then you can override it



//In .h file
bool IsActorSelected(ATriggerBox* actor) override;


Hopefully one of them answers your question.

NB. using CODE ] tags is easier to work with than screenshots of your code.