How to check Collision detection for GameObjects of same prefab (Unity) - c#

(For 2D Project)
I created a gameObject and made it a prefab.
Now when the game starts, the prefab is used to instantiate gameObjects and they all should check if they collide with one another.
I tried other unity's collision methods but it didn't work.
They either kept colliding with themselves (their own rigidbody) or it didn't work at all.
I'm new to unity and learning things. I searched every where but didn't get my question solved. I'll appreciate any help, Thank you!
Prefab is loaded and Instantiated as such..
GameObject tile = Instantiate(Resources.Load("Prefabs/Tile") as GameObject);
Its a basic gameObject having SpriteRenderer 2D.
I used Box Collider 2D and Rigidbody 2D components on that prefab -
Inspector
A simple script which has OnTriggerEnter2D(Collider2D other) function to check if it collides..
using UnityEngine;
public class TileCollider : MonoBehaviour {
public Rigidbody2D triggerBody;
void OnTriggerEnter2D(Collider2D other) {
if (triggerBody == null)
return;
if (other.attachedRigidbody == triggerBody) {
Debug.Log("Collision!");
}
}
}
I tried it without any if statements - It triggers collision for the Rigidbody2D of the gameObject (itself)
I passed the Prefab itself to check the collision for - Script in Inspector.
This is where were things get bad. It looks for the rigidbody of its own gameObject but I wanted it to search for other cloned gameObjects from same prefab.

The first thing to look at to solve the problem is to check if your prefabs have tags attached to them.

Assuming you have the TileCollider script attached on your prefab which it looks like it is in the inspector, you are checking if the other.attachedRigidbody is its own rigid body (triggerBody). And an object cannot collide with itself. You should probably check if its own rigid body is not the other.attachedRigidbody. If its not its own rigidbody then you have collision with another GameObject!
I hope I understood your question correctly, Thanks!

There looks to be quite a few errors with your code. First, you've got a triggerBody but it doesn't look like it's assigned. Hopefully you're assigning this manually as part of the prefab arrangement, but you could guarantee this by doing that hookup in Start and throwing an error if it fails to get the Rigidbody, like:
public Rigidbody2D triggerBody;
void Start()
{
if(triggerBody == null) // Would happen if it's not set in the prefab
{
triggerBody = gameObject.GetComponent<RigidBody2D>();
}
if(triggerBody == null) // Would happen if there is no Rigidbody2D attached at all!
{
Debug.LogErrorFormat("Failed to find a Rigidbody2D to use with {0}!", gameObject.name);
}
}
Another issue is that you're asking for collisions, but your code is looking for triggers. Here's a link to an article, but the short version is that if you're checking OnTriggerEnter then at least one of the colliders involved needs to have the IsTrigger option ticked:
Another issue is that you're bailing on the operation if the triggerBody is null. As I mentioned at the start, you're not explicitly setting the triggerBody in your code, so if it's also not set in the prefab then you'd abort here even if the collider options were set correctly.
Finally, and probably most importantly, is this snippet doesn't make sense:
if (other.attachedRigidbody == triggerBody) {
Debug.Log("Collision!");
}
What you're saying here is that you want there to be a collision if the other rigidbody is the same as the local rigidbody. This would ensure the behavior you described in your post,
They either kept colliding with themselves (their own rigidbody) or it didn't work at all.
You're only calling it a collision if they're colliding with themselves! The way to check if it's NOT self-colliding is to make sure the other.attachedRigidbody is NOT equal to the local triggerBody!
What you would want instead would be:
if (other.attachedRigidbody != triggerBody) {
Debug.Log("Collision!");
}

Related

unity text trigger not working as expected

in my game im trying to make text appear on the ui when entering a specific room,but when i try to go into that room nothing happens
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Room_trigger : MonoBehaviour
{
public GameObject UiObject;
public GameObject cube;
void Start()
{
UiObject.SetActive(false);
}
void OnTriggerEnter(Collider other)
{
if (other.tag == "player")
{
UiObject.SetActive(true);
}
}
void Update()
{
}
void OnTriggerExit(Collider other)
{
UiObject.SetActive(false);
Destroy(cube);
}
}
the player controller is based of of brakeys fps controller tutorial.
Three things you will need to check:
Does the player object (the one that the player capsule collider component is attached to) have the tag "player" assigned to it? Is it definitely "player" and not "Player" or "Player1". Note - the TAG of an object is not the same as the NAME of an object.
Is the "Is Trigger" on the capsule collider on the player object ticked/checked? If the player capsule collider is not a trigger then it won't cause OnTriggerEnter to be fired by your Room_trigger attached object. Also check the next point.
If you don't want your player capsule collider to be a trigger (which is highly likely), then make sure that the object your Room_trigger script is attached to has:
a collider that is set to Is Trigger
a Rigidbody component
A couple of other possibilities are that you haven't dragged GameObjects into the UiObject and/or cube fields in the Unity Editor UI but that should throw NullReference errors in the console when you run the game.
Whilst Vasmos is correct, you should compare strings using the Equals() method, that's not going to be the cause of your trouble in this specific case. Comparing strings using == as you've done here will work.
replace
if (other.tag == "player")
with
if (other.tag.Equals("player"))
always use .Equals for comparing strings, otherwise its just comparing if its the same variable
#HumanWrites i figured out what the problem was, the cube wasn't set as trigger, the i watched a different tutorial and he sayed "dont forget to set the collider as trigger" and that fixed it.

My projectiles wont collide with my enemies in a 2D side scrolling Unity project?

As the title suggests, I've literally just started learning Unity recently and I'm practising by making a side scrolling shooter. I've been following a Udemy course about it and (to my knowledge) I've been following the tutor's instructions to the letter, but at the point where he tests his and it works fine, by projectiles go straight through my enemies.
I'm a bit stumped at this point and so I thought I'd post here to see what you guys thought. I bet it's something really simple I've not done.
Please see my projectile code below:
using UnityEngine; using System.Collections;
public class DestroyEnemyAndProjectile : MonoBehaviour {
public GameObject WhiteExplosion;
public GameObject OrangeExplosion;
void Start()
{
}
void Update()
{
}
void OnCollisionEnter2D (Collision2D tempCollision)
{
if (tempCollision.gameObject.tag == "Collision")
{
spawnParticles(tempCollision.transform.position);
Destroy(tempCollision.gameObject);
}
}
void spawnParticles(Vector2 tempPosition)
{
Instantiate(WhiteExplosion, tempPosition, Quaternion.identity);
Instantiate(OrangeExplosion, tempPosition, Quaternion.identity);
}
}
Thanks for your help!
I did post a question to them which got a response, they suggested that perhaps the projectile is going too fast and check there was a Rigidbody 2D attached - both of which were already collect
make sure that the object you're colliding with has the tag "Collision", with the same capitalisation.
If it's not, you can do this by:
1. Selecting the GameObject to be collided with
2. In the top-right, select the Tag property
3. Add tag, click the plus and type in "Collision"
4. Select the GameObject again, and select the "Collision" tag from the Tag property dropdown
Otherwise, if that's not the issue. Make sure the projectile has a type of Collider2D component, and that the projectile, or the object being collided with, has a Rigidbody2D.
First I would like to know what the behaviour of this script curently is. Is the collision method being called, and the projectile goes through the enemy anyway? Or the collision method is not being called at all?
That being said, these are things that you should check in order for collision to work:
Make sure that the projectile and the enemy have Collider2D components attached to them.
Make sure that the projectile and/or the enemy (at least one of them must) have a Rigidbody2D attached to it.
Make sure that the layer of the projectiles and the layer of the enemies are set to collide in the collision matrix (You can find the collision matrix in Edit->ProjectSettings->Physics)
Make sure that the enemy GameObject has its tag set to "Collision".
P.S: Welcome to Unity where issues like this are, in fact, usually caused by something super simple that you probably missed.

Get gameobject of unity collider when it is attached to a rigidbody

I have a game object that has a rigidbody and then a group of sub game objects with sprites and colliders where each collider is attached to the parent's rigidbody.
This works well for the physics and collisions as the entire group of objects will bounce and collide off of the scenery.
However, when two groups collide I want their to be damage on one of the individual sub game objects.
I have a OnCollisionEnter2D(Collision2D coll) on each of the sub objects(Which have the collider on them) however, when they collide with another group using coll.gameObject the returned game object is always the parent and not the individual sub object.
Long Story Short:
Is there any way to get the game object of a collider when it is attached to another game object with a rigid body?
Note: I have seen some solutions that use a ray cast to find the object but it seems like a lot of unnecessary work.
Note 2: I have also seen options that use trigger but i prefer the collision as it handles physics as well.
private void OnCollisionEnter2D(Collision2D coll)
{
Debug.Log(coll.gameObject.name); // Showing the parent
ShipPiece sp = coll.gameObject.GetComponent<Piece>(); // Looking for the individual piece
if (sp != null)
{
// Apply the damage to the other piece based off the weight of this piece
coll.gameObject.SendMessage("ApplyDamage", weight*10);
}
}
Obviously I can can the first Piece in the collision as it is the class where OnCollisionEnter2D exists, but I cannot figure out a way to get the second Piece which its colliding into.
You're trying to get the gameObject property of the Collision2D object when you really want the gameObject properties of the Collider2D itself. Collision2D has the collider and otherCollider properties that you can use:
private void OnCollisionEnter2D(Collision2D coll)
{
Debug.Log(coll.collider.gameObject.name);
Debug.Log(coll.otherCollider.gameObject.name);
...
}

Falling Blocks on player touch - Unity (C#)

I'm making a game in unity for a school project. I'm stuck on this one part where I want a block to fall and be destroyed once a player has touched the block and moved to the next. Having so much trouble and would love some assistance.
The concept of what i'm aiming for can be seen here: http://www.coolmath-games.com/0-b-cubed
On each block, you'll need to attach a script which contains the OnCollisionExit () method (reference). Pass in the collision parameter (see reference) and use the collision info to confirm that the object leaving the collider is the player (eg tag the player with a player tag in the inspector and check the collision's collider's tag).
In this method, place your code for making the block fall.
Make sure you've added colliders to your objects so that they interact. If you run into problems, post back some code and I'll get back to you.
Actually you do not need to detect collision here. It is not neccessary. Just compare base cube position with player cube position in x,z plane (there should be only difference in Y-axis since player cube is over base cube). No need for collsions here. Than you attach script to all base cubes checking for playercube to hover other them (position check) and than on playercube next movement you attach rigidbody to basecube and destroy it after a second. Simple:)
EDIT
The code should look like this. More or less.
GameObject playerCube; //this is reference to Player object
bool playerEnter = false;
bool playerLeft = false;
void Start()
{
playerCube = Gameoject.Find("PlayerCube"); // here you put the name of your player object as a string. Exactly as it is in the hierarchy
}
void Update()
{
if(playerCube.transform.position.x == transform.position.x && playerCube.transform.position.z == transform.position.z)
{
playerEnter = true; // this checks if player stepped on the cube
}
if((playerCube.transform.position.x != transform.position.x || playerCube.transform.position.z != transform.position.z) && playerEnter == true && playerLeft == false) //checks if player left the cube
{
playerLeft = true; // we do this so the code below is executed only once
gameObject.AddComponent<Rigidbody>(); // ads rigidbody to your basecube
Destroy(gameObject, 1.0f); //destroys baseCube after one second
}
I think that more or less that should do it. In the final game I probably would use coroutines for your task. Also you need to think how do you check if the cube already was destroyed, I mean how will your game detect if player can step on the next cube - does it exist or not?
EDIT 2
Hard to tell what will work or not without your hierarchy, your code and knowing what do you want to have exactly. Study this code - it will work after some adjustments to your needs

OnCollisionEnter2D fails to send information

I am testing OnCollisonEnter2D and it doesn't seem to want to work for me.
I have box collider 2d and rigidbody2d's on both of my game objects and again, it fails to send a message to the console.
using UnityEngine;
using System.Collections;
public class CollisionAndResetSystem : MonoBehaviour {
void OnCollisionEnter2D(Collision2D coll) {
if (coll.gameObject.tag == "Cube")
print ("hit");
}
}
I took this strait from the Scripting API and it doesn't want to work.
There is no problem in the script. Problem must be in your "boxcollider2d" component. Please check the size of "boxcollider2d", change it to something like 100 in both x and y and in both the gameobjects also. Please check in the scene view if you can see the "boxcollider2d" gizmo. You have to make "boxcollider2d" as big as your gameobjects, then only OnCollisionEnter2D will work.
If you dont need your objects to be affected by physics
then set isKinematic = false and Gravity Scale = 0 and remember to attach your OnCollisionEnter2D script to your gameObject
A Couple of things:
void OnCollisionEnter2D(Collision2D coll) {
if (coll.gameObject.tag == "Cube")
print ("hit");
}
Make sure you are comparing with a correct tag (keep the case sensitivity in mind).
Make sure the gameObject that is being compared has this tag linked. May be you defined the tag but there is no gameObject with this tag.
Check the size of your collider component, it should be enough big to receive touch event.
Hope it helps!
Most important is that check on which gameobject your script is attached,Cross check that your script are attached to your gameobject that you are trying get collision with. And Use Debug.log() too in place of Print(),Hope this help.

Categories