I’d like to know the position of an actor. But not the actual position. I want to know where it was 100ms ago.
The obvious (but wrong way) is to remember the position every 100ms. This doesn’t work, because if I check the position shortly after the variable with the location was set, I get the position 5ms ago, or maybe 25ms ago.
Does anyone have an idea how I could implement this without a huge array of values that gets updated every tick?
The shortcut method (which should work depending on how specific that 100ms window needs to be) is a VInterpTo Constant node. You use a Vector variable which, every Tick, updates its position attempting to reach the actor’s current position at a constant rate. That rate will determine how much it “lags” the actor in question.
This won’t be mathematically super-accurate (it won’t consistently point to where the actor exactly was exactly 100ms ago), but it satisfies most reasons to want to do that. For example, I use it for my enemy’s aiming AI so that he always points at where the player just WAS, so he can be out-strafed. For stuff like that, or for making one actor follow another around, it works really well.
Cant the same not be achieved by just putting the aim slightly off in the opposite direction of player movement from the enemy perspective.
Like: The enemy sees me running “from left to right”, his aim would be made a bit off to the left.
This way it would be independent of any position, but only depend on comparing direction of player movement and direction of enemy view…
It COULD, but it would be more trouble than it’s worth. For one thing, velocity and position aren’t directly related in all cases; take, for instance, situations where the player is running against a large wall. The engine will allow him to “move” without making any progress; he remains stationary, and the enemy remains shooting at a fixed point in space behind him? Or, for example, my player can grind if he makes contact with a specific spline-based rail actor; this actor moves him by updating his position to a new one on the spline every frame, not by applying velocity to his capsule. He moves FASTER along the rail than while walking, yet the enemy would nail every shot since he doesn’t actually have a VELOCITY, he’s just changing positions every tick.
For another thing, the VInterpTo node is just simpler. It’s very easy to set up and understand and doesn’t require a lot of math nodes for calculating things like which way to offset the aim position, how much to scale it by based on velocity, etc. The actor aims at a space which is always moving toward the player but cannot reach him unless he is stationary.
The timer would work. You need to set a temporary var to the coordinates each time it’s called, but BEFORE that part of the exec chain you need to set your ‘reporting’ var to that temporary one. Then each time it’s called you’ll get the var which was set on the previous call.
Timers won’t work, though, since storing a location at 100ms intervals is NOT the same as getting the location from 100ms ago. If the timer triggers and then the result is queried 50ms later, the value will be where the player was 50ms ago; if it’s queried 8ms later it will be where it was 8ms ago. Etc.
The only ways to really do this are either using interp nodes (which due to how they work usually point at a value approximately X ms in the past) or a large array with an element set every ms to keep a record of the last couple hundred ms for the query.
Then how about keeping track using DeltaTime and a float variable in the tick? You add delta to the float variable until it surpasses 100 ms. When it equals or surpasses 100 ms you do something like this:
This is just my tired pseudocoding, from the top of my head, so it probably doesn’t work exactly. Hopefully it should be a decent approximation (disregard minimal floating point errors). If you want to get even more precise than this, then I assume you would have to go C++.
Biggest problem I see is that you can’t guarantee that the tick fires exactly on the 100 ms mark because of rendering and other things slowing it down. If you get to a point where you’re overshooting way past the 100 ms mark, then your game is probably performing too poorly for this to even matter.