Colliders (906634)

So, im trying to make it to where the player (the white ball) when ever it hits the enemy (the red ball) and it colldies i want the player to fall. I added a OnCollionEneter in my player script. Except when i test it doesnt seem to work. I watched a Unity tutorial and i cant figure out why, do you know?

Code:

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

public class Player : MonoBehaviour
{
   
    public float moveSpeed;
    public Rigidbody2D rb2d;
    private Vector2 moveInput;

    void Start()
    {
        rb2d = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        moveInput.y = Input.GetAxisRaw("Vertical");

        moveInput.Normalize();

        rb2d.velocity = moveInput * moveSpeed;

        Debug.Log(moveInput.magnitude);
    }

    void OnCollisionEnter(Collision col)
    {
        if(col.gameObject.name == "Enemy")
        {
            rb2d.gravityScale = 5;
        }
    }

}

a picture incase you need it i guess ;-;

As it looks like you are trying to do 2D collisions, you need to be using OnCollisionEnter2D. You are using OnCollisionEnter which is for 3D collisions.

its still not setting the gravity to 5 after I changed the OnCollisionEnter2D.

You are setting velocity directly. This overrides the acceleration of gravity, not allowing the object to fall.

You will need to prevent the setting of velocity based on user input upon the player’s death.

would setting the velocity to 0 work?

You need to stop manipulating the velocity entirely. You can introduce a boolean value, say private isDead = false; and set that to true when they collide with an enemy. Then, use that to prevent your code in update running.

private void FixedUpdate()
{
    if (isDead == true)
    {
        return;
    }
   
    // rest of code
}

Also FYI, physics related code should be in FixedUpdate. Poll inputs in Update, act upon them in FixedUpdate().

I would post your updated code because maybe you’ve changed it to “OnCollisionEnter2D” but are still specifying “Collision” rather than “Collision2D”.

Instead of focusing on gravity not being set, focus on whether the function is being called. Add in a Debug.Log("Collision!") or a Debug.Log(col.gameObject.name). The function might be called but it isn’t with the GameObject with that name. You could also attach a debugger and put a breakpoint, that way you can inspect when it’s called and which GameObject/Collider (etc) it is.

I would read this: Unity - Manual: Debugging C# code in Unity

heres the updated code.

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

public class Player : MonoBehaviour
{
   
    public float moveSpeed;
    public Rigidbody2D rb2d;
    private Vector2 moveInput;

    void Start()
    {
        rb2d = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        moveInput.y = Input.GetAxisRaw("Vertical");

        moveInput.Normalize();

        rb2d.velocity = moveInput * moveSpeed;

        Debug.Log(moveInput.magnitude);
    }

    void OnCollisionEnter2D(Collision col)
    {
        if(col.gameObject.name == "Enemy")
        {
            rb2d.gravityScale = 5;
            Debug.Log(col.gameObject.name);
        }
    }

}

so i keep the oncollision but i check if the user is dead?

And just as @MelvMay said:

You have not changed the parameter type to Collision2D. If you look at the scripting url that I gave you for OnCollisionEnter2D in my last post you would see that it needs a Collision2D type as the method parameter, not a Collision type

ahh thanks yes i fixed that

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
  
    public float moveSpeed;
    public Rigidbody2D rb2d;
    private Vector2 moveInput;
    void Start()
    {
        rb2d = GetComponent<Rigidbody2D>();
    }
    void Update()
    {
        moveInput.y = Input.GetAxisRaw("Vertical");
        moveInput.Normalize();
        rb2d.velocity = moveInput * moveSpeed;
        Debug.Log(moveInput.magnitude);
    }
    void OnCollisionEnter2D(Collision col)
    {
        if(col.gameObject.name == "Enemy")
        {
            rb2d.gravityScale = 5;
            Debug.Log(col.gameObject.name);
        }
    }
}

MelvMay

i put the debug log and its not working

No you haven’t. It’s still wrong in your code example.

Line 21 needs to be void OnCollisionEnter2D(Collision2D col).

oh wait what oh ye i got mixed up

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

public class Player : MonoBehaviour
{
   
    public float moveSpeed;
    public Rigidbody2D rb2d;
    private Vector2 moveInput;

    void Start()
    {
        rb2d = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        moveInput.y = Input.GetAxisRaw("Vertical");

        moveInput.Normalize();

        rb2d.velocity = moveInput * moveSpeed;

        Debug.Log(moveInput.magnitude);
    }

    void OnCollisionEnter2D(Collision2D col)
    {
        if(col.gameObject.name == "Enemy")
        {
            rb2d.gravityScale = 5;
            Debug.Log(col.gameObject.name);
        }
    }

}

spiney199

okay so 2 things i dont understand about this:

what do i put in my return? cus i cant just change or manupilate the velocity so what else do i put there. and what do i do my col? cus again i can just change or manipulate my velocity.

The point of it is to exit the method early so that you don’t manipulate physics.

So long as you manually drive the .velocity of a rigidbody you are effectively overriding physics on that object, and most expected physics operations likely won’t happen.

Lets say you want the player to fall for two seconds. You’d do something like this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
 
    public float moveSpeed;
 
    public Rigidbody2D rb2d;
 
    private Vector2 moveInput = Vector2.zero;
 
    private float hitStun = 0f;

    private void Start()
    {
        rb2d = GetComponent<Rigidbody2D>();
    }

    private void Update()
    {    
        if (hitStun > 0)
        {
            hitStun -= Time.deltaTime;
            return;
        }
    
        moveInput.y = Input.GetAxisRaw("Vertical");
        moveInput.Normalize();
    }
 
    private void FixedUpdate()
    {
        if (hitStun > 0)
        {
            return;
        }
    
        rb2d.velocity = moveInput * moveSpeed;
    }

    private void OnCollisionEnter2D(Collision2D col)
    {
        if(col.gameObject.name == "Enemy")
        {
            hitStun = 2f;
            rb2d.gravityScale = 5;
            Debug.Log(col.gameObject.name);
        }
    }
}

Though you should probably just being using regular Ridigbody(2D).AddForce methods here, to be honest.

“return” terminates a function.

Your issue was that you were moving your character by setting velocity every update loop. This prevents gravity from taking effect even after you reactivate it, because the rigidbody’s velocity is being overwritten every update loop.

The solution as proposed by @spiney199 is meant to stop the rigidbody’s velocity from being overwritten every update loop after the player is dead in the context of your game, allowing gravity to take effect.

maan i thought we was talkin 'bout bools, i dont understand this maan…thx for the help though ill try and figure out the addforce

The solution involves one bool, but understanding how the bool is being used and how it affects other parts of your script is what you lack. Switching over to using addforce isn’t going to change much, you will still encounter problems you do not understand if your fundamentals are lacking.

so, whys this not showing up in console?

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

public class Player : MonoBehaviour
{
   
    public float moveSpeed;
    public Rigidbody2D rb2d;
    private Vector2 moveInput;

    void Start()
    {
        rb2d = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        moveInput.y = Input.GetAxisRaw("Vertical");

        moveInput.Normalize();

        rb2d.velocity = moveInput * moveSpeed;

        Debug.Log(moveInput.magnitude);
    }

    void OnTriggerEnter2D(Collider2D col)
    {
        Debug.Log("hit detected!");
    }

}

Maybe you haven’t changed your collision to be a trigger?
If you have a 2D collider set as Is Trigger in the IDE, then it should fire the OnTriggerEnter2D method. But as we haven’t seen any updated screens of your colliders for the player we can’t tell you if you have missed doing something or not.
The last time you showed us the collider on the player it was not flagged as a trigger and you were doing OnCollisionEnter2D not OnTriggerEnter2D, so I’m just going to guess that you haven’t finished setting the relevant colliders to actually be triggers yet.