[Open Beta] Procedural On-the-Fly Animation in UE4: iTween!

Does this work with 4.7?

I’m getting a build error message when I try to launch my project (immediately after installing iTween) - something to do with the .DLL being made for an earlier version of the UE4 engine.

So one of the packaging issues comes from a line of code in the iTweenEvent source that names the iTweenEvent, or actually sets its actor label. This works fine in the engine, but not in the packaged game. The way to deal with this is to comment out the line in “NameEventActor” at line number 2965 and rebuild.

With this commented out, I’m able to package a development build at 64-bit, but not a shipping build at 32-bit, but the error doesn’t point to iTween. It points to the game’s dll, so I’m not 100% sure what the problem is . I’m going to keep investigating until I figure it out. This seems to be a problem with a lot of people trying to package with plugins, but none of the fixes have yet worked for me.

There is no problem when packaging the game with the installed source version of iTween, but I can’t easily recommend you switch over to it. UE4 will recognise the plugin iTween and the source iTween as being two different namespaces so it won’t just transfer over. I’ll figure something out for you and all the other plugin users soon, though :slight_smile:

While you can have the tween stop prematurely when it collides (by turning on sweep) and turn on physics when it does, there is no way currently to take the inertia from the tween and apply it to the physics calculation. Working with physics is on the roadmap, but for now you’re better off working with physics exclusively.

As for a random point in a vector radius, you can plug something like below into an iTween event:


Capture.PNG

Yes, the plugin does work with 4.7 but the last build was for 4.6.1. You can rebuild it for 4.7 yourself using this guide: YouTube

Or you can wait for the next release which will be sometime this week after we figure out a packaging issue. I’d strongly recommend installing the source version (I’m a C++ user or both) though because it will still allow you to use blueprints for setting up tweens and doesn’t have the packaging issues plugins have (thanks Epic).

It’s a shame that while plugins are great it’s evidently very frustrating/problematic for users to try and build with them (through no fault of your own I mean but problems that seem to be a part of unreal engines setup for them). Thanks for all your hard work looking into the issue, hope you can find an easy to implement solution soon ^^,

Hi , can you post a piece of code showing how to use the OnTweenComplete (and others callbacks) in c++? Im extending IiTInterface in my target but it is not calling my implementation =/

edit: Got it working! I changed it to BlueprintNativeEvent and did a little to work. Dont you think that BlueprintNativeEvent is better? with BlueprintImplementableEvent we need to use blueprint, dont we? In my case I wanted C++.

Thanks once again for this awesome plugin =)

Cheers

This is amazing work . thanks

To be honest, I never really knew much of the difference between all of the different macro parameters. I’ve been implementing them in somewhat of a roundabout way. In the interest of advancement, would you mind sharing the code you wrote and changed? I would very much appreciate it as would other C++ iTween users :slight_smile:

Thank you for the compliment. We always love aggrandising praise :slight_smile:

Hey , consider using Github for your project, must easy for rest of us to get updates, and maybe contribute to your code.

That’s a great idea! I’ll check out the logistics of doing this with a plugin and post the code there as well.

Changed Version

Sure, the changes that I did were:

  1. Turned OnTweenStart and OnTweenComplete a BlueprintNativeEvent in iTInterface.h.

class IiTInterface
{
	GENERATED_IINTERFACE_BODY()

public:
	UFUNCTION(BlueprintNativeEvent, BlueprintCallable, meta = (FriendlyName = "On Tween Start"), Category = "iTween|Interface Events")
		void OnTweenStart(AiTweenEvent* eventOperator, AActor* actorTweening = nullptr, USceneComponent* componentTweening = nullptr, UWidget* widgetTweening = nullptr, FName tweenName = "");

	UFUNCTION(BlueprintImplementableEvent, BlueprintCallable, meta = (FriendlyName = "On Tween Tick", DeprecatedFunction, DeprecationMessage = "Interface Event deprecated, use On Tween Update instead."), Category = "iTween|Interface Events")
		void OnTweenTick(AiTweenEvent* eventOperator, AActor* actorTweening = nullptr, USceneComponent* componentTweening = nullptr, UWidget* widgetTweening = nullptr, FName tweenName = "", float alphaCompletion = 0.f);

	UFUNCTION(BlueprintImplementableEvent, BlueprintCallable, meta = (FriendlyName = "On Tween Data Tick", DeprecatedFunction, DeprecationMessage = "Interface Event deprecated, use On Tween Update instead. Data values are now stored in 'Data Type Values' struct. Break that to get float value, vector value, etc."), Category = "iTween|Interface Events")
		void OnTweenDataTick(AiTweenEvent* eventOperator, FName tweenName = "", float floatValue = 0.f, FLinearColor linearColorValue = FLinearColor::Black, FRotator rotatorValue = FRotator::ZeroRotator, FVector vectorValue = FVector::ZeroVector, FVector2D vector2DValue = FVector2D::ZeroVector, float alphaCompletion = 0.f);

	UFUNCTION(BlueprintImplementableEvent, BlueprintCallable, meta = (FriendlyName = "On Tween Loop"), Category = "iTween|Interface Events")
		void OnTweenLoop(AiTweenEvent* eventOperator, AActor* actorTweening = nullptr, USceneComponent* componentTweening = nullptr, UWidget* widgetTweening = nullptr, FName tweenName = "", int32 numberOfLoopSections = 0, ELoopType::LoopType loopType = once, bool playingBackward = false);

	UFUNCTION(BlueprintNativeEvent, BlueprintCallable, meta = (FriendlyName = "On Tween Complete"), Category = "iTween|Interface Events")
		void OnTweenComplete(AiTweenEvent* eventOperator, AActor* actorTweening, USceneComponent* componentTweening, UWidget* widgetTweening, FName tweenName, FHitResult sweepHitResultForMoveEvents, bool successfulTransform);


};

  1. Changed iTweenEvent.cpp, making AiTweenEvent::RunInterface to use only the static version with the Execute_ prefix. (somehow the cast version was crashing with c++). Double checked the changed version and it was still working with blueprints.

void AiTweenEvent::RunInterface(UObject* target, FString type)
{
    /* Little hack to work with c++
	IiTInterface* interf = Cast<IiTInterface>(target);

	if (interf)
	{
		if (type == "start")
		{
			interf->OnTweenStart(this, actorTweening, componentTweening, widgetTweening, tweenName);
		}
		else if (type == "update")
		{
			//interf->OnTweenUpdate(this, actorTweening, componentTweening, widgetTweening, tweenName, dtv, alpha);

			if (IsEventDataType())
			{
				interf->OnTweenDataTick(this, tweenName, dtv.floatCurrent, dtv.linearColorCurrent, dtv.rotatorCurrent, dtv.vectorCurrent, dtv.vector2DCurrent, alpha);
			}
			else
			{
				interf->OnTweenTick(this, actorTweening, componentTweening, widgetTweening, tweenName, alpha);
			}
		}
		else if (type == "loop")
		{
			interf->OnTweenLoop(this, actorTweening, componentTweening, widgetTweening, tweenName, numberOfLoopSections, loopType, playingBackward);
		}
		else if (type == "complete")
		{
			interf->OnTweenComplete(this, actorTweening, componentTweening, widgetTweening, tweenName, sweepResult, successfulTransform);
		}
		else
		{
			UiTween::Print("Target is not defined as iTweenEvent message-accepting type.", "error");
		}
	}
	else
	{
     */
		if (target && target->GetClass()->ImplementsInterface(UiTInterface::StaticClass()))
		{
			if (type == "start")
			{
				IiTInterface::Execute_OnTweenStart(target, this, actorTweening, componentTweening, widgetTweening, tweenName);
			}
			else if (type == "update")
			{
				//IiTInterface::Execute_OnTweenUpdate(target, this, actorTweening, componentTweening, widgetTweening, tweenName, dtv, alpha);

				if (IsEventDataType())
				{
					IiTInterface::Execute_OnTweenDataTick(target, this, tweenName, dtv.floatCurrent, dtv.linearColorCurrent, dtv.rotatorCurrent, dtv.vectorCurrent, dtv.vector2DCurrent, alpha);
				}
				else
				{
					IiTInterface::Execute_OnTweenTick(target, this, actorTweening, componentTweening, widgetTweening, tweenName, alpha);
				}
			}
			else if (type == "loop")
			{
				IiTInterface::Execute_OnTweenLoop(target, this, actorTweening, componentTweening, widgetTweening, tweenName, numberOfLoopSections, loopType, playingBackward);
			}
			else if (type == "complete")
			{
				IiTInterface::Execute_OnTweenComplete(target, this, actorTweening, componentTweening, widgetTweening, tweenName, sweepResult, successfulTransform);
			}
			else
			{
				UiTween::Print("Target is not defined as iTweenEvent message-accepting type.", "error");
			}
		}
		else
		{
			/*if (target)
			{
			UiTween::Print("Cannot send Interface message to" + target->GetFName().ToString(), "error");
			}
			else
			{
			UiTween::Print("Cannot send Interface message.", "error");
			}*/
		}
	//}
}

  1. Then, in my actor class I extended IiTInterface;

class RUBIKSUNREAL_API ARubiksCube : public AActor, public IiTInterface

and set to override the _Implementation version of OnTweenComplete (Needed for BlueprintNativeEvents).


...
public:

  virtual void OnTweenComplete_Implementation(AiTweenEvent* eventOperator, AActor* actorTweening, USceneComponent* componentTweening, UWidget* widgetTweening, FName tweenName, FHitResult sweepHitResultForMoveEvents, bool successfulTransform) override;
...

  1. this way, if I not implement the callback in blueprints it will use the c++ version.

Did you get it? If not I can send you the project after I finish it.

Best Regards,

Daniel

Hello, I am frustrated and can’t seem to get it to work. It shows up in the plugin list, but when i select it, it tells me to restart. The problem is I can’t “compile”. Please look at these two images. PLEASE HELP, I CAN’T WAIT TO TRY THIS.Capture.Capture2.

Some will say to compile it with Visual Studio Express, but for some reason I cannot install it, it just freezes on my computer. Can anyone provide the new build?

I’d say compile it with Visual Studio Community since Express is on the way out and Community is free and allows VS plugins. I go over how to compile for C++ projects in the installation tutorial video: YouTube

Additionally, I’d recommend installing as a C++ user even if you’ll only be using blueprints to make your game because right now plugins have issues packaging a final shipping game. Epic is working on a fix and I’m trying to find a workaround (still) but if you install as a C++ user you won’t have packaging issues unless the UE codebase changes, in which case simply upgrading iTween will fix the problem since I’ll be keeping up with the codebase. Installing as a C++ user will still allow you to use iTween blueprint nodes.

But if you still want to install the plugin version (“I’m a blueprinter exclusively”) despite that, 's a 4.7.2 compiled version: iTween v0.8.5b for UE4.7.2

It has no new features, just an update for the 4.7.2 codebase. While it has not been fully tested, it shouldn’t be broken. New features coming in a near-future release. :slight_smile: Have fun, malospam!

Daniel, thank you so much for this! I’m going to look it over tomorrow and add it to the codebase. Best of all, I’m sure I’ll learn something. :slight_smile:

Actually, I can’t get this to compile at all. If you wouldn’t mind, I’d love to take a look at your project.

Thanks for this. I thought the express was the free one thats why I downloaded it, but I’ll try community. Yes I was following exactly as your video showed , its just that I could not get Express installed, even after I formatted my computer!

Sure… just released it.

Source code: Bitbucket

checkout: RubiksCube.h, RubiksCube.cpp, iTInterface.h and iTweenEvent.cpp

if still doesnt work, I can try to make an empty project with the changes in iTween and send you back!

Cheers!

Hi , I made a very simple project with the modification only on the OnTweenComplete.

is the download link: Dropbox - Error

Checklist:

  1. Changed OnTweenStart from BlueprintImplementableEvent to BlueprintNativeEvent in iTInterface.h.
  2. Changed iTweenEvent.cpp, making the method AiTweenEvent::RunInterface to use only the static version with the Execute_ prefix.
  3. Make a class extend public IiTInterface;
  4. Override the OnTweenStart_Implementation.

I added two blueprints in the TweenMap scene: Cube_Blueprint and Cube_CPP.

Cube_Blueprint I added a simple logic that when I press “B” the cube moves and notifies itsellf when its done on screen.

Cube_CPP is a blueprint from a CubeCPP class in c++. I added a simple logic in c++ that when I press “C” the cube moves and notifies itsellf when its done in the Output Log (Window > Developer Tools > Output Log).

Hope it helps!

Cheers!

Thanks for all of this, Daniel! In the end, I will not be going with BlueprintNativeEvent. The reason being, BNEs require a native implementation in a derived class that is not abstract. You can’t just put the implementation in the interface source, frustratingly enough. As much as I love your solution, it just wouldn’t work for everyone unless I were to make a tweenable actor, tweenable component, and tweenable uwidget class with native implementations and make everyone derive from them OR force all C++ users to provide implementation for Start, Update, Loop and Complete whether they use them or not.

So in the end I’ve decided to keep the BlueprintImplementableEvents the way they are and compromise by adding OnTweenStartNative and others ending in “-Native” as virtual voids for C++ users. So now if you want to use interface messages in C++, you only have to override the type of message + “Native.”

Example:

MyActor.h


#pragma once

#include "GameFramework/Actor.h"
#include "iTween/iTInterface.h"
#include "MyActor.generated.h"

UCLASS()
class MYPROJECT_API AMyActor : public AActor, public IiTInterface
{
	GENERATED_BODY()
	
public:

	AMyActor();

	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Default")
		AActor* actorToMove;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Default")
		FVector v;

	virtual void OnTweenCompleteNative(AiTweenEvent* eventOperator, AActor* actorTweening, USceneComponent* componentTweening, UWidget* widgetTweening, FName tweenName, FHitResult sweepHitResultForMoveEvents, bool successfulTransform) override;
	
};

MyActor.cpp


#include "MyProject.h"
#include "MyActor.h"
#include "iTween/iTween.h"
#include "iTween/iTweenEvent.h"


// Sets default values
AMyActor::AMyActor()
{

}

// Called when the game starts or when spawned
void AMyActor::BeginPlay()
{
	AActor::BeginPlay();
	
	if (actorToMove)
	{
		AiTweenEvent* ie = UiTween::ActorMoveFromToMin(actorToMove, "vfrom = this; vto = " + v.ToString() + "; time = 5; easetype = ioquad;", false);
		ie->onTweenCompleteTarget = this;
		ie->InitEvent();
	}
	UiTween::Print("ok", "error");
}

void AMyActor::OnTweenCompleteNative(AiTweenEvent* eventOperator, AActor* actorTweening, USceneComponent* componentTweening, UWidget* widgetTweening, FName tweenName, FHitResult sweepHitResultForMoveEvents, bool successfulTransform)
{
	UiTween::Print("Interfacing works in C++!", "error");
}

In this example, the tween will run over 5 seconds, moving a blueprint-specified actor from its current location to a blueprint-specified vector using the EaseInAndOutQuadratic easetype, but won’t start automatically because I want to set the onTweenCompleteTarget to be this actor, then I manually start the tween with InitEvent(). Then I print “ok” to debug, using “error” so that it prints to my screen without needing to turn on “printDebugMessages.”

When it completes, I force a print to screen again with a message about how it works.

It’s a bit more to type and I hate having separate events for C++ users, but that’s the best solution I can come up with for right now!

Thank you so much for your hard work and sharing it with us!

No problem! I`m glad that I helped. Keep up the awesome work with iTween!

Best Regards,

Daniel

New version! v0.8.6b compiled in engine version 4.7.3.

Get it : Mediafire Next time you can get it or on GitHub!

Changelog:
~New Features:
-Added virtual voids to iTInterface that will much more easily allow C++ users to implement interface callbacks in native code. Thanks to danielvmacedo for bringing this issue to our attention! See this post for more information.
-Added an option to cull tweens for Actors and Scene Components when they’re not in view (cullNonRenderedTweens, parser shortcut “cull”). Off by default, but if turned on, iTween will check to see if a tweening actor or component is visible to the camera before tweening. If so, the tween will continue. If not, the tween will continue still for as many seconds as specified in secondsToWaitBeforeCull (default 3, parser shortcuts “cullwait” and “stwbc”), then if the tweening object is still out of view, the tween will stop until it is again in view. This is useful if you have a large area with many different tweens going on at once. Recommended for open-world projects, areas with large occluders, and scenes with hundreds of tweens in which the player won’t see all of them at once. Thanks to TDoro for this suggestion!
~Fixes:
-Fixed a bug that made paused looping tweens continue, overriding the pause. Thanks gpvd for finding the bug and proposing the fix!
-Disabled a function that names event operators after they’re created (NameEventActor()). This only works in the editor and causes some packaged games to crash or not compile.
-Upgraded the SetTimer() implementation to adhere to 4.7 standards.