3
\$\begingroup\$

I'm trying to deal with units (generated from the same prefab) dealing damage to each other on collisions. Each Unit has both a Collider2D and a trigger on the front, that deals damage to other units that enter it.

I drew a small image (with Paint, sorry) to better illustrate what I mean and want. Desired Outcome

The problem I am having is that when a collision occurs (one unit enters the trigger of the other), both units damage each other, meaning Unit 2 also deals damage to Unit 1.

I have seen that you can create a separate gameObject as a child of the unit and attach the trigger to this gameObject.

However, the number of units will be very high so if possible I don't want to double the number of gameObjects used by units.

Also, the amount of damage dealt is calculated from many other parameters from many other scripts on the units and doubling all those references doesn't look like an elegant solution.

Any Ideas? Thanks

\$\endgroup\$
2
  • \$\begingroup\$ Do all units move around? If two units are not colliding, and after both units move in a frame, now they both collide diagonally with each other, should they both receive damage? \$\endgroup\$ Nov 20, 2019 at 15:29
  • \$\begingroup\$ They all CAN move around. but yes, In the case you mentioned they should both deal damage to each other. \$\endgroup\$ Nov 20, 2019 at 16:44

3 Answers 3

2
\$\begingroup\$

Also, the amount of damage dealt is calculated from many other parameters from many other scripts on the units and doubling all those references doesn't look like an elegant solution.

You can have a reference to the unit and call a method of that unit, removing the necessity to copy all of the stuff.


  1. First and maybe the most easiest solution in case your other Collider is not trigger. Is to use isTrigger which would tell you if the collider that invoked this method is the one that is trigger.
private void OnTriggerEnter(Collider other)
{
    if (other.isTrigger)
}
  1. Create a child GameObject attach trigger collider to it and a script that would notify main object of that collision. To differentiate between colliders, if you have many of them, you can give those objects tags, id and any other identification approach...

If you don't want to create another GameObject as a child then you could ask yourself a question "What are the conditions under which the collision damages a unit?". When answering this you will come up with methods to check if those conditions are satisfied.

  1. Raycasting, one of the methods to check if condition is satisfied. If you know that a collider in case of damage event would be in front of the object raycasting or in any other direction you could then determine which entity should receive the damage.

  2. Any other type of collision casting. Similar approach to Raycasting, but using Physics.BoxCast() and other things alike.

  3. Vector comparison. This one is very similar to Raycasting, but instead of using Physics we can compare two vectors of the GameObjects that collided. If one is pointing to another then it's probably the vector that should do that damage based on conditions of inflicting the damage [basically if direction to other GameObject and active GameObject forward direction align - then the one pointing towards other is the active].

  4. Getting the contacts of collision and using this information to determine a damage inflicting collider.

  5. ... Other methods that depend on what information you are provided with, on the state of the game and on conditions.

\$\endgroup\$
0
\$\begingroup\$

I think you are using OnCollisionEnter / OnCollisionStay which are triggered for any colliders instead of OnTriggerEnter / OnTriggerStay which are triggered only if any collider collide with a trigger collider in your gameobject.

So OnTriggerEnter or OnTriggerStay would only be triggered if any collider (trigger or not) is colliding with your Trigger collider.

With this, if anything collide with your weapon trigger, you should damage it.

OnTriggerStay(Collider other)
{
    Damage(other.GetComponentInParent<Unit>()); // Damage would remove hp from the given unit
}

Docs on those colliding functions OnTriggerEnter OnCollisionEnter

\$\endgroup\$
2
  • \$\begingroup\$ No, I was already using onTriggerEnter \$\endgroup\$ Nov 22, 2019 at 13:25
  • \$\begingroup\$ The problem I have is that both Units are executing the DamageOther() function inside the OnTriggerEnter Event \$\endgroup\$ Nov 22, 2019 at 13:26
0
\$\begingroup\$

I would just use a child object with one collider for its Rigidbody and a separate child object with a collider for the damage effect.

If you really want to use just one collider, then you could use the OnCollisionEnter event and then use collision.GetContacts to find out how the objects collided and implement your game mechanics accordingly.

If your game needs to handle a very large number of objects, then you might want to consider to not use GameObjects but instead use Entities with the new Entity - Component - System architecture. But keep in mind that the whole feature is still in a preview state, which means it is poorly documented, poorly supported by the editor and might constantly change with every update (the link I just posted does actually have a lot of information which is already outdated, but it still gives a good introduction into what ECS actually is).

\$\endgroup\$
2
  • \$\begingroup\$ I looked at ECS, but isn't it bad for high interactivity systems ? Because every entity can act on and influence every other entity, and other parts of the system \$\endgroup\$ Dec 22, 2019 at 14:15
  • \$\begingroup\$ @Caussan That's actually one of the use-cases ECS was invented for. There are some impressive videos of physics simulations with thousands of rigidbodies around. The new Havoc based physics engine (which is only available for entities) promises even more performance. \$\endgroup\$
    – Philipp
    Dec 22, 2019 at 18:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .