private void OnTriggerEnter(Collider other)
{
if(other.tag == "Melee")
{
Destroy(gameObject);
}
}
The code shown above is the code in my enemy script that lets it die when the player's knife hits it. The knife is tagged as Melee. When the knife hits the enemy, it doesn't get destroyed.
Things you can check.
Is your collider 3D?
At least one of the two colliding objects must have a Rigidbody.
Also make sure the typo in "Melee".
One more thing, Make sure your collider is in Trigger Mode.
Related
(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!");
}
I have a moving platform script. My platform is frozen unless I collide with it, then it starts moving. I have a platform effector so I can be able to jump on it from under it and not hit my head on it.
However OnCollisionEnter2D is getting called even though I'm under it and haven't physically collided with the one way collision. It's as if it's a trigger.
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.GetComponent<Player>())
{
Debug.Log("On Collision Enter");
//CameraFollow.instance.useFixedDeltaTime = false;
Player = collision.gameObject;
PlayerScript = Player.GetComponent<Player>();
amountOfTimesPlayerCollided++;
}
Even if my head just touches the collider area (without hopping on the platform) the method gets called and "On Collision Enter" is logged into the console.
How do I make it so that OnCollisionEnter2D only gets called when I physically collide with the platform?
Thanks!
I'm using the latest version of Unity 2021 but this has happened to me with other versions in the past I'm pretty sure.
This callback is sent when an incoming collider makes contact with this object's collider.
I think "contact" and "touch" have the same meaning, so this is an expected behavior.
only gets called when I physically collide with the platform?
I guess you want to detect an impact, so you may also pay attention to the velocity between two objects when the collision occurs.
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.GetComponent<Player>()
&& collision.relativeVelocity.magnitude > THRESHOLD)
{
......
}
}
Game Screen
Teleportation Code
Child Objects And Their Original Location
I'm new to Unity, and so after taking just some regular online courses for Unity2D I wanted to mess around with adding in different features, the first of which I decided to do was something like in Portal, where a projectile spawns two connected portals you can teleport between. However, I've run into an issue. When I'm teleporting my character, sometimes, usually when I'm teleporting too quickly but can happen at any time, the child objects to the Player game object tend to shift, and I don't understand why. **I'd like to:
Know why the offset between the parent and child objects are changing through teleportation.
Know how to fix this issue, preferably in code I can easily understand as a beginner to Unity. Also preferably in a way that doesn't involve me constantly appending the child objects to the parent object through transform position with the added offset, though if it's the simplest solution I'm not against trying it.**
Something worth noting is that the offset change is different as well, I have a Child Object called Feet which detect the Ground for jumping, which seems to remain at the location of the previous portal when it first breaks. However, another child object called Gun which is where the projectiles spawn from seem to only move down a little bit, meaning there's inconsistency in how they are offset when they break. It might be because the Feet has a collider, but I'm unsure, don't know enough, and only felt it was worth mentioning.
[SerializeField] GameObject otherPortal;
Portal otherPortalComponent;
BoxCollider2D boxCollider2D;
bool firstEntered = true;
// Start is called before the first frame update
void Start()
{
boxCollider2D = GetComponent<BoxCollider2D>();
otherPortalComponent = otherPortal.GetComponent<Portal>();
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (boxCollider2D.IsTouchingLayers(LayerMask.GetMask("Player")) && firstEntered)
{
Teleport(collision.gameObject);
otherPortalComponent.SetFirstEnteredFalse();
}
}
private void Teleport(GameObject obj)
{
obj.transform.position = otherPortal.transform.GetChild(0).transform.position;
}
public void SetFirstEnteredFalse()
{
this.firstEntered = false;
}
private void OnTriggerExit2D(Collider2D collision)
{
this.firstEntered = true;
}
To simplify the question, the position of the child objects relative to the parent changes when I instantly change the parents position sometimes, why does this happen and how do I fix the issue without simply using transform.position in an Update method to constantly append the child to the parent, if possible.
I would look at your OnTriggerEnter2D method's if statement for a solution.
private void OnTriggerEnter2D(Collider2D collision)
{
if (boxCollider2D.IsTouchingLayers(LayerMask.GetMask("Player")) && firstEntered)
{
Teleport(collision.gameObject);
otherPortalComponent.SetFirstEnteredFalse();
}
}
Because you are using OnTriggerEnter this method will only be called with your feet since your player's main collider isn't a Trigger. This means that your collision variable that you call your Teleport method on is actually your feet object, not your player's body object. So you are changing the offset of your feet from your player in your Teleport method.
I would try changing your collision method to OnCollisionEnter2D(Collision2D)
which would pick up your player's base collider when it enters and not the feet collider.
void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.GetComponent<Player>() && firstEntered)
{
Teleport(collision.gameObject);
otherPortalComponent.SetFirstEnteredFalse();
}
}
Since the Player script is on the same object as your base player collider you can do a simple GetComponent<Player>() call to check if its the player object. Though you could still use the Layer to check if you want.
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.
Hi I have question for which I haven't been able to find an answer thus far. I have two game objects next to each other and each one has a collider. Now when a third object collides with one of the game objects then the direction/bounce of that third object takes a different direction based on which gameObject/collider it touched. This works fine for most part when the gameObjects are hit cleanly but when it collides in the middle of both colliders then it takes a direction in the middle, this causes a problem for my game.
I wanted to know how to make sure that only one collider/collision is triggered (doesn't matter which one) when any other objects collides with both i.e. when it hits the join of both gameObjects.
Collision happens at the beginning of the frame so you can detect the collision and reset in the LateUpdate:
private bool hasCollided = false;
void OnCollisionEnter(Collision col)
{
if(this.hasCollided == true){ return; }
this.hasCollided = true;
}
void LateUpdate()
{
this.hasCollided = false;
}