Inheriting smoothly from AIPath

Hi Aron,

I have posted a few times having made a single custom class out of AIBase, AIPath and my own requirements. However I’m noticing that there are issues each time I upgrade to the latest version. On top of that, I miss out on any new features you add (like the ability to slow down to a stop).

I wondered if you could point me in the right direction of overriding AIPath non-destructively so future upgrades will not cause any issues (or just require minor tweaks). I’ve had a look through the code, and can’t seem to find a way to cleanly do some of the things I need. I’m hoping it’s a breeze for you to know where to override!

Here’s what I’m hoping to achieve:

  • No gravity, top down X/Y grid (this is obviously already possible)
  • Essentially a GetMaxSpeed() method (none exists, is there another way to achieve this?) My speed varies semi-frequently, I’d like to get the value each update.
  • Move with a custom controller. Basically take the delta calculated by your class and move my own custom controller with it, in the same way you do CharacterController. (And still use RVO.)
  • No rotation. I don’t want any rotation at all. All movement should be directly towards the desired waypoint.
  • The ability to pause movement instantly (I have a GameManager.IsPaused which I currently just check at the top of FixedUpdate, is it possible to insert the same check somewhere?)
  • The ability to send a Move(Vector2.zero) to my controller when no movement is taking place (as it stores its own velocity etc. that need to be updated)

Thanks for any help you can offer!

Hi

I would recommend doing this in a separate script (i.e you create a new MonoBehaviour which gets the AI using GetComponent, not using inheritance) instead as everything you want is possible.

  1. Already possible
  2. Just set ai.maxSpeed on every Update.
  3. See https://arongranberg.com/astar/docs/iastarai.html#MovementUpdate
  4. Just set ai.rotationSpeed = 0 and ai.slowWhenNotFacingTarget to false, that will essentially disable rotation.
  5. With the code in (3) you can just stop calling that code.
  6. See (3).

Hi Aron,

Thanks for the response, 1, 2 and 3 are simple enough!

However MovementUpdate (and particularly FinalizePosition) seem to contain a lot of the code that I’m hoping to keep intact. When you say create a new MonoBehaviour, do you mean just for 1, 2 and 3? Or can all of this be handled from an external class? As reading through FinalizePosition it seems to move based on the current position. So if I move my agent prior to calling this, the values will be off?

I essentially just want to change line 530 of AIBase to use my own controller rather than a CharacterController. Is this possible using an external script?

I’m really sorry for the basic question, I’m going through the code but clearly missing something!

Hi again Aron,

I had a go at implementing this:

https://pastebin.com/RsbJqBb3

It all seems to be behaving correctly, however I was hoping you could have a skim of it to see if I’ve missed anything, or if I’ve misunderstood?

Additionally my RVOController is on another GameObject, as it’s used by both NPCs and player objects in the game. Would it be possible to make this NonSerialized public instead of protected in future versions? (As I had to do so manually to be able to access the property.) And then in OnEnable test if it’s null first, otherwise the assignment gets replaced.

AIBase
:126 [System.NonSerialized] public RVOController rvoController;
:251 rvoController = rvoController != null ? rvoController : GetComponent<RVOController>();

Thanks!

Hi Aron, just bumping this to see whether you have any issue adding those changes in a future update?

Hi

That looks good from what I can see.

To get the RVOController, why not just GetComponent()?

I do, however I need it set in AIPath. But AIPath clears the value in OnEnable. So I’m hoping you could both give the variable public access, but also check to see that it’s null before getting the component on line 251.