How to make player walk through another collider and trigger?

I’m struggling to get the player walking through an enemy and having the OnCollisionEnter or OnTriggerEnter work?. I’ve got 2 colliders on my player (one is trigger) and one on the enemy. I’ve tried removing collisions from the physics 2D project settings but then collisions and triggers don’t work. I want them both to have rigidbodies and colliders but only trigger went the player walks through.

Any ideas? I can’t seem to find anything on the internet?

Hello,
If you are using 2D colliders (and 2D rigidbodies), make sure to use OnTriggerEnter2D / OnCollisionEnter2D.
Let me know if this fixes your issue

Hi Ted, those are the functions i am calling, I should have specified!

I see,
Could you share a bit more about your current setup (what kind of components does tthe player and the enemy have), and the code you are trying to call. That would give me some more insight.

Hello,

The code I’ve tried calling are the OnTriggerEnter2D / OnCollisionEnter2D. I’ve tried both and both do not return my debug message when colliding with each other. this is when the physics 2D settings are are unchecked i.e player not colliding with enemy. When theyy are checked, they collide but push each other around which I don’t want. I’d like them to go through each other but still register the trigger.

I’ve tried the arrangement with a combination of both colliders on both the enemy and the player and no tomato.

Please post your code so we can see what you’re doing.

The specific information we need is:

  • The script that has the OnTriggerEnter2D and a description of which GameObject this is on

  • The Rigidbody2D and Collider2D on each GameObject

  • The details of the Rigidbody2D configuration (image of the inspector) but mainly, the BodyType & the Is Trigger properties.

  • The Layer both the GameObject are set to

  • The Layer Collision Matrix for these layers in the Settings > Physics 2D > Layer Collision Matrix

Alternately, if you want you can host a simple reproduction project I’ll take a look at it for you. If you can’t easily host it then send me a DM with your email address and I’ll send you a location you can securely upload it.

Hi Melv,

  1. script is copied below
  2. I’ve included an imgur album link with snips for both the player and the enemy
  3. included in imgur link
  4. Enemy on enemy, player on player - shown on imgur link
  5. Attached in the imgur link

At the moment I’ve got both colliders and trigger collider on as I’m trying to figure out whats going on. But I’ve tried a combo of turning them off and on.

Cheers,

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
    [SerializeField]
    private LayerMask groundLayerMask;
    public float speed = 6.5f;
    private Rigidbody2D rb;
    private BoxCollider2D playerCollider;
    private SpriteRenderer spriteRenderer;
    private float Pos1;
    private float Pos2;
    public float jumpForce = 400f;
    public float jumpCooldown = 0.1f;
    private float jumpTimer;
    public bool jumpOnCooldown = true;
    private float inputHorizontal;
    private float inputVertical;
    public Animator playerAnimator;

    public float attackCooldown = 1f;
    private float attackTimer;
    private bool canAttack = true;
    public GameObject fireball;
    public Transform fireballPoint;
    public float fireballSpeed = 10f;

    public float maxHp = 100f;
    public float currentHP = 100f;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        playerCollider = GetComponent<BoxCollider2D>();
        spriteRenderer = GetComponent<SpriteRenderer>();
        playerAnimator = GetComponent<Animator>();
    }

    void Update()
    {
        inputHorizontal = Input.GetAxisRaw("Horizontal");
        inputVertical = Input.GetAxisRaw("Vertical");

        if (onGround())
        {
            playerAnimator.SetBool("isJumping", false);
            playerAnimator.SetBool("isFalling", false);
        }
        else
        {
            if (rb.velocity.y <= 0)
            {
                playerAnimator.SetBool("isFalling", true);
                playerAnimator.SetBool("isJumping", false);
            }
            else
            {
                playerAnimator.SetBool("isJumping", true);
            }
        }

        if (inputHorizontal < 0)
        {
            spriteRenderer.flipX = true;
            playerAnimator.SetBool("isWalking", true);

        }
        else if (inputHorizontal > 0)
        {
            spriteRenderer.flipX = false;
            playerAnimator.SetBool("isWalking", true);
        }
        else if (inputHorizontal == 0)
        {
            playerAnimator.SetBool("isWalking", false);
        }

        if (jumpTimer <= jumpCooldown)
        {
            jumpTimer += Time.fixedDeltaTime;
        }
        else
        {
            jumpOnCooldown = false;
        }

        if (Input.GetKey(KeyCode.Space) && onGround() && !jumpOnCooldown)
        {
            jump();
            jumpTimer = 0;
            jumpOnCooldown = true;
            //Debug.Log("Jump Registered");
        }

        if (!canAttack && attackTimer <= attackCooldown)
        {
            attackTimer += Time.deltaTime;
        }
        else if (attackTimer >= attackCooldown)
        {
            canAttack = true;
        }
     

        if (Input.GetKey(KeyCode.Z) && canAttack)
        {
            attack();
            canAttack = false;
            attackTimer = 0f;
        }

    }

    // Update is called once per frame
    void FixedUpdate()
    {
        rb.velocity = new Vector2(inputHorizontal * Time.fixedDeltaTime * speed, rb.velocity.y);
        //rb.transform.position += new Vector3(inputHorizontal, 0.0f, 0.0f)*Time.fixedDeltaTime * speed;
    }

    public bool onGround()
    {
        float extraHeight = 0.05f;
        RaycastHit2D rayCastHit = Physics2D.Raycast(playerCollider.bounds.center, Vector2.down, playerCollider.bounds.extents.y + extraHeight, groundLayerMask);
        Color rayColor;
        if (rayCastHit.collider != null)
        {

            rayColor = Color.green;
        }
        else
        {
            rayColor = Color.red;
        }
        //Debug.Log("Grounded");
        Debug.DrawRay(playerCollider.bounds.center, Vector2.down * (playerCollider.bounds.extents.y + extraHeight), rayColor);
        return rayCastHit.collider != null;
    }

    void jump()
    {
        rb.velocity = new Vector2(rb.velocity.x, 0.0f);
        rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Force);
    }

    public void takeDamage(float Damage)
    {
        currentHP -= Damage;
        if (currentHP < 0)
        {
            death();
        }
    }

    private void death()
    {
        //do something
    }

    void OnTriggerEnter2D(Collider2D other)
    {    
           //Debug.Log(other.tag);
    }

    void attack()
    {
        GameObject Fireball = Instantiate(fireball);
        Fireball.transform.position = fireballPoint.transform.position;
        Rigidbody2D Fireballrb = fireball.GetComponent<Rigidbody2D>();
        Fireballrb.velocity = new Vector2(inputHorizontal*fireballSpeed, Fireballrb.velocity.y);
    }
}

Note that I don’t see any imgur link above.

Anyway, the code above has the correct trigger callback and it looks like you have a Rigidbody2D/BoxCollider2D on it. Not sure if the enemy has the trigger or the player. Just need to ensure that the player/enemy GameObject have the appropriate layers and that they’re set to collide in the layer collision matrix. Nothing else would stop that happening if they overlap.

apologies! imgur link below.

My problem is i don’t want them to collide as such, jsut trigger, but when taken out of the physics matrix they don’t trigger either. Is there another way to mask collisions?

Presumably you want a collider on the enemy to NOT be a trigger because you’re using it to ensure you walk on your platforms? You are free to create an additional child object on the Enemy with another Collider that is set to trigger just for triggering. Set that child object layer to something that can collide with the player (a layer like “EnemyTrigger”). Ensure this can contact the Player layer and you’ll get trigger callbacks.

So:

  • Create a layer you use specifically for enemy triggers.
  • Set that to contact the Player layer in the Layer Collision Matrix.
  • If your enemy has a child collider as a trigger and this GameObject is set to the enemy trigger layer then it works fine.
  • You can still have a parent Enemy GameObject with a collider that isn’t a trigger and isn’t set to collider with the player. This can be used to actually collide for purposes of standing on platforms etc.
  • Profit!

That sounds like it will work! I’ll give it a try thank you!

1 Like

I had the same problem. I solved it using your solution. Thankyou. I appreciate it very much.