I’ve set up a simple elevator that I’m trying to implement realistic elevator logic into. As the elevator reaches each floor (overlap event), I’m checking whether that floor has called the elevator, and if it has (and it is on the way up/down to where the elevator is going), I want to stop the elevator at that floor. I’m having trouble with this because I’m using Move Component To when the elevator starts moving to its target floor, and I have no way to stop that movement when it comes across a floor that has called it. Using the Stop entry on the Move Component To node that started the movement is not ideal, because then it executes other stuff after it stops that I don’t want executed in that path. Is there no better way to fully stop a moving component, using blueprint?
I chose to use Move Component To rather than a timeline because the Timeline causes the elevator to change speed depending on how far it’s traveling. The Move Component To node has the “Over Time” input which makes it easy to have it travel at the same speed between all floors, taking 2-3 seconds to travel between each floor.
Best thing is don’t use MoveComponentTo. If you know where you’re going, just use a lerp and SetRelativeLocation ( or SetWorldLocation ) to change the Z of the component.
Thank you! And I take it I can easily control that Lerp in a loop with like a boolean value that I flip when I want to interrupt the travel? Didn’t think of that approach and it’s simple, thanks!
Use a timeline to control the lerp. I need to know more about this case to really fill you in, but you can stop timelines, or you can lerp from one floor to the next etc…
Hmm… I just implemented the timeline with lerp and I do have the elevator moving smoothly from floor to floor, but it takes the same amount of time to travel 2 floors as 1 (it speeds up the further it has to travel to reach the destination within the 3 seconds on the timeline). This was why I didn’t use a timeline to begin with. I’d like for the elevator to take 3 seconds between each floor (so 6 seconds to travel 2 floors, 9s to travel 3 floors, etc.) with the ability for it to stop along its path if a button on a level along the way is pushed. Isn’t this a limitation of timelines, where you can’t dynamically adjust the timeline’s length? I have most of this wired up aside from the movement “interruption” and this speed issue.
The high level look at this is I basically have X number (as many as you place) of “call buttons” (a blueprint of its own), one per desired floor, all linked to the desired elevator via an instance variable. When you interact with the button, it adds that call button to an array on the designated elevator (separate blueprint), and every time the doors on the elevator close, the next target floor is determined (not completed yet but that’ll be decided based on the closest floor in the array). As the elevator travels to the target floor, I’m using an overlap event so that as the elevator nears each floor, it checks to see if that upcoming floor is on the array (meaning, that floor called it since it last departed), and if so, it’ll now use that floor as the target floor to travel to and stop.
Edit: Wow, I totally didn’t realize that Timelines get added as a variable in the blueprint. I’m sure that is a big factor into how this will work.
Edit 2: I might have just nailed the “interrupt” call by just calling Stop from the Timeline component variable and then going back to Play from Start, which starts the timeline again but for the new target floor. The remaining problem is just the speed. It will take 3 seconds to reach the destination no matter the distance, which can make the elevator go crazy fast for further travels XD.
You were really helpful, you just mentioning timelines and lerp made this click. I think I’m getting close. I am adjusting the play rate based on the distance to the target floor and I think it’s working.
Set a variable for “base speed” and dynamically set a variable on elevator call for the “Number of floors” between the floor you are on and where you are going.
get “number of floors” then divide by “base speed” and plug into the speed?
I havent tried it but maybe it can get you closer to your goal for the speed issue
Yes sirs, thanks much to both of you. Your idea of figuring out the number of floors we’re travelling to calculate the speed of that is great. I was currently doing it based on the distance which may be better since some floors may be further apart (picture like a 2A/2B scenario). I’m on the fence on that but I’m definitely closer to perfecting this.
When you call MoveComponentTo() you can send a LatentActionInfo if you set your actor as the CallbackTarget, later you can ask LatentActionManager to stop the movement for you
FLatentActionInfo LatentInfo;
LatentInfo.ExecutionFunction = GET_FUNCTION_NAME_CHECKED(YourClass, FunctionToCallOnEnd); //not sure if this is mandatory, test if the function is needed
LatentInfo.CallbackTarget = this; //this or your object
LatentInfo.UUID = 123; //anything, not sure
LatentInfo.Linkage = 0;
UKismetSystemLibrary::MoveComponentTo(YourComponent, Loc, Rot, true, true, Time, true, EMoveComponentAction::Move, LatentInfo);
And when you want to stop it, you use
FLatentActionManager& LatentActionManager = GetWorld()->GetLatentActionManager();
LatentActionManager.RemoveActionsForObject(this); //this or the CallbackTarget object you set in LatentInfo