Download

Moving and performing action when in action range

Hello everyone,

First things first, I’m an UE noob. I’m trying to make a simple mechanic similar to Diablo 3/ POE / Torchlight style topdown ARPGs where, when I click an object, I will move there and perform an action. If the object is a weapon, I will pick it up. If the object is an enemy, I will attack. If none of those, just move.

I laid down the logic here:

And then I implemented this in my PlayerCharacter according to the logic above:




Right now the only problem is that when I’m not in range of the object, the Player moves to clicked location ( object location) and stops. I have to click again to pick up the weapon or attack the enemy. How would I do this so that while moving towards the object I check if I’m in range, and when I’m in range I perform the action? So for instance I click the weapon and when I’m in range for picking up the weapon I pick it up without needing to click again.

Can anyone help with this? Like I said, I’m an UE noob.

Also a video if this helps understand the issue better:

Thank you !

You could measure the distance as you approach and trigger as soon as the condition is met. But, instead, you could experiment with something along the lines of:

  • once an actor has been clicked on, have the interface spit out its reference (perhaps not every actor is worth approaching)
  • if it’s a valid interaction target, store its reference
  • the player has a sphere collision whose size is adjusted by the selected actor’s minInteractionRange var
  • as the player approaches, the sphere collision will eventually overlap (unless something blocks the way, ofc)
  • compare the selected actor with the one from the overlap → fire interface function to Interact

You can, of course, employ something a tad more nuanced than crude actor comparison:

  • give the selected actor a DoThingsToMe tag
  • give the selected actor a DoThingsToMe flag
  • or, better, set collision channels on both - the collision sphere & the actor - to the very same value; so no other filtering is needed

As a bonus, you may use the sphere to scoop gold off the ground automagically, avoiding carpal tunnel syndrome D1 gave too many people.


Pretty sure there’s a bunch of other methods but the above is what I’d try first. See if it delivers.

Btw, it’s all very nicely explained. A somewhat rare sight. Neat.

2 Likes

As I studied your info I came to a similar first conclusion as Everynone, but with a timer. Youd click on the weapon and the character walks to it (as already happens) but as it begins moving, a timer is started (Set Timer By Function, check looping) that checks the distance between the character and the item (dist) and when dist<=pickuprange, the function fires the ‘pick up weapon’ event for the character and clears the timer.

My thinking when confronted with something like youve described would be to assume that the “go to the weapon I clicked on” bit of the code is fine, but the “pick it up when you get close enough” bit isnt. As a first-step pseudo-debugging method, Id add print strings after virtually every node of a tricky script (helpfully labelled, obvs) to see how far the execution chain goes and if the software isnt butting up against a boolean with a bad check, a missing reference, or something else that I forgot to do.

1 Like

First of all, thank you both for replying ! You really made my day. Being a noob it wasn’t very easy to understand your suggestions but you gave me more stuff to think about which is always good. I’m going to try both your suggestions to see which works best for what I’m trying to do and which one can be expanded further.

I started with @Bevman00 's suggestion with using a timer since it seemed a bit easier to implement. Had a few hiccups but I’m at a point where it works as suggested, I’m not sure that the way I did it is correct or a bit overkill.

Here is what I understood:

I had to do some digging since I’ve never used timers before and also decided to use an event rather than a function because it felt weird to have a function do 2 things : check for range and interact when in range. Did I get this correctly, that the function/ event is supposed to do both?

Thank you for you suggestion, it’s doing what I wanted. Here’s a video with how it looks right now:

You can see at the end of the video already my next problem with the tick event, I’m thinking once I have an animation for attacking I can just loop the animation if mouse button is clicked

@Everynone I will now try your suggestion and get back to you because I really liked how you explained it and the gold example is something I would like to have in game. I’m not sure I can get this working by myself but I’ll get back to you when I hit a wall.

Again, thank you both for you help, really appreciate it !

Back with an update. I tried my best with @Everynone 's suggestion and I have something working although I think I’m not implementing it correctly probably because I didn’t understand it very well.

First of all, I wanted to clarify a bit why I’m using different ranges for Interaction and Attacking, maybe I’m thinking about this wrong.
The plan is to have an interaction range for picking up items, talking to NPCs etc. and an attacking range depending on what weapon I’m using. That way when I click an interactable, I move there and interact when I’m interaction range and when I click an enemy, I move towards him and attack when I’m in attack range ( for example, if I’m using a bow this range would be higher than a sword).

So I tried to follow your suggestions with using sphere collision to determine the Player Range.

  • I created 2 spheres, one for InteractionRange and one for AttackRange.

*If I understand correctly, I should create 2 new object collision channels : interactable and enemy. I set my interactables to Interactable object type and my enemy to Enemy object type. Then I set the collision on the spheres to ignore all, but overlap the object type I want to interact with. Is this correct? I have no experience with adding new collision channels … *

  • When I click , I check the object type, if it implements the interface I store it and check what it is. Then, I move there. Now is the part where I got confused, implemented something but this doesn’t look right to me ( it works though). Lets say if item is already in range, I check what’s already overlapping my sphere and compare with the clicked object, if it’s there I interact. If it’s not in range, once it overlaps with my sphere I check if it’s the clicked object and Interact. Here’s how I did it:

-Then same thing for attack range sphere

This doesn’t look right, does it? It works though, here’s the video :slight_smile: :

Red sphere is attack range, green sphere is interaction range

Again, thanks for all the help so far, I now have 2 ways of doing this that both work just need to understand them better and refine them.

1 Like