Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Pathfinding: Component Based vs Object Oriented

Discussion in 'Editor & General Support' started by delzhand, Oct 15, 2012.

  1. delzhand

    delzhand

    Joined:
    Jul 20, 2012
    Posts:
    26
    When I was using XNA, I wrote a genericized A* pathfinding system for a project. It was comprised of an interface iPathable and a class Pathfinder. iPathable had functions for finding neighbors and calculating heuristic costs. Pathfinder's primary feature was a function that returned a List<T>, where T was iPathable.

    But in Unity I'm struggling to wrap my mind around the problem as a component based solution. I have a battlefield composed of hexes. Each hex has a script attached to it that contains its X and Y values. It wouldn't be hard to just write the methods contained in iPathable as non-generic methods in the hex script. But if, in theory, I had a battlefield comprised of hexes and other shapes, that wouldn't work, because Pathfinder would have to be rewritten to return a List<Hex>.

    What's the best way to do this?
     
  2. Loius

    Loius

    Joined:
    Aug 16, 2012
    Posts:
    546
    Can't you just have Hex and OtherShape both implement iPathable? Then they should count as iPathables (and can be returned in a List<iPathable>). They can still implement their own 'next in line' solutions.

    Code (csharp):
    1. class Hex implements iPathable {
    2.   function GetPath() {
    3.     for ( pathable in AllPathables ) {
    4.       if ( pathable.GetDistanceFrom() )....
    Let each class define its own distance/etc functions; don't try to access member variables of pathables that aren't "this".
     
    Last edited: Oct 15, 2012
  3. delzhand

    delzhand

    Joined:
    Jul 20, 2012
    Posts:
    26
    Well, Hex already implements MonoBehavior. C# doesn't support multiple inheritance, right?
     
  4. Loius

    Loius

    Joined:
    Aug 16, 2012
    Posts:
    546
    Iiiiiuuummmm I dunno.

    You should be able to extend and implement, though.

    This right here is valid in Javascript, though. I'm pretty sure it should be valid in C# as well:

    Code (csharp):
    1. class Hex extends MonoBehaviour implements iPathable
     
  5. jc_lvngstn

    jc_lvngstn

    Joined:
    Jul 19, 2006
    Posts:
    1,508

    Yes, you can do this. In this example, you are deriving from one class, and implementing one interface. You can derive from only one class, but you can implement many interfaces.

    One suggestion: Would it be better overall to create a separate class which contains the shape gameobjects, and also contains the path implementation for that shape?

    Code (csharp):
    1. class PathStep
    2. {
    3.     private readonly GameObject _pathGo;
    4.     private readonly ShapeLogic _pathLogic;
    5.     private GameObject PathGO;
    6.     private ShapeLogic PathLogic;
    7.  
    8.     public PathStep(GameObject pathGo, ShapeLogic pathLogic)
    9.     {
    10.         _pathGo = pathGo;
    11.         _pathLogic = pathLogic;
    12.     }
    13.  
    14.     public float PathCost(...)
    15.     {
    16.         return _pathLogic.PathCost(...whatever goes here);
    17.     }
    18. }
    19.  
    20. // Shapelogic would handle the logic for different shapes, as far as pathing goes. Like a circle, vs a hex, vs a square.
    21.  
    22. //Path controller would handle returning pathing results, and also would initialize to hold all pathable locations.
    23.  
    24. internal class PathController
    25. {
    26.     // Initialize the internal data from the shapes in the world.
    27.     // All pathable gameobjects might be children of one gameobject, and this
    28.     // would initialize its internal information from that parent.
    29.  
    30.     // Call this to get the path steps from point a to b
    31.     private List<PathStep> GetPath(PathStep startPath, PathStep endPath)
    32.     {
    33.         return new List<PathStep>();// return the actual path steps here.
    34.     }
    35. }
    This may totally not work for you, though. I haven't done any pathfinding (yet) :) But it might keep you from having to include your path logic in with your gameobjects (maybe a big deal, maybe not).
     
  6. delzhand

    delzhand

    Joined:
    Jul 20, 2012
    Posts:
    26
    Huh! I guess it was a pretty simple solution. I'm not sure where I got the idea that you could only inherit from one class or interface.

    C#
    Code (csharp):
    1. public class Hex : MonoBehaviour, iPathable