Announcement

Collapse
No announcement yet.

Get the position of an Actor where it was 100ms ago

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Get the position of an Actor where it was 100ms ago

    Hi,

    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?

    Thanks,
    Ben
    Unreal Meetup Franken - Unreal Engine 4 Meetup
    Hands for VR - Space HDRI Skyboxes [Marketplace]

    #3
    Unfortunately this is the same as storing the value every 100ms:
    Click image for larger version

Name:	DELAY.jpg
Views:	1
Size:	18.4 KB
ID:	1075430
    Unreal Meetup Franken - Unreal Engine 4 Meetup
    Hands for VR - Space HDRI Skyboxes [Marketplace]

    Comment


      #4
      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.

      Comment


        #5
        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.
        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......

        Comment


          #6
          Originally posted by KVogler View Post
          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.

          Comment


            #7
            situations where the player is running against a large wall. The engine will allow him to "move" without making any progress; he remains stationary,
            That is the point. You have to compare the enemy view direction against the player movement, not his view direction.
            But the movement direction would be interpolated by two locations.... I see..

            Maybe you could just delay his firing, so the enemy is a top accurate aimer, but a bit slow on the reflexes....

            Comment


              #8
              Why not use a looping timer for the original question?
              Programmer, Rigger, Animator - Demo Reel 2015 - My RnD / WIP thread - www.dennylindberg.com
              Worked on: Kitten'd - Guardians of Valor (Android, iOS)

              Comment


                #9
                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.

                Comment


                  #10
                  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.

                  Comment


                    #11
                    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:

                    FVector PreviousPosition = CurrentPosition; // CurrentPosition is "last" update, so we remember it before overwriting it
                    FVector CurrentPosition = GetActorPosition();

                    // "Correct" the difference in the "timer" by interpolating previous and current position.
                    float Overshoot = FloatTimer - 0.1; // Maybe 120 ms, so overshoot is 20 ms.
                    float LerpAlpha = 1 - Overshoot/FloatTimer;
                    CurrentPosition = LERP(PreviousPosition, CurrentPosition, LerpAlpha); // Now we should have a decent approximation of where it was at 100 ms

                    FloatTimer = FloatTimer - 0.1; // The "timer" should continue from it's "overshoot"
                    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.
                    Last edited by Denny; 04-30-2015, 06:11 PM.
                    Programmer, Rigger, Animator - Demo Reel 2015 - My RnD / WIP thread - www.dennylindberg.com
                    Worked on: Kitten'd - Guardians of Valor (Android, iOS)

                    Comment


                      #12
                      Thanks all for your input!
                      I went with Denny's solution (lerping as the magic ingredient). It works best and most accurate - thanks Denny!
                      Unreal Meetup Franken - Unreal Engine 4 Meetup
                      Hands for VR - Space HDRI Skyboxes [Marketplace]

                      Comment


                        #13
                        Cheers! I'm glad I could help. Thank you for the challenge.
                        Programmer, Rigger, Animator - Demo Reel 2015 - My RnD / WIP thread - www.dennylindberg.com
                        Worked on: Kitten'd - Guardians of Valor (Android, iOS)

                        Comment


                          #14
                          Originally posted by Denny View Post
                          Why not use a looping timer for the original question?
                          Hello denny, couldn't find a way to contact you, I have some questions about character rigging, do you have an email I could contact you with?
                          Marketplace Assets

                          Advanced Mobile Input: Marketplace Page | Support Thread ――― Easy Input Remapping: Marketplace Page | Support Thread
                          Multiplayer Blueprint Chat System: Marketplace Page | Support Thread ――― Closing Credits System: Marketplace Page | Support Thread
                          Minesweeper Template: Marketplace Page | Support Thread ――― Maze Creator: Marketplace Page | Support Thread

                          Comment


                            #15
                            You can send me a private message if you click my name. I would prefer not to post my email in public to avoid spam bots.

                            Edit*
                            I sent you a PM.
                            Last edited by Denny; 05-07-2015, 04:27 AM.
                            Programmer, Rigger, Animator - Demo Reel 2015 - My RnD / WIP thread - www.dennylindberg.com
                            Worked on: Kitten'd - Guardians of Valor (Android, iOS)

                            Comment

                            Working...
                            X