I am currently learning how to make games in Unity and I want to detect when a Child's collider is being triggered to apply the damage to the thing being hit. But I'm confused about how it works.
Does the Parent's OntriggerEnter detect the trigger event of the Child Object?
And how do I know the trigger comes from the Child and not the Parent?
And which Child's collider got triggered?
The Parent's collider is not triggered but the Child's collider is. Also the Child object doesn't have a rigidbody attach to it
I don't have enough reputation to comment so I'm going to answer it.
It's been answerd here as well I think : Collision Layer Matrix and Parent/Child object relationships.
If the child collision is not inside of parent collision you don't need to set IsTrigger = true for parent collision, just try different layers for you collisions.
Here is Unity documentation : https://docs.unity3d.com/Manual/LayerBasedCollision.html
What you talk about is called self-collision. One way of handling this is to ignore certain colliders, take a look at the documentation here.
If I understood you correctly you have an GameObject hierarchy like so:
parentGO (contains player mesh and Capsule Collider 2D)
|-childGO (contains attack mesh and Mesh Collider 2D)
I'd attach to the childGO a script, which should register collisions on its polygon collider and notify the weapon script on the parentGO of the object being hit. The weapon can then deal the damage to the target.
I know most likely You got your response, but It is also good to mention, that maybe You should think about separating these object and attaching them to new GameObject, that have a script holding both colliders - that might be more reliable and easy to read.
You can use Collider2D.IsTouching(Collider2D other);
Here is documentation for IsTouching
Or write custom script that uses the observer and notify the main GameObject that the collision occurred.
private Action _onGameObjectCollided;
private void OnTriggerEnter2D(Collider2D col){
if(col.gameObject.CompareTag("TAG")
_onGameObjectCollided?.Invoke();
}
public void AddOnColliderEnterObserver(Action observer)
{
_onGameObjectCollided += observer;
}
public void RemoveOnColliderEnterObserver(Action observer)
{
_onGameObjectCollided -= observer;
}
And inside new GameObject:
collider.AddOnColliderEnterObserver(MethodToCallOnTriggerEntered);
Related
in the game I am trying to make there is a level with moving platforms that make the player object a child for the duration of the collision.
private void OnCollisionEnter2D(Collision2D collision)
{
collision.transform.SetParent(transform);
}
private void OnCollisionExit2D(Collision2D collision)
{
collision.transform.SetParent(null);
}
Player does have a DontDestroyOnLoad method so he can move between the levels freely. However that method disappears whenever i come into contact with one of the moving platforms so the game crashes while going to the next level because the camera is using the player object to follow him and without player is missing a reference. I am pretty sure that the cause is that it becomes a child object of the platform and the platform itself does not use that method. Is there a way to keep the DontDestroyOnLoad method no matter the circumstances fn the player object?
The scene cannot be loaded automatically. It is controlled by you, so you can unlink the player's parent before switching to the next scene.
player.transform.SetParent(null);
DontDestroyOnLoad(player.gameObject);
SceneManager.LoadScene("next scene");
I am new to using unity and am having a real problem getting trigger collisions to register.
public void OnTriggerEnter2D(Collider2D other)
{
print("collide");
if (other.CompareTag("Fish"))
{
print("Caught");
}
}
I have 2D polygon colliders and a rigid body on both items. I have also got 1 set a trigger(have tried having both as trigger). However one UI item is a sprite and the other is an image.
Both items are also tagged with "fish"
Would really appreciate any help.
Thanks
There are four things I can think of which need to happen so that OnTriggerEnter gets called:
The two objects' colliders need to actually be overlapping. Just because their rendered pixels are overlapping, doesn't mean their colliders are overlapping. This can be checked in the editor. Their colliders are indicated with a green outline in the Scene tab. If you don't see anything, make sure the button labeled Gizmos is turned on.
The two objects need to be in physics layers which are set to collide with each other. You can check this in Edit > Settings > Physics2D > Layer Collision Matrix.
Both objects need to have Rigidbody2D components attached. Make sure these aren't Rigidbody components, as those are for 3D physics.
The object which contains the OnTriggerEnter2D event needs to have isTrigger = true.
I've tried several things to do.
First I've checked recommendations from another post.
In nutshell:
Checked if I have rigid body at least for one of objects
Checked layers
Checked tags
Played with "is trigger".
Finally, the solution was to add script to object via create and add component button and not to drop written script to it. Have no idea, but for me that was the solution. Even it was same script.
Both a Sprite and an Image can collide with another Image. What might be wrong is that your sprite may look like touching the image however in the scene the canvas might be far away, so camera may deceive you. Here is the sample code for my tests:
Script that moves the Sprite:
private Rigidbody2D _rigidbody;
private void Awake() => _rigidbody = GetComponent<Rigidbody2D>();
private void FixedUpdate()
{
if (Input.GetKey(KeyCode.A))
{
var movement = -transform.right * Time.fixedDeltaTime * 250;
_rigidbody.MovePosition(transform.position + movement);
}
if (Input.GetKey(KeyCode.D))
{
var movement = transform.right * Time.fixedDeltaTime * 250;
_rigidbody.MovePosition(transform.position + movement);
}
}
Trigger script on image:
private void OnTriggerEnter2D(Collider2D other)
{
Debug.Log(other.name);
}
Nothing helps for me, but in my case I didn't know there was a place in code that breaks collision layers (that is do not change the collision matrix settings visually):
Physics2D.IgnoreLayerCollision(...
Check that too and make sure it is not called.
I'm developing a simple 2D Unity game (which I'm very new to so sorry if this is a silly question!) in which my player can eat its enemies by colliding with them. This works fine as I'm just selecting the "is trigger" component for the enemies and using this code in my Player class:
private void OnTriggerEnter2D(Collider2D other)
{
Debug.Log("Hit detected");
Destroy(other.gameObject);
transform.localScale += new Vector3(x, y, z);
}
However, this means the colliders placed around the border of my background image aren't stopping the enemies. What's the best fix for this?
I don't understand very well your question. However it seems that your collisions are not working. So, remember that for have collisions actually taking place in your game you need to use colliders and that one of the two elements participating in the collision need to have the rigidbody component.
That will make the physics work in the engine, which triggers dont.
To check if that works you can debug with:
// called on collision
void OnCollisionEnter2D(Collision2D col)
{
Debug.Log("OnCollisionEnter2D");
}
From what I understood, you want only to detect triggers between the player and the enemies, but you still want these to collide with physic objects in your scene, such as background colliders.
One possible way to achieve this is to create a child object for the player object with a collider component with the trigger option set, and attaching a script to it to handle the triggers. Then, with the use of layers to group your player and enemy objects, you can uncheck the collision between them following: Edit -> Project Settings -> Physics 2D: "Layer Collision Matrix".
You can assign a script to any enemy, checking the distance with the player in each frame. Then you can Uncheck "is trigger"
Vector2.Distance
I am making a 2D Game with Unity 5 and I have a problem with child GameObject collider. I want to detect a collision between a Child GameObject with another object, doing this from the parent script and using tags.
Follow my parent script below:
void OnCollisionEnter2D(Collision2D hit) {
if(hit.transform.tag == "Enemy"){
this.playerRigidbody.AddForce(new Vector2(0, this.forceJump));
}
}
The "Enemy" tag is another object that is colliding with the collider of my player child. I want to detect the collision between the child object and that another object, I searched in many similar forums about Unity but I couldn't solve my problem. Someone can help me with this problem?
When a collision occurs, Unity will search up the hierarchy for the nearest Rigidbody and run any scripts on that same GameObject.
So, the simple approach is to make sure the rigidbody is on the parent object with the script. Here's an example hierarchy:
Parent
Child A
Child B
Parent has:
A Rigidbody 2D
The script
Child B has:
A Box Collider 2D
When the box collider collides with something, the event will bubble up straight through Child A and be received by the Rigidbody on the parent, which will then cause the script to run.
If you can't put the rigidbody on the parent..
Unity won't bubble the event up the hierarchy any further than that for performance reasons. So, your other options are..
Add a script to the child which catches the collision and deals with it there. If you need to, you could forward the event to the parent script like so:
void OnCollisionEnter2D(Collision2D hit) {
// Forward to the parent (or just deal with it here).
// Let's say it has a script called "PlayerCollisionHelper" on it:
PlayerCollisionHelper parentScript = transform.parent.GetComponent<PlayerCollisionHelper>();
// Let it know a collision happened:
parentScript.CollisionFromChild(hit);
}
Or a script on the "another" object in order to catch that collision event from its point of view instead.
Make sure the child object doesn't have a rigidbody and ensure the collider properties are correct. Check out the Compound Colliders section in this article for more information on combining colliders in child objects.
I am trying to have a block that can only be pushed inside of a rectangular collider. The player has to be able to move through the collider in order to push the block. I have tried to affect the mass upon the block being pushed into the edge collider, the drag, the angular drag, the velocity, isKinematic but nothing will stop the cube from moving when it hits the collider. It is really confusing, any help would really be appreciated...Here is the code:
public class pushBlock2 : MonoBehaviour {
public Rigidbody2D pBlock2;
void OnTriggerEnter2D(Collider2D col)
{
if (col.tag == "edge") {
Debug.Log ("pushblock2 touched edge");
pBlock2.isKinematic = true;
pBlock2.isKinematic = false;
}
}
void OnTriggerStay2D(Collider2D col)
{
if (col.tag == "edge") {
pBlock2.isKinematic = true;
}
}
Why don't you try and create four colliders around the area you want to move your block within? This way you'll have to stop the block from entering those which is much easier task than trying to prevent an item from leaving the collider.
I am pretty sure you will be able to pull this off without any code at all, you just need to setup a couple of static colliders to collide with objects on certain layer and put the cube you wanna move on that layer.
More info on Layer-based collisions can be found here: http://docs.unity3d.com/Manual/LayerBasedCollision.html
The way I understood, you're trying to use the volume defined by a collider as a delimiter for movement. I'm supposing you also desire "realistic" collisions when the object attempts to go outside said volume. That being the case, I'm afraid it is not possible.
The whole physics simulation is made by assuming some rules. Whenever two colliders intersect, the physics follows the rule that two objects should not occupy the same space (just like the real world), and thus it will try to figure out how to separate them again.
You can somewhat work around this by using a set of colliders that defines an hollow object, such as a barrel or box, but its more likely you'll turn off physics simulation for the box and roll up your own algorithm if consistent behavior is needed.
Many things in games are actually "fake" behaviors. Perhaps you can achieve what you want by faking physics or faking collisions?