Download

Limiting a trace's direction?

For a while now, I’ve been working on a setup for taking out enemies by jumping on them a la Super Mario and I’ve managed to get it mostly working through use of BoxTraceByChannel, except for one glaring issue.

That one issue being that when the player & enemy collide with one another from the side, the jump collision I set up is initiated, causing the player to bounces upwards upon contact and killing the enemy in the process. This shouldn’t be happening, as the jump collision is intended to only initiate when the bottom of the player character comes into contact with the enemy & not from the side.

Is apparent that the source of this problem is the Box Trace, as the trace doesn’t seem to be limited to a downward trajectory, rather the trace will always trigger upon contact regardless of which direction the enemy collided with the player character.

So what I want to do is limit the direction of the box trace to a downward trajectory, so that the jump collision will only occur when the player comes into contact with the enemy from above and not from the side. Elsewhere I got the suggestion of using a line trace in addition to the box trace to limit the box trace’s direction. The problem is that I have limited experience in general with using trace nodes so I have no idea on how to make this work. Can anyone with a better understanding Unreal Engine 4’s inner workings help me out here?

Player Jump Collision blueprint:

Enemy Jump Collision blueprint:

Blueprint for bouncing the player upon landing on a enemy:

you need to do a dot product on the hit normal and positive Z. this will give you a float of how “upward” is the hit coming from.
but i would do a linetrace because its a lot easier to use and debug

1 Like

Wouldn’t it be easier to have a small collision piece attached to player’s feet. So it only collides with what they step on? Example at the very bottom. Collision channels come in handy here.

Also, this way you wouldn’t need to trace and cast every frame but detect overlap event as they happen; and you can have many collision zones - another one placed higher up should you wish to headbutt a mushroom, for example.


Apart from being a flat plane, your trace looks fine and the whole thing should work OK with traces. Potentially even better if you need more control.

  • perhaps the box trace exceeds the dimensions of the character? That’d explain the incorrect detection to the sides. How Super Plump is this Mario in relation to the 30 uus box trace?
  • enable Draw Debug Type to visualise the trace - For One Frame

So what I want to do is limit the direction of the box trace to a downward trajectory, so that the jump collision will only occur when the player comes into contact with the enemy from above

When you say downwards, do you mean directly down or account for angles? If that’s the case you’d need dot product vectors as didel23 mentioned.

1 Like

That was actually the first thing I tried when I started. The problem though was that a collision box would frequently wouldn’t be able to communicate fast enough before the player’s capsule component came into contact with the enemy. The result was that the player character would end up randomly taking damage before the jump collision could take effect, a problem I haven’t had since I switched over to the box trace.

On top of that, I’m pretty sure the collision box still had problems with not being directionally limited. I seem to recall that while it didn’t have the problem of setting off the jump collision when my player character came into contact with a enemy from the side, the player character could still kill enemies by jumping upwards through their body, which shouldn’t be happening.

I have no idea actually, as far as I’m aware of I just need to limit the direction of trace directly down, like this:

jump_example

How do I set up the line trace though? As I mentioned in my initial post, my experience with setting up trace channels has been limited to the box trace for the jump collision and that’s about it. As such, I don’t really the expertise on how to implement a line trace limited to one direction from the box trace I already have set up.

Use the z velocity of the player. If the velocity is negative, the player is falling. So only allow killing the enemy if the player’s z velocity is negative.

Alternatively, you could use one-way collision, like how platformers work where you can jump through a platform but land on it when falling down. If the player lands on the enemy’s “platform” (their head), then you can kill the enemy.

1 Like

I’m hesitant to use downward velocity because in theory, it would mean that if an enemy were to come into contact with the player from below like in the picture below then the player would take damage:

jump_example_2

When I would much rather the enemy be one to take damage.

jump_example_3

Which reminds me, I should have mentioned this earlier but some time ago I got the suggestion elsewhere of using this setup for a line trace that would supposedly limit the direction of the trace downward.

However, my implementation hasn’t worked out well as it instead breaks the jump collision, resulting in the player character always taking damage when try to jump on an enemy.

The problem appears to be here:

The reason why is that the various balloon blueprints shown in the above screenshot are not hooked up to that setup and the jump collision still works unlike the enemy blueprints.

I was wondering if the basic idea of this setup of using a line trace with Distance (Vector) could be used to limit the direction of the box trace, assuming I can figure out why the current setup is breaking the jump collision on the enemy blueprints.

Any ideas?

My issue with this is that as I outlined in the previous post, attaching a collision box to my player character didn’t work out very well with inconsistence response times from the box resulting in my player character occasional taking damage before the jump collision could initiate. I’m afraid that attaching a collision box to the enemy is also going to result in similar, random delayed response times causing the player to take damage when they shouldn’t.

Okay, since I have absolutely no idea on what I’m doing, I just decided to apply some random line trace blueprint into my jump collision setup just to see what would happen.

The good news is that the jump collision didn’t end up breaking but it didn’t fix the trace collision problem. On top of that, I’ve noticed that the area of the jump collision box trace has shrunk with my player character taking damage from jumping on the enemy if they land off-center.

I’m sorry but I really, really don’t know anything about setting up traces and I am completely lost :confounded:.

Ok, I made what you were trying to do:

Steps

Player Character:


Enemy Character:

Enemy Capsule & Box Component:
image

Enemy Viewport (added a box to give player more room to land on):
image

Result:

2 Likes

So I finally found a solution that fixes the box trace collision issue.

Its not the one that midgunner66 proposed above. While I appreciated the effort they went to in coming up with it, I was reluctant to use it as it would require a complete teardown of the various blueprints involved, which were working for me aside from the minor collision issue.

Unfortunately, while the above solution fixes the problem that I originally created this topic for, it doesn’t fix another related issue that I completely forgot about until now.

You see, the current solution limits the direction of the box trace to the Z-axis so that the jump collision can no longer be triggered by the player coming into with the enemy from the side, but the Z-axis restrictions do not distinguish up from down. The result is that the player character can damage enemies by jumping up through them, which should not be happening. I tried doing the same thing in some Mario games and this does not happen in any of the ones I tried. In those games, Mario can only do damage to an enemy if the enemy collides with Mario from underneath and not from jumping through the enemy.

Is there anyway that I can expand upon my current fix to limit the box trace so that the jump collision will only occur if the player comes into contact with an enemy from above?

I was wondering if perhaps the Break FindFloorResult part of midgunner66’s solution could be incorporated into my current setup?

Or is there something else perhaps a bit more basic that I’m unaware of that can be used to fix this issue?

Yes, the current floor is what the player is standing on (it is a trace), so it can only be below the player. You then check if the floor (what the player is standing on) is an enemy, and if so, kill it. So the only way the player can kill an enemy is to land on them; this also works if the enemy jumps into the player from below.

You can alternatively do like the others said and use a dot product. But a simpler way would be to say "if the player has collided with an enemy, and the player is higher than that enemy, kill the enemy; i.e. if (HitActor == Enemy && Player.Location.z > Enemy.Location.z) Enemy.Kill().

1 Like

My concern with going with the collision based on the player being higher idea is that if you’re using a collision capsule for the enemy, then you would end up with a rather small area for the player to land on.

jump_collision_example

One could use a box collision instead but it would then make it rather awkward to size the hit box so that isn’t too big or too small in relation to the enemy model.

jump_collision_example_2

jump_collision_example_3

So I think dot product might be the way to go if it can be used to limit the box trace to a one-way trace on the negative Z-axis.

The question is how do I accomplish this? I tried looking at a tutorial video on the subject and I came away only more confused :frowning:.

You could try something like this:

edit: ‘The opposite of UP’ is mislead above; essentially, directions from below would return False but we can use values different than 0, of course.

The dot product will allow you to decide what angles are acceptable for the Jump to happen. And if you prefer working with angles:

180 is a perfectly vertical landing. 150 gives you a 30 degrees wiggle room to each side of the perfect landing, resulting in a 60 degree cone which would look similar to this:


Can’t recall how stuff is oriented in the 2D template. Here’s hoping that UP is actually UP, there, too.

1 Like

Thank you for the response. The problem though is that I noticed that you’re using velocity in your setup, which is something I want to avoid as I mentioned in an earlier post:

In addition to the above example, there’s also my concern that if the player is in mid-air moving upwards and an enemy came into contact with the player from below, the player would take damage.

jump_example_4

jump_example_5

jump_example_6

Ideally, this should be movement direction, not velocity. It was easier to demo the example this way. If you use direction of the movement, you will not even need to Normalise.

Do note that I’m using the Velocity here as if was direction, so it would work well in the context of the abovementioned example. It’s addressing this very issue precisely.

Or did you try it and it does not work as intended? You can see it in the animation. That’s all the script there is for this. The static mesh has no collision, the box collision is overlapping all.


Admittedly, 2d is not my strong suit. But you asked about dot product - that’s how you’d use it.

1 Like

No, I haven’t tried it because I need to figure out how to incorporate the dot product into the player’s jump collision setup & not the target in order to simplify things.

Jump Collision:

You can get direction from Trace Start / End, dot product it against enemy’s up vector:

1 Like

Well, I have absolutely no idea on what I’m doing at all :confounded:. I tried implementing Everynone’s dot product implementation into my jump collision setup and only succeeded in completely breaking the jump collision.

All of this trace by channel & dot product stuff just so mind-numbingly frustrating :face_with_symbols_over_mouth: to deal with. I desperately need help with this as I just said, I have no idea what I’m doing, and I’m completely lost in how to make any of this work.

Is there a reason we’re box tracing on Tick for this? I understand that you may need it for something else but it seems redundant here. Do tell, perhaps I’m missing the point.

Why not approach it from the event-based side of things, as suggested above. Besides that, there’s a couple of unknowns in your script:

  • are we sure velocity can be used (does the owner have a movement component - probably, but we can’t tell from the pic)
  • why not use Trace Start / End for direction since we have it and want to rely on it (you understand what it’s supposed to do here, surely!)
  • the up vector should be the enemy’s up vector, not yours - may be irrelevant but we have no clue how things work / rotate in your game. If you look at the snippet I posted, you’ll notice it’s from the enemy’s point of view.

Consider the following:

  • this in the player

  • and results in:

  • and the debug, if you’re into that kind of thing:

Apologies if I missed something critical discussed earlier on.

1 Like

Okay, I think I finally got it working.

Sorry for the mess, anyways, I had to modify the degree angle from 150 to 120 as I felt it was too narrow but otherwise everything else seems to be working.

Thanks for the help!

1 Like