Disable or enable collisions based on object tag Unity 2d - unity3d

I want to disable or enable collision with object in unity 2d game based on its tag. Lets say I have object with tag "foo1" and objects with tag "foo2". If user choose to collide with objects "foo1" then it should not collide with objects "foo2".
How could I achieve this? I tried this:
void OnCollisionEnter(Object other)
{
if (other.tag == "foo1")
collider.enabled = false;
}
But this is not working for two reasons. First object has to have isTrigger set to true (this could not be set for objects that serves as ground) and if I disable entire collider then object will fall through ground.
I am new to unity and I will study it in more details but I am asking for quick help and maybe idea how to do this?

Instead of doing this via tags, you might want to have a look at layers.
By assigning different objects to different layers, you can set them to either collide with each other, or ignore any potential collisions. You can achieve this at
Edit->Project Settings->Physics
where you can edit the layer collision matrix, to enable or disable collisions between layer elements.

Related

Unity 3D collision without physics

In my game I have 2 objects. I want them to be able to collide and not go through each other. Currently Collision is working, but when one object pushes the other, he other starts floating away. I don't want that. How can I get collisions(not going through each other) without the physics(floating away, pushing, etc)?
The component that makes the gameobject react to external forces applied on it is the Rigidbody
-You can configure constraints on your rigidbody so the passive physics (forces coming outside the object, like gravity and collisions) won't work in the axis you block. Only active forces will (like AddForce() method)
Ridigbody Component in Editor with all constraints enabled
-In static objects (like walls, a tree) you can remove the rigidbody components. It will enhance performance too. Only use rigidbody in dynamic objects like characters, vehicles, balls, bullets
-Between A and B object, at least one of them must have rigidbody, or the collision detection won't be possible (in the object which contains the method OnCollisionEnter (or Stay)
But be careful. Without the rigidbody, you won't be able to use the AddForce() method to move object. If you use simply the Translate method on the Transform, the collision detection will become a such unaccurate

Multiple Colliders on Complex Object

I have designed a complex city with thousand of objects like roads, sideways, buidlings, trees, etc. and imported to Unity3d
I want to put colliders over them, so that when player hit them, it should face collision and should not passes though them
Though it has many objects, if i put one by one collider to each object, it will take so much time. Is there any other way i can just select all of them and put collider.
Also, if i select all object and put colliders (Mesh Collider). it is not adding to the object
Please help
Editor Scripting to the rescue. I would write a tool similar to this example. It uses a Menu Item which can be selected via Window -> Collider Tool. It then runs our custom method to find all meshes, which we want to add a collider to, then adds one and also logs which GameObjects were changed.
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
public static class ColliderTool
{
[MenuItem("Window/Collider Tool")]
public static void RunTool()
{
List<MeshFilter> meshes = findObjectsThatNeedColliders();
for (int i = 0; i < meshes.Count; i++)
{
GameObject go = meshes[i].gameObject;
// Add a collider to each mesh and record the undo step.
MeshCollider collider = Undo.AddComponent<MeshCollider>(go);
// Use the existing mesh as the collider mesh.
collider.sharedMesh = meshes[i].sharedMesh;
Debug.Log("Added a new collider on: " + go.name, go);
}
Debug.Log("Done");
}
private static List<MeshFilter> findObjectsThatNeedColliders()
{
// This list will be filled with all meshes, which require a collider.
List<MeshFilter> meshesWithoutCollider = new List<MeshFilter>();
// Get all meshes in the scene. This only returns active ones.
// Maybe we also need inactive ones, which we can get via GetRootGameObjects and GetComponent.
MeshFilter[] allMeshes = GameObject.FindObjectsOfType<MeshFilter>();
foreach(MeshFilter mesh in allMeshes)
{
if(mesh.GetComponent<Collider>() == null)
meshesWithoutCollider.Add(mesh);
}
return meshesWithoutCollider;
}
}
You might need more complex rules about which objects require a collider and which type it should be, but a simple tool can still save you a lot of time before hand tweaking everything.
You should also consider making this selection based. The Selection class can give you a list of all selected objects. Some ideas:
Add a MeshCollider to all selected objects, if one doesn't already exist.
Add a BoxCollider to selected objects and scale it to an approximate size depending on the transform size or bounding box of the MeshRenderer.
My solution is based on your question about how to add a collider to many objects in a large scene. However, this might not be the overall best solution. Maybe too many MeshColliders hurt physics performance. You will most likely want to approximate most of the colliders with boxes and spheres, but of course you can still write a tool to help you with that.

Preventing colliders on the same rig from colliding with each other. But allowing them to collide with other rigs.

I have a prefab NPC which has a physics rig attached to it (to do some specific rag-doll stuff with). I need to avoid the various colliders on the same rig (arms, legs etc) from colliding with each other, but they have to be able to collide with the rigs of other instantiated NPCs.
Is there a way to do this? I know I can avoid all the colliders from colliding by putting them on a separate layer, but I cant create a new layer for every NPC.
Thanks
You can do by setting up IgnoreCollision on your NPC class if you have any
http://docs.unity3d.com/ScriptReference/Physics.IgnoreCollision.html
So simple loop through all colliders in the rig and set up to ignore each other
void Start() {
colliders = GetComponentsInChildren<Collider>();
foreach(Collider collider in colliders) {
otherColliders = GetComponentsInChildren<Collider>();
foreach(Collider otherColider in otherColliders) {
if (collider != otherColider) {
Physics.IgnoreCollision(collider, otherColider);
}
}
}
}
It looks like the only way to ignore collisions without using layers is to use Physics.IgnoreCollision() between a pair of colliders, for each pair.
You can write some code that would automatically register a newly instantiated game object and create these pairs between the new object and the other ones that were registered before, so you wouldn't need to call this method for each pair yourself.
Or, you can use this code that does that for you :) It has its own representation of layer to control how the objects should ignore each other.

How to detect two object collide or not?

I am making one unity game in which two objects having collider in which I have select isTriger and does not have rigid body, if I put the rigid body then they are kinematic object, So that gravity did not effect on that object, Even also i don't want any physic operation on this object also. but I want to detect whether this two object collide which each other or not.
How can I do this ?
When 2 colliders make contact with each other,
OnCollisionEnter2D
OnCollisionExit2D
OnCollisionStay2D
are called for 2D games, likewise for 3D(remove 2D in names) also.
Check out this link: http://docs.unity3d.com/ScriptReference/MonoBehaviour.OnCollisionEnter2D.html
Sorry man, but unity use the phsysics engine to detect collision so you have to add the rigidbody to the item you want to to plug the script.
PS:remeber if you want to detect collisions with Trigger collider, you need to use
void OnTriggerEnter(){
//your code
}
void OnTriggerStay(){
//your code
}
void OnTriggerLeave(){
//your code
}

Compound Collider Trigger

I have a parent object, which has four children cubes. The parent has rigidbody, no collider. The four cubes only have colliders, which trigger tags are set true. I want to handle collision in the parent object. However, it didn't work. I know use onCollisionEnter may work, but I must use trigger. Could anybody give me some ideas?
Trigger colliders are unable to use OnColliderEnter because things pass through them instead of colliding. If you wish to detect when an object enters a trigger collider, use OnTriggerEnter instead.
https://docs.unity3d.com/ScriptReference/Collider.OnTriggerEnter.html
If however you wish to keep the trigger colliders and make them collide only with specific kind of objects, you can add a second set of colliders that are not triggers and use layers to differentiate which objects can collide with them and which ones pass through. You can then go to Edit->Project Settings->Physics and at the bottom at Layer Collision Matrix configure which layers can collide with each other.
https://docs.unity3d.com/Manual/LayerBasedCollision.html