Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Vunpac · Nov 18, 2015 at 12:01 AM · pathfindingdesigndesign-patterns

Decoupling with a path-finding algorithm

Alright so I have created my pathfinding class for a TD game I am working. So far it calculates the grid using Dijkstra algorithm. and has functions that take a grid position and does the calculations as if a wall were placed or removed all internally

eg. bool AddWall(Vector3 position) returns true if the wall was placed and false if it wasn't (nodes have a occupied bool to see if placing a wall would enclose an occupied node)

So from here I am unsure exactly how to handle linking this code to interact with creeps. Should I have functions that take a position and just return the parent and sets occupied on it's own with many different variations of these setters and getters? Or should I allow creeps direct access to node information?

The creeps need to know where to go (current nodes parent) and nodes need to know if they are occupied. So both kind of need information from each other. But I want this information to be as loosely coupled as possible.

So My question is what would be a good way to design this code to allow them to communicate without giving too much information? Currently the creep script is empty because I can not for the life of my decide on how this should be designed.

I know design can usually vary from person to person, so keep in mind I am looking for a loosely coupled design (unless there are strong reasons to avoid such)

Thanks in advance!

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by JoshuaMcKenzie · Nov 21, 2015 at 03:10 AM

In short, to answer your question about where to connect the data between Nodes and Creeps...With Decoupling set aside your suggestions are completely fine and its mostly up to preference.

I'm actually building my own TD game where the path-finding is dynamically updated as the player shapes the paths on their map. Due to the nature of my game I use a multidimentional linked-list to construct a graph and then employ an altered version of the biconnected component algorithm along with Djikstra's Algorithm for path-finding. and due to the complexity of some of the creeps, defenses, spells and debuffs, decoupling was very important in my game.

If you're worried about properly decoupling, then a couple of Design principals to start with:

Each class should have one and only one responsibility (or as few as possible)

This principal is a big game changer and it can explode the number of classes your project can have. The improved flexibility it will grant you will likely cost you in terms of complexity and debugging, just be aware of the trade-offs. In this specific case you'll likely want 3 classes:

  1. Creeps: manages actual movment and other behavior.

  2. Nodes: Tracks who it's current neighbors are.

  3. Agent: connects Creeps and Nodes. controlling how Creeps path through the map and informing nodes then they are occupied.

In this design example, Node will have a reference to an agent (or null) to determine if its occupied, though you could have easily had the Agent store a Dictionary of nodes to creeps instead. Having the Creeps connect to an Agent class allows to find the preferred path to a destination via the neighbors its node is linked to.

program to an interface, not an implementation

Interfaces are a great way for decoupling your classes while at the same time enabling extensibility. For example, you have a map with roads and rivers. You might have one type of enemy that only walks on the road, while another that can only swim, and finally a third that can fly. All three movement modes have a common behavior, they find the next waypoint (even if how they get their next waypoint is found differently). you can simply create an interface "IAgent" that has a method Next() which your adapter classes (WalkableAgent,SwimableAgent,FlyableAgent) all implement. Your creeps can polymorphically call their agent.next() to find their next way-point without even knowing what type of class they are referencing. this has a benefit of allowing you to near effortlessly swap out agent types (maybe you have an air tower that forces a flyer to walk) and the creep is none-the-wiser.

With interfaces the implementing classes are abstracted away from the calling class so that the caller only knows what it needs to know. the more you have a class reference an interface over a concrete class the more decoupled you can make your project.

but like I said before, decoupling will make your project's complexity skyrocket. if you have multiple programmers (even if you don't you might in the future) then documentation is key because following decoupled code when it breaks is a headache. So its best to find compromises where you want flexibility + extensibility over simplicity + development time. Don't forget your scope!

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Vunpac · Nov 27, 2015 at 01:13 AM 0
Share

After doing a lot of digging I came to a lot of similar ideas that you mentioned here. I was mostly looking into Design Patterns in order to get a better idea. $$anonymous$$y path-finding is set up almost identical to yours but I don't use a linked-list. I just use a jagged array.

I too wanted dynamic updates, that's why I found Dijkstra's the best, since you only need to find all paths once, then just update nodes related to where the tower was placed.

The interface is the Strategy Pattern. I was thinking it is definitely perfect for creep typing. Right now my path-finding class handles everything including the grid (so I ended up having setters and getters to set a node to occupied or get a nodes parent.

As it stands my Agent class gets creeps positions and if their position has changed to a new node and there are no other creeps on the Node then set it to not occupied. I guess I just need a lot of agent classes to couple things together when need be but still having all the core classes decoupled from everything.

I also want to thank you for taking the time to explain your answer great depth and detail. It was very helpful!

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

33 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Design and Naming Patterns for Unity 0 Answers

Where to put debug methods and variables 0 Answers

Need advice on Design 0 Answers

Best practice for adding specific attributes to an object but not all of them 2 Answers

Creating one class or using polymorphism? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges