Collider2D.OnTriggerEnter2D not firing - c#

I assigned a projectile to my enemy that shoots at the player, and this projectile has a collider2d which I marked as a trigger. And it doesn't seem to recognize my player collider. The projectile just goes through my player.
void OnTriggerEnter2d (Collider2D other)
{
Player _player = other.GetComponent<Player>();
if (_player != null)
_player.ChangeHealth(1);
Destroy(gameObject);
}
My Player Components:

There is a small typo in your method name. The "d" in "2d" needs to be capitalized.
onTriggerEnter2d ---> onTriggerEnter2D
void OnTriggerEnter2D (Collider2D other)
{
Player _player = other.GetComponent<Player>();
if (_player != null)
_player.ChangeHealth(1);
Destroy(gameObject);
}

Without seeing your code, I will make the assumption that your 'player' object does not have a Rigidbody2D attached to it.
I strongly suggest you read the docs on colliders and how they interact with each other but as a very brief summary; In order for collisions to occur between two objects, at least one of them must have a Rigidbody or Rigidbody2D attached to them.
Attach a Rigidbody2D component to your player (you may want to mark it as kinematic so collisions don't affect it's position/rotation etc.) and it should then work as you expect.

I would change your code in OnTriggerEnter2D to this:
void OnTriggerEnter2D (Collider2D other)
{
// In your scene you have just two objects, so not really required now
// may be interesting for you when you have more objects there
if(other.gameObject.CompareTag("Player"))
{
//Here add .gameObject to refer the GameObject which contains the collider2D
Player _player = other.gameObject.GetComponent<Player>();
if (_player != null)
_player.ChangeHealth(1);
Destroy(gameObject);
}
}
Besides that. You have added an image of the components in the GameObject Player. Add the same for the Bullet, or at least check this two things:
The bullet is also in position Z = 0
The bullet has got a collider2D with the isTrigger feature as
true (checked), to detect the player.

Related

OntriggerEnter not called playerController

I have a script that is a attached to a box, the box has two colliders on for physics and one (slightly bigger) for detecting OntriggerEnters when my player walks over it. I have a script attached to the box that does the following:
public class ColorChangeCollision : MonoBehaviour {
private GameObject Element;
private Color32 BaseColor, CollisionColor;
private Material ElementMaterial;
void Start () {
Element = this.gameObject;
BaseColor = new Color32(255,255,255,255);
CollisionColor = new Color32((byte)Random.Range(0, 255),(byte)Random.Range(0, 255),(byte)Random.Range(0, 255), 255);
ElementMaterial = Element.gameObject.GetComponent<Renderer>().material;
}
private void OnControllerColliderHit(ControllerColliderHit other)
{
Debug.Log("collision...");
ElementMaterial.color = CollisionColor;
}
private void OnTriggerEnter(Collider other)
{
Debug.Log("enter");
}
private void OnTriggerStay(Collider other)
{
Debug.Log("staying..");
}
private void OnTriggerExit(Collider other)
{
Debug.Log("left...");
ElementMaterial.color = BaseColor;
}
}
Main problem OnTriggerEnter or OnControllerColliderHit is never called nor are the other trigger events..
See below for an image of the setup of the box, and its components:
See here for my player who should be calling the OntriggerEnter or OnControllerColliderHit function of the box:
EDIT I modified all the elements to the suggestions of #Programmer. But the OnControllerColliderHit event is still not being called.. (note this function is attachted on the box )
There are 3 issues on how you setup your scene and your code:
1. You are missing a Rigidbody. This should be attached to the "Cube" GameObject since it's not ok to attach Rigidbody to GameObject with a CharacterController.
2. You have two BoxColliders attached to one GameObject ("Cube"). Do not do this. This can cause many issues including a callback function being called multiple times or non at-all.
What to do when you need both trigger and non trigger collider?
Create an empty child GameObject put the trigger there. You can do that.
3. You are using CharacterController so you should remove the OnTriggerXXX callback functions. When using CharacterController, it recommended to use it's callback function OnControllerColliderHit.
void OnControllerColliderHit(ControllerColliderHit hit)
{
Rigidbody body = hit.collider.attachedRigidbody;
......
}
4. CharacterController is not mean to be used as triggers. They are used to detect collisions.
You have two options to make it detect triggers:
A. Remove the isTrigger from the "Cube" Object
Or
B. Add a child empty GameObject under the CharacterController then add the CapsuleCollider or any other collider to it. You don't have to mark it as isTrigger since the "Cube" is already marked as so. You also shouldn't have Rigidbody attached to this child collider.
Create a new layer named "CC" and make the CharacterController and the new child GameObject to be in the "CC" layer. Go to your physics collision matrix settings and make it so that "CC" layer cannot collide with "CC" layer. This will make sure that the CharacterController doesn't detect collsion from tis child object.
You can now use your OnTriggerXXX callback functions to detect collision between the CharacterController and the "Cube" object.
One of them needs to have rigidbody to detect collisions.

Unity - Detection between two different types of colliders is not working

I have two different type colliders in a gameobject: a sphere collider for a trigger and a capsule collider for a hit raycast. I have this code for the OnTriggerEnter but nothing happens when the player enters in the sphere trigger. What am I doing wrong?
public GameObject canvasTesoroFoto;
public GameObject canvasTesoroDatos;
private GameObject Player;
public SphereCollider sCollider;
public CapsuleCollider cCollider;
void Start()
{
Player = GameObject.FindGameObjectWithTag("Player");
sCollider = GetComponent<SphereCollider> ();
cCollider = GetComponent<CapsuleCollider> ();
}
void OnTriggerEnter(Collider other)
{
if (other == sCollider) {
if (other.gameObject.tag == "Player") {
canvasTesoroFoto.SetActive (true);
canvasTesoroDatos.SetActive (true);
}
}
if (other == cCollider) {
Debug.Log ("HitCollider");
return;
}
}
To make it work you will need:
In the obstacle: The Sphere collider with the is trigger checked
In the player:
A collider
A rigidbody
Besides, if the scrip is in the obstacle, the collider other will refer to the player NOT to the OBSTACLE. So you should do directly like this:
void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Player") {
canvasTesoroFoto.SetActive (true);
canvasTesoroDatos.SetActive (true);
}
}
Based on your comment. In that case you should consider add the trigger in the collider of the player, to detect the sphere of the obstacle, and leave the trigger for the capsule.
And in case you need that both colliders in the obstacle are triggered, what you can do is to create a sphere gameobject as child of the obstacle, make it transparent and add there the script and sphere collider. Then keep the collider in the obstacle itself. Then you can exchange information between script in the sphere and the obstacle if necessary.
But as far as I know, there is not way to distinguish which of the colliders in the gameobject triggered OnTriggerEnter() if both has got checked "is trigger"
Edit: based on your comments, I imagine a situation where the GameObejct of the colliders is some kind of enemy which may be hit by raycast and at the same time can crash with the Player (for example to take life from him).
The best approach is to make is trigger the collider of the Player, to detect the sphere collider of the enemy in a script attached to the Player. Then uncheck is trigger the sphere collider in the enemy. And just leave is trigger the capsule collider to detect raycast.
In this tutorial you have a nice example of this:
https://unity3d.com/learn/tutorials/s/survival-shooter-tutorial
Make sure that your game object for Player also has attached collider

How do i use the OnTriggerExit function and check inside if my ship collided?

I want to check if my ship/s collided and not some other objects.
So this is the script that i attached to a GameObject and the GameObject have box collider and Rigidbody. The box collider: Is Trigger set to on. And he size is 500 600 500. The Rigidbody i didn't change anything and Use Gravity is on.
When running the game i have many cloned gameobjects each one Tagged as "Sphere" but in the script when i check the tag name the collider is "Untagged".
What i'm trying to do is to make sure the collided object is a cloned spaceship.
using UnityEngine;
using System.Collections;
public class InvisibleWalls : MonoBehaviour {
public float smooth = 1f;
private Vector3 targetAngles;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnTriggerExit(Collider other)
{
if (other.tag == "Sphere")
{
targetAngles = other.transform.eulerAngles + 180f * Vector3.up;
other.transform.eulerAngles = Vector3.Lerp (other.transform.eulerAngles, targetAngles, smooth * Time.deltaTime);
}
}
}
This is the part where i'm trying to check and make that a ship is collided:
if (other.tag == "Sphere")
But when using break point it does stop on this line when the pbject collided but the other.tag the tag is "Untagged".
Screenshot showing the object spaceship cloned that is tagged as "Sphere"
And this screenshot showing the gameobject with the box collider and the rigidbody
From what i can gather,
You CrashLandedShip objects do not have colliders, adding colliders should work.
Also note that for triggers to work, One of the objects (the terrain or the ship) has to be a non-trigger (2 triggers will not cause a collision or trigger event)
So try this : Add a sphere collider to your CrashLandedShip_UpsideDown prefab and make sure they are not set with IsTrigger
The rest of your code looks fine.

Physics.IgnoreCollision Doing Nothing

I'm trying to make a BTD game. Since different balloons (enemies) have different speeds, they collide with each other when traveling on the path. I'm currently using this code:
void OnCollisionEnter (Collision coll)
{
if (coll.gameObject.tag == "Enemy")
{
Physics.IgnoreCollision(coll.collider, gameObject.GetComponent<SphereCollider>());
}
}
However, it doesn't appear to be working at all. The enemies still collide with each other. On the otherhand, the collision with the enemies and bullets from towers is working.
void OnTriggerEnter (Collider col)
{
if (col.tag == "Bullet")
{
CurrentHP -= col.GetComponent<TackShooterBullet>().Damage;
}
I've tried layer-collision (enemies to same layer & unchecking of the same layer collision in the layer collision matrix, but that doesn't work either. The enemy contains a sphere mesh filter, sphere collider, mesh renderer, rigidbody, material, and 2 scripts. Is there a better way to avoid collisions between the enemies. I'm asking this question since I've seen duplicates, but their solutions aren't working at all. I can provide more of my code if needed.
Edit for Clarity: Again, what I'm trying to accomplish is have the enemies be able to go through each other.
Edit (Fixed Problem): I found out to avoid Enemy Collisions, I could also remove rigidbody. However, removing the ridigbody would mess up the bullet --> enemy trigger in the enemy class. Therefore, I just wrote the collision between bullet & enemy in the bullet class instead.
using UnityEngine;
public class TackShooterBullet : MonoBehaviour {
private GameObject target;
public float Damage;
// Use this for initialization
void Start () {
target = transform.parent.GetComponent<TackShooterRange>().Target; // Target = Enemy[0] (First Enemy To Enter Range - Enemy is Removed from JList when exiting Range)
}
// Update is called once per frame
void Update()
{
Damage = gameObject.transform.parent.transform.parent.GetComponent<TackShooterLimitingRange1>().level * 20; // Upgrade Level * 20 = Damage Done
if (target == null) // If Enemy Exits Range
{
Destroy(gameObject); // Destroy Bullet
}
if (target != null) // Enemy Exists In Range
{
transform.position = Vector3.MoveTowards(transform.position, target.transform.position, 20 * Time.deltaTime); // Bullet Follows Enemy
Destroy(gameObject); // Destroy Bullet Upon Contact With Enemy
target.GetComponent<HealthOfEnemy>().CurrentHP -= Damage; // Enemy Loses Health
}
}
This allowed me to remove the OnTriggerEnter & OnCollisionEnter methods as well as the RigidBody from the Enemy Class as stated before, so these properties no longer affect the collisions between Enemies.
Unity has a built in function for easier collision detection called layer-based collision detection:
https://docs.unity3d.com/Manual/LayerBasedCollision.html
The documentation is really good. Just comment if you need further clarification.

Unity C# GameObject collides with another GameObject

I have a invicible GameObject called trigger, and when my Hero collides with it, a chandelier falls.
I want to give the chandelier a Rigidbody so it falls, and you can collide with it and maybe use it.
If you can explain to me how collision works and show how to do something if to gameObject collides its would realy cool still new at Unity.
using UnityEngine;
using System.Collections;
public class Collider : MonoBehaviour {
public GameObject chandelier;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
//When my hero collides with trigger go to the fall function
void OnTriggerEnter (Collider other) {
if (other.tag == "Trigger")
{
fall();
}
}
//Add Rigidbody to the GameObject called chandelier
void fall ()
{
chandelier.rigidbody.AddForce(1, 1, 1);
}
}
For collision to work at least one of your colliding gameObjects must have a rigidbody attached to it, since you using OnTriggerEnter method, the following setup should work:
First object:
-collider (Marked as trigger)
-rigidbody (Marked as kinematic)
Second object
-collider (Marked as trigger)
Then when the objects collide, "OnTriggerEnter" method will get called and you can add the physical
rigidbody to the second object, please notice that you cannot add a rigid body as you mentioned in your post
// This will cause to Exception if there is no rigidbody attached
chandelier.rigidbody.AddForce(1,1,1);
So basically you have to options:
-Add a rigidbody to your game object through Unity editor and set it to kinematic, then remove "Is kinematic" flag in your collision method, like this:
rigidbody.isKinematic = false;
-Add the rigidbody after collision using the following code:
gameObject.AddComponent< Rigidbody >();
Afterwards you can add the required force or if you only want it to fall, simply add gravity to the rigidbody:
rigidbody.useGravity = true;

Categories

Resources