npruehs / ue4-rts

Real-time strategy plugin and showcase for Unreal Engine 4.
MIT License
747 stars 151 forks source link

Double click for attack prompts attack outside of allowable range #110

Closed JaredP94 closed 4 years ago

JaredP94 commented 4 years ago

Hi @npruehs,

I believe I've found a bug when issuing an attack order on a target unit twice. This then allows the attacking unit to begin firing out of the allowable range whilst simultaneously moving towards the acceptable range.

I stepped through BT_RTSPawnBehaviourTree and found that it is correctly evaluating the IsInRange task until the second attack order is given. This appears to restart the HasAttackOrder sequence and somehow gets to the UseAttack task. I debugged the IsInRange task and it correctly returns false until the attacking unit is actually within range so I'm not quite sure how the behaviour tree is getting short-circuited.

Video of the issue can be viewed here.

On a side note, I also noticed that the target unit did not attack a nearby enemy unit whilst idling within the acquisition range. I haven't investigated it much further as yet but thought I'd mention it whilst we're dealing with the behaviour tree.

Let me know if you require any additional info :)

JaredP94 commented 4 years ago

Hi @npruehs,

I decided to do a bit more digging tonight. When issuing an attack order, the controller loops the IsInRange decorator until the attack radius is reached. Issuing another attack order on the same target then seems to cause the parent selector of the IsInRange decorator to move to the next child, which is the FaceTarget and UseAttack tasks. This explains the shooting whilst still moving towards the attack radius.

I'm still unsure of how the second attack order causes this to happen, I took a brief look at RTSPawnAIController.cpp but it'll probably take a bit more time to spot the cause.

A very hacky "solution" is to simply add a second IsInRange decorator alongside the first IsInRange decorator. This prevents the bug from occurring, regardless of the number of duplicate issued attack orders.

The image below should provide any additional clarity if needed :)

image

npruehs commented 4 years ago

Good find! :)

I've applied a different fix in b328e68c67f7e01696fe1c84170c8ed62f1802d5: Adding an IsInRange decorator to the following sequence seems more useful, as this fights another potential issue we've experienced in A Year Of Rain: If moving into attack range fails (e.g. because the target is unreachable), the selector would allow the unit to attack anyway.

So here's how the fix looks like:

SecondRangeCheck

Let me know if that works for you as well!

JaredP94 commented 4 years ago

Hi @npruehs ,

Definitely a simpler approach through the behaviour tree :)

Thanks for looking into this!