• 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 Randomeda · Oct 14, 2015 at 02:17 PM · collisioncollisionscollidebest practicescollision issues

Best way to implement an advanced collision system?

Hi everyone, we are working on a small space shooter-like game for android, which has multiple types of objects in a scene, all with its own behaviour when it comes to collision with another object. For example, we have bullets that are destroyed when they touch anything, walls are never destroyed, but they do interact with other gameObject (physical and trigger), and enemies / player that can be hit multiple times before dying.

We don’t have problems understanding the basic collision system Unity has, so far we used all kinds of rigidbody and trigger colliders to achieve what we want, for instance we used trigger colliders on bullets, rigidbody physics colliders on enemies, and kinematic / static colliders on walls (obstacles).

The problem is, we want our gameObject to have different behavior depending on which object it collides. For example, we want to do nothing with the wall, when it is hit by a bullet, but we want to destroy an enemy when it is hit by a bullet. But also we dont want to destroy an enemy, when it hits another enemy. What we reeeeally want to avoid is this code (which i have seen many-many times in tuts and examples):

 void OnTriggerEnter(Collider other) 
 {
     if (other.tag == "Enemy")
     {
         //do something
     }
     if (other.tag == "Player")
     {
         //do something different
     }
 }

In addition to comparing strings is the seedbed for errors, as our project grows bigger and bigger, collisions become totally out of control, even in this simple game. This way it is hard to tell why one object did (or did not) destroy another, and we have to look into 6-8 attached scripts to get a clue about what went wrong. So far we used layer based colllision detection to limit interactions between objects, but its not enough since we want different things to happen even when objects are on the same layer.. ..So we developed our own collision matrix, which tells what happens when two types of objects collide. This is very complex and very ineffective but readable.

The big question: what is the best way to implement a structure for our after-collision behaviour, that is more effective and readable than the above, less error prone, and it can be used in other projects as well? We dont fear interfaces, inheritence, or any type of structure (we use them in our project), we just cant figure out what’s the best way to implement this in Unity. Collisions are so basic in any game, i’m sure there are someone who went through all the trouble and can give us some ideas :)

Thank you 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
0

Answer by Dave-Carlile · Oct 14, 2015 at 02:39 PM

Seems like some sort of lookup table of classes or delegates would work here... Here's a pass at it...

 Dictionary<ColliderObjectType, Dictionary<ColliderObjectType, ColliderHandler>> collisionMatrix;

 // ColliderObjectType would be whatever key you need to lookup the type of object
 // Collider handler is a delegate type or class type
 // The outer dictionary is the collision source, the inner dictionary is what was collided with

 // add a collision handler
 void AddCollisonHandler(ColliderObjectType source, ColliderObjectType target, ColliderHandler handler)
 {
     Dictionary<ColliderObjectType, ColliderHandler> handlers;
     if (!collisionMatrix.TryGetValue(source, out handlers)
     {
         // no handlers for source, so add it
         handlers = new Dictionary<ColliderObjectType, ColliderHandler>();
         collisionMatrix.Add(source, handlers);
     }

     // handlers is a reference to the handlers for this source, add the target
     // probably want to check for duplicates and such
     handlers.Add(target, handler);
 }

 // get a collision handler given source and target keys
 bool TryGetHandler(ColliderObjectType source, ColliderObjectType target, out ColliderHandler handler)
 {
     handler = null;

     Dictionary<ColliderObjectType, ColliderHandler> handlers;
     if (collisionMatrix.TryGetValue(source, out handlers)
     {
         if (handlers.TryGetValue(target, out handler))
         {
             return true;
         }
     }

     return false;
 }


In Unity's collision event you'd get the source and target keys and use them to get the handler...

  ColliderHandler handler;
  if (TryGetHandler(source, target, out handler)
  {
      handler(source, target, .... other stuff as needed ...);
      // or if it's a class...
      handler.HandleCollision(...);
  }
  else
  {
      // no collision handler for this combination - error, ignore, etc.
  }


This is effectively an implementation of your collision matrix, but makes it data driven instead of a bunch of hard coded logic. Depending on how you do the object keys (I was thinking types, but could just as easily be strings) you could even set this up in a config file, or the inspector or whatever.

...untested code, doubtless doesn't handle various edge cases... other normal caveats...

I guess the key here is the lookup table concept. Add your various combinations to some sort of data structure that can ultimately give you a delegate or class that handles that particular combination.

Is this the best way? Can't really say, but it's what I'd do until I learn something better :)

Comment
Add comment · 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

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.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Player registering collisions where there are none 0 Answers

How to do collision of external objects on script? 1 Answer

Check If Any Objects In Your Game Are Colliding? 1 Answer

Calculating collision behavior while using lerp 0 Answers

Collision problem 0 Answers

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges