Elevator Style Character Movement (Should I even be trying to use Lerp?)

Caught that amazing bit of info regarding the back up just a touch too late to do anything with it. Swapped the files over first thing this morning though and everything works again. This coming on the heels of a bunch of finger wagging from my friends that I need to get a some sort of source safe set up, well they can SUCK IT! But seriously I need some kind of off site source safe for reals.
Thanks for the tip .

Ok, for the other post regarding the OOP break down, most of that all makes perfect sense. Classes start as the broadest possible concept, and each related category subgroup inherits their abilities and adds on their own touches, with divisions between them occurring as more and more individuality is noted. I’ll be sure to main line those videos as soon as I can.

I’m not entirely sure I’m following the difference between a CPU tick and a World Tick. Why would the tick of your level be different from the CPU?

For your question regarding a reference variable, I think I might be describing that wrong, but having an object selected in the view port and then right clicking in the blueprint will bring up a context sensitive option to reference it. Good for calling a camera or object to plug into a target pin. Now that I’m really considering it, that doesn’t really sound like a variable as such, at least not in the way that a class would need to be referred to. I promise I’ll do it right in the updated version.

On that note, I have a day off so lets get all that implemented!

Disclaimer: The following explanation of CPU ticks is based more on colloquialism than actual computer science for the sake of simplicity.

So a CPU Tick is (non-scientifically) referring to a cycle your CPU goes through to perform an operation. These are sometimes (non-scientifically) referred to as FLOPS or floating-point operations per second. The more GHz your CPU sports, the more FLOPS it can put out. When you ask your computer to perform arithmetic, it’s going to cost a “CPU tick” to do it. One operation will be practically instantaneous, but many many floating-point operations will slow you down. They say that preemptive optimization is the root of all evil, but you should save any CPU time you can. This is the lowest of the low-hanging fruit. For the most part, you don’t need to worry at all about CPU ticks.

Now where this differs from the world or object tick is that an object (the world is an object) is ticked once per frame rather than based on hertz. When an object is ticked, all of its instructions are sent to the CPU and GPU for their internal ticks to handle. The more instructions you have to send, the more finite CPU ticks it will take and the longer it will take for the next frame to be rendered, thus lowering the frame rate. All of your objects’ tick times are added up to the frame update time. When all of your objects’ instructions have been executed, they will be ticked again. Of course, “Tick” isn’t the scientific name for a frame update. Some engines refer to this frame update cycle as “Update” or “Draw.” Unreal just uses the word “Tick.”

I’ve heard Draw and Tick both, but it’s cool to have the distinction. Someone also just explained to me what “delta” actually means. “Change or difference”. A bunch of things suddenly just started making sense thanks to that!

Also this was what I meant in regard to the character placement and height:

This would be incorrect placement based purely on bounding boxes:


And this would be the desired look:


When I was working with the DS we would try and have an artist defined origin point to reference in the asset, often right around the point where the feet were supposed to be visually intersecting with the world in a way that looked attractive. It would allow different objects to be produced and added to the game, and all the object positions would come out looking like roses each time, without a scripting update to manage it. Right now I’m specifically calling an arbitrary height increase to manage this. Using an edited collision box would work in a snap, but then I have to worry about gravity and this game really isnt going to be taking that into account (as far as I can think of outside of some weird edge cases that I think I’d rather avoid).

Delta, as you might surmise, is the number of seconds (hopefully fractional seconds!) it takes to change or update the frame. When moving something over time, it’s important to multiply the movement value by delta time so that the movement stays framerate-independent. This isn’t a concern when using timelines since they are time-based and not frame based, but if you were moving your character using the thumbstick or something, you’d multiply the movement rate by delta so that would ensure the character moved at a rate per second.

For example, you have have your character move 1 unit every tick, they’ll move 30 units over 1 second on a computer that’s running the game at 30 frames per second and move 60 units over 1 second on a computer that runs the game at 60 frames per second. Multiplying the 1 unit by delta will fractionalize it so that whether the game is running at 30 fps or 60 fps, it will still take 1 second to move 1 unit (and to that end you might want to increase the rate up from 1 unit!).

As for your footing, in that case you can just add a negative value to the Z when you add the half-height. So it would be like GetBounds Z->Add to tile Z->Add negative (or subtract) a little offset until you get the desired look. This may be difficult if you have collision considerations to make, but if not you won’t have any problems.

Ok, I’ve got everything built and implemented, everything compiled without error, but I still have no response from either my Press Up or any of the other input commands.

I just copy and pasted the Press Up event into the Level Blueprint and guess what works! So something needs to be sent down into the Debtor Blueprint. Cast control access to the Debtor Class Blueprint or something along those lines?

Nah, nothing like that. You should have a button on the toolbar that will enable you to edit class defaults. Make sure “Block Input” is NOT checked and It’s listening for input from Player 0, not Disabled.

Like this?


I’m still not getting any reaction. Do I need to do something like put the player controller into the level as a physical reference or could the 2D Side-Scroller Player Blueprint be interfering in any way? Or could I have screwed it up somehow? When I started building this I quickly realized how little of my game would actually use that player set up and set about ice-cream scooping out as much of it as I could.

Interesting! this is on your Player Pawn, correct?

try two things for me. First, put up the input priority to something like 10. Then put in any key event in the graph, like G, and print a message from it and see if it works.

Well he’s a PAWN class, but not a character class, and I didn’t see PLAYER PAWN specifically.

I’m adding in that check now.

Ok the input priority yielded no results. to make sure I did the same thing on a 2nd button up in the level blueprint and that did fire.

Whelp, one of those important things I scraped out early on was the “Auto possess when level starts”, and now the G Key input message is displaying and the pawn is recieving input. He’s not moving correctly just yet but I’ll track down where that’s happening. Let me crack at this for a few minutes…

Ok movement works! Here’s the current set up and it is so close! Still broken, but close!


Now my current assumption based on what I’ve seen by editing this, is that I need to establish both where the Debtor is before the transition, and where he’ll end up after it, hence the Current Location and Destination variables. I have two problems I’m encountering:

  1. The timeline only plays one time. Every move after that does not register that the timeline exists and I’m really uncertain as to why.

  2. I have no control over the speed of the Debtor’s transit. I’ve looked into a handful of alterations or even switching from the lerp to something else, but nothing does it. Any edits to the Move curve I’m linking from the Timeline to the lerp results in a change to the actual distance between Current and Destination rather than the time it takes to transit between them. I’ve heard of this problem when I was doing research earlier, and there was this really gorgeous implementation I’ve been desperately trying to find where the author performs a series of operations on both the Current Location and the Destination BEFORE they’re handed off to the lerp.

I’m due out but I’ll be damned if I’ll be able to dislodge this one from my brain any time soon…

  1. Try Play from start instead of play, as that plays from where you left off.
  2. Divide the “Move” return value from the timeline by the number of seconds you want the motion to take before plugging it into your lerp’s alpha.

Damnit, just as I’m about to leave! But seriously thanks for the quick response !

I’ll hook up the From Start pin when I get back.
As for the move, I tried that with a “Float Divide” based on your description further up the correspondence chain. The result was that it either lengthened or shortened the physical distance of the move rather than playing off the speed of it. I’ll double check that behavior when I get back in, but that’s what I’ve been trying to crack since my Meme post.

Ok good news! Switching to play from start absolutely lets the Debtor use the Lerp to transit through space each time!

Bad news is that he skips over the tile he’s supposed to go to and is too low by about six or seven pixels. Here’s the fun part; when I tell him to move to the next tile after that double tile jump, he rises up those six or seven pixels and settles into position at what would be the correct spot of that second move. I’ve counted the number of moves before it spits back the “no more tiles” debug line. He’s moving six total spaces if I start doing this from the far side. I don’t even know where to start with that, but either way it’s not happening tonight.

Still I owe you a massive amount of thanks . In the span of five days I’ve gone from doing everything incorrectly, to having a functional transition between spaces. I wouldn’t doubt that using your system would have given me a picture perfect result immediately, but I’ll be damned if I didnt learn a whole bunch with your help.

I’d wager that the reason he’s jumping between tiles and not in order is because “Get All Actors of Class” doesn’t necessarily get them in the order you want. I had a hunch this would be an issue at the beginning, but didn’t want to overload you. You’ll need to sort these tiles, but there is no one-size-fits-all approach to it, unfortunately. It would be easiest to pass the array into a C++ blueprint function library and sort based on a predicate of the tile’s name, but I assume that C++ isn’t your forte.

Let’s assume that you want tiles to be sorted left-to-right as they are on-screen. Assuming your camera is facing down the X axis, Y-left should be a lower number than Y-right.

When you get the tiles, put them into a temporary array (as a local variable in a function). Do a foreach on the array and get the Y coordinate of each, placing it into a local float array.

After the previous foreach is completed, use the while loop. The while loop will run a block of code for as long as the condition plugged into it is true. While the local float array’s length is greater than 0 (meaning it still has entries), Get the minimum number of the float array and put it into another sorted float array, then remove the entry from the previous float array. This will continue until the original float array’s entries are totally removed, placed into the sorted float array in order.

After that’s completed, we’ll run another while loop, this time checking that the length of the sorted float array is greater than 0. Inside each while loop body, we’ll run another foreach loop on the array of tiles, but this time we want to use “foreach loop with break.” This will allow us to break out of the foreach loop when we find what we’re looking for so we’re not wasting time iterating over the rest of the entries in the array.

This foreach loop will get the Y coordinate of the tile and check if it is nearly equal to the first entry of the sorted float array (since they are in order). If it is nearly equal, we know that this tile is the first of the tiles going from left to right. We can then place this tile into a permanent array of tiles for his level and they’ll be sorted based on their Y positions going from left to right. After placing each tile in the array, we remove the first entry of the sorted float array. We remove the first because we want to go through them in order. then we break the current foreach loop.

Nearly equal is used instead of equal because floats are imprecise. They can be slightly different between ticks just because they’re meant to be approximations of numbers, not exact numbers. Changes are usually minute, within a trillionth of deviation, but it can still be different and therefore, not equal.

The while loop will then evaluate the length of the sorted array again and if necessary repeat the process until the sorted float array is empty. In the end you should have your tile array sorted by Y-coordinate from least to greatest, and if your scene is set up to corroborate, from left to right.

Unreal really needs some array sorting nodes. I’ll add them to my blueprint function library and submit a pull request so they get added to the engine.

http://www.protias.com/Pictures/Super%20Troopers/Mother%20of%20God.jpg

I’ll get on this when I get home tonight. I was considering the array being jumbled as a possibility, but after I got the print array to screen debug key working the order that it would spit back was appearing in the numerically correct order, ranging 0 to 6. I was wondering how the engine would know which tile to grab first, as get all actors of class does seem like it could be arbitrary, so that’s why I added a number to each instance of the tiles in the hope that it might outpace such a problem.

So if I’m following this correctly we’re creating a temp array to house the tiles in the stage. Then we’re chewing through that to pull out the physical location of each object to create a 2nd array of those numbers. Third we rearrange those numbers from lowest to highest to get a left to right physical order that the tiles are supposed to appear in. Lastly we create a final array and compare each array tile versus the numbers we pulled and sort the order of the final array according to the physical position numbers in the other array to ensure that the tiles are forced to the same order they hold in physical space. Is that about correct?

This seems like the sort of thing that might have been needed on a real project at Epic by now…

Hmm… if the tiles print back in order (highest to lowest, top to bottom) then that probably isn’t the issue, but at least this function will allow you to place tiles arbitrarily. There’s gotta be something else afoot. If the problem persists, supply screens of errrthang you got and we’ll work it out.

I’m sure Epic has needed to sort arrays before, but I’m even more sure they would use C++ in that case. There are quite a few glaring omissions in blueprint functionality that require workarounds. You CAN do essentially anything (with a few exceptions) but sometimes what you want to do requires some insane lateral implementation. Learning Unreal C++ really does help a LOT in terms of productivity.

I imagine it’s the difference between getting a super literal puppy to fetch something and just getting up to go get it yourself.

That’s a fairly apt comparison, yes.