Download

Set direction property in timeline before firing events

Just to illustrate my proposal:
I tried to create a simple door, which plays two different sounds, when opened or closed. If it gets opened it plays a low volume ‘click’ sound and when someone closes it, it could be a somewhat louder ‘click’ or ‘bang’.
This was implemented with blueprint nodes. I have a timeline object and it’s “Play” slot is activated, if the door should open. The “Reverse” slot is triggered, when it should close.
The timeline has a float track and an event track. The float track is used to animate the door. The event track fires one event very close to 0 on the timeline.

The logic of the blueprint relies on the “Direction” property to diifferentiate between closing and opening when the event is fired, so it can play the right sound.

The first time, those triggers are activated, everything is fine. But from the second run onwards, the direction is always “backwards”, so even if the door is beeing opened, the close sound gets played.

While I tried to debug this, I realized, that the direction property is set to forward, after the event is triggered, because it was so close to 0.

One idea to fix this issue, would be to set the direction property, before any event is fired.

As a git diff:



diff --git a/Engine/Source/Runtime/Engine/Private/Timeline.cpp b/Engine/Source/Runtime/Engine/Private/Timeline.cpp
index cb56eec..daca650 100644
--- a/Engine/Source/Runtime/Engine/Private/Timeline.cpp
+++ b/Engine/Source/Runtime/Engine/Private/Timeline.cpp
@@ -158,6 +158,29 @@ void FTimeline::SetPlaybackPosition(float NewPosition, bool bFireEvents)
 		}
 	}
 
+	UObject* PropSetObject = PropertySetObject.Get();
+
+	if (DirectionPropertyName != NAME_None)
+	{
+		if (PropSetObject)
+		{
+			if (DirectionProperty == NULL)
+			{
+				DirectionProperty = FindField<UByteProperty>(PropSetObject->GetClass(), DirectionPropertyName);
+				if (DirectionProperty == NULL)
+				{
+					UE_LOG(LogTimeline, Log, TEXT("SetPlaybackPosition: No direction property '%s' in '%s'"), *DirectionPropertyName.ToString(), *PropSetObject->GetName());
+				}
+			}
+			if (DirectionProperty)
+			{
+				const ETimelineDirection::Type CurrentDirection = bReversePlayback ? ETimelineDirection::Backward : ETimelineDirection::Forward;
+				TEnumAsByte<ETimelineDirection::Type> ValueAsByte(CurrentDirection);
+				DirectionProperty->SetPropertyValue_InContainer(PropSetObject, ValueAsByte);
+			}
+		}
+	}
+
 	// If we should be firing events for this track...
 	if(bFireEvents)
 	{
@@ -190,8 +213,6 @@ void FTimeline::SetPlaybackPosition(float NewPosition, bool bFireEvents)
 		}
 	}
 
-	UObject* PropSetObject = PropertySetObject.Get();
-
 	// Iterate over each vector interpolation
 	for(int32 InterpIdx=0; InterpIdx<InterpVectors.Num(); InterpIdx++)
 	{
@@ -294,27 +315,6 @@ void FTimeline::SetPlaybackPosition(float NewPosition, bool bFireEvents)
 		}
 	}
 
-	if(DirectionPropertyName != NAME_None)
-	{
-		if (PropSetObject)
-		{
-			if (DirectionProperty == NULL)
-			{
-				DirectionProperty = FindField<UByteProperty>(PropSetObject->GetClass(), DirectionPropertyName);
-				if (DirectionProperty == NULL)
-				{
-					UE_LOG(LogTimeline, Log, TEXT("SetPlaybackPosition: No direction property '%s' in '%s'"), *DirectionPropertyName.ToString(), *PropSetObject->GetName());
-				}
-			}
-			if (DirectionProperty)
-			{
-				const ETimelineDirection::Type CurrentDirection = bReversePlayback ? ETimelineDirection::Backward : ETimelineDirection::Forward;
-				TEnumAsByte<ETimelineDirection::Type> ValueAsByte(CurrentDirection);
-				DirectionProperty->SetPropertyValue_InContainer(PropSetObject, ValueAsByte);
-			}
-		}
-	}
-
 	// Execute the delegate to say that all properties are updated
 	TimelinePostUpdateFunc.ExecuteIfBound();
 }



Another idea that just came to my mind would be to set the forward/backward property in the Play() and Reverse() method calls. Why is it set continually during the update event anyway? Can the direction change without a call to Play(), Reverse() etc?

For the lack of a bigger testing project on my side, I’m not quiet sure, if any of the two proposed changes could have a negative side effect.

Since this is my first post here, please feel free to tell me, if it should have gone somewhere else.

This does sound like a good fix! Would it be possible to submit it as a pull request?

Unfortunately that’s difficult, since I use the engine as a student at my university and I have no direct access to the registered GitHub account.

I will see what I can do.