- Home /
Is it possible to check collision from another object?
The question says everything. Can we detect a collision from an object from another object. For example, a collision that happens to a child object of a body that will make the health go down. Thanks for your answers everyone!
Answer by rsodre · Mar 04, 2017 at 08:48 AM
Here's how I solved it. This is the script that is not on the same GameObject as the Collider, but in some parent of it. It will find the first object with a Collider2D and listen to it's events:
public class ColliderListener : MonoBehaviour
{
void Awake()
{
// Check if Colider is in another GameObject
Collider2D collider = GetComponentInChildren<Collider2D>();
if (collider.gameObject != gameObject)
{
ColliderBridge cb = collider.gameObject.AddComponent<ColliderBridge>();
cb.Initialize(this);
}
}
public void OnCollisionEnter2D(Collision2D collision)
{
// Do your stuff here
}
public void OnTriggerEnter2D(Collider2D other)
{
// Do your stuff here
}
}
And this is ColliderBridge.cs, no need to attach it anywhere:
public class ColliderBridge : MonoBehaviour
{
ColliderListener _listener;
public void Initialize(ColliderListener l)
{
_listener = l;
}
void OnCollisionEnter2D(Collision2D collision)
{
_listener.OnCollisionEnter2D(collision);
}
void OnTriggerEnter2D(Collider2D other)
{
_listener.OnTriggerEnter2D(other);
}
}
Would edit question: _listener l; needs to be _listener = l; And if there was a way to make this more generic. For example if i have a few GameObjects with different names i need to make a script like ColliderBridge for each one of them. All in all, upvoted by me :)
To make more generic, no need to change ColliderBridge, but inherit ColliderListener. Edited, thanks.
Absolutely fantastic!
And you can also do it by creating the class in the same .cs file as ColliderListener so you have the solution in one .cs file alone.
Great, rewarded!
Question. How can you do the same thing in 3D? Do you just need to do Collider and not Collider2D?
ColliderListener 9th line: for me this line get the error that the name colliderbridge cant be found so how can i fix it?
Answer by Eno-Khaon · Jun 13, 2015 at 11:20 PM
As long as you have a consistent means of checking for it, there shouldn't be a problem. If it's a projectile hitting the child object, for instance, the projectile handles the "OnCollisionEnter()" function (or whichever variant) and determines whether the target hit has your script on it. If not, maybe it's the parent object? If it's not that either, then it must've hit something else.
// C#
void OnCollisionEnter(Collision other)
{
MyScript otherScript = other.GetComponent<MyScript>();
if(otherScript == null && other.transform.parent != null)
{
otherScript = other.transform.parent.GetComponent<MyScript>();
if(otherScript == null) // If second test also failed...
{
// Probably hit something other than your player
}
}
}
Reference for calling parent data: http://docs.unity3d.com/ScriptReference/Transform-parent.html
Yeah I guess that's one way of doing it. But in my eyes (maybe because I haven't been doing this for that long) it seems a bit complicating. I've tried this other thing out but I don't know how to verify it. This is what I have found so far
public Collider head;
public Collider body;
public Collider legs;
public float hp = 10;
public static bool alive;
void Start()
{
alive = true;
}
void OnTriggerEnter(Collider other)
{
if (other.tag == "Bullet")
{
if (other.collider == head)
{
hp = hp - (Bullet.hp * 2);
Destroy(other.gameObject);
}
if (other.collider == legs || other.collider == body)
{
hp = hp - (Bullet.hp * 2);
Destroy(other.gameObject);
}
}
I made the public Colliders so i can see which one it was. the colliders are attached to the player and i wanted to say if the player is hit check which collider that got hit and then apply changes. See what I mean?
It kind of chanegs the question... A lot, but it would be easier
That's certainly a reasonable approach. The key difference between the two is whether you're handling it on the dealing or receiving end.
If you handle it on the dealing end, you have a script on the bullet, which checks what it hits and redirects its hit as necessary. Plus, by having the script on the bullet, damage can be defined per bullet to send as damage to the recipient.
If you handle it on the receiving end, you ins$$anonymous$$d have a script per potential receptor target to say whether it was hit by a bullet. This would make the pipeline easier for sending the message directly to the body (without setting up anything like a tag-based system on the body parts), but doesn't inherently define damage values associated with the projectile unless the bullets also have scripts and/or every type of bullet has its own if/else sets.
I certainly have no qualms with the difference in ease of access of the parent parts (and, for that matter, there are surely better ways than I described to handle it from the bullet's perspective), but I think that, looking at the big picture, it would likely be more sensible to treat it as "hit detection" rather than "hit reception" in this case. (i.e. "did you hit them" vs. "did you get hit by them")
Yes I see what you mean and I think that's the best idea too now I think about it. I'll modify a cuple of things and see where i get to.
Answer by zastrow · Jun 13, 2015 at 11:07 PM
I did this by creating a public static Boolean variable and set it to true on collision.
other object scripts have access to the Boolean variable.
Good idea but it will still distribute the damage between them. I'm on an idea here at the moment and if it works I'll share it ;)
Answer by DarkGate · Oct 08, 2017 at 07:38 AM
I have a similar problem where I am instantiating a projectile from a prefab. You can attach a collider to the prefab, and add a script like the following:
public class ColliderDetector : MonoBehaviour {
[HideInInspector]
public bool collided = false;
void OnTriggerEnter(Collider other) {
if (other.gameObject == target) {
collided = true;
}
}
}
Then in your other class, just do a check for it like so
boolean collided = projectile.GetComponent<ColliderDetector>().collided;
If you need to check at runtime, then an event pub-sub system might be the way to go. There are quite a good number of tutorials online for that.
Your answer
Follow this Question
Related Questions
Checking and destroying a rigidbody? 2 Answers
Detect touches on the top right corner of the screen 1 Answer
Detect Side of Collision 2 Answers
Manual Collision Detection... 2 Answers
Particle Collision / Trigger not being reported to On_xx Event 1 Answer