Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Colliders

Discussion in 'Scripting' started by junior333istall, Jan 20, 2023.

  1. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    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:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Player : MonoBehaviour
    6. {
    7.    
    8.     public float moveSpeed;
    9.     public Rigidbody2D rb2d;
    10.     private Vector2 moveInput;
    11.  
    12.     void Start()
    13.     {
    14.         rb2d = GetComponent<Rigidbody2D>();
    15.     }
    16.  
    17.     void Update()
    18.     {
    19.         moveInput.y = Input.GetAxisRaw("Vertical");
    20.  
    21.         moveInput.Normalize();
    22.  
    23.         rb2d.velocity = moveInput * moveSpeed;
    24.  
    25.         Debug.Log(moveInput.magnitude);
    26.     }
    27.  
    28.     void OnCollisionEnter(Collision col)
    29.     {
    30.         if(col.gameObject.name == "Enemy")
    31.         {
    32.             rb2d.gravityScale = 5;
    33.         }
    34.     }
    35.  
    36. }
    37.  
    a picture incase you need it i guess ;-;

    upload_2023-1-19_20-56-37.png
     
  2. BABIA_GameStudio

    BABIA_GameStudio

    Joined:
    Mar 31, 2020
    Posts:
    488
    spiney199 likes this.
  3. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    its still not setting the gravity to 5 after I changed the OnCollisionEnter2D.
     
  4. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    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.
     
  5. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    would setting the velocity to 0 work?
     
  6. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,883
    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.

    Code (CSharp):
    1. private void FixedUpdate()
    2. {
    3.     if (isDead == true)
    4.     {
    5.         return;
    6.     }
    7.    
    8.     // rest of code
    9. }
    Also FYI, physics related code should be in FixedUpdate. Poll inputs in Update, act upon them in FixedUpdate().
     
  7. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,529
    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: https://docs.unity3d.com/2019.3/Documentation/Manual/ManagedCodeDebugging.html
     
    Colonel_Campbell likes this.
  8. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101



    heres the updated code.
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Player : MonoBehaviour
    6. {
    7.    
    8.     public float moveSpeed;
    9.     public Rigidbody2D rb2d;
    10.     private Vector2 moveInput;
    11.  
    12.     void Start()
    13.     {
    14.         rb2d = GetComponent<Rigidbody2D>();
    15.     }
    16.  
    17.     void Update()
    18.     {
    19.         moveInput.y = Input.GetAxisRaw("Vertical");
    20.  
    21.         moveInput.Normalize();
    22.  
    23.         rb2d.velocity = moveInput * moveSpeed;
    24.  
    25.         Debug.Log(moveInput.magnitude);
    26.     }
    27.  
    28.     void OnCollisionEnter2D(Collision col)
    29.     {
    30.         if(col.gameObject.name == "Enemy")
    31.         {
    32.             rb2d.gravityScale = 5;
    33.             Debug.Log(col.gameObject.name);
    34.         }
    35.     }
    36.  
    37. }
    38.  
     
  9. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101

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

    BABIA_GameStudio

    Joined:
    Mar 31, 2020
    Posts:
    488
    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
     
  11. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    ahh thanks yes i fixed that

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. public class Player : MonoBehaviour
    5. {
    6.  
    7.     public float moveSpeed;
    8.     public Rigidbody2D rb2d;
    9.     private Vector2 moveInput;
    10.     void Start()
    11.     {
    12.         rb2d = GetComponent<Rigidbody2D>();
    13.     }
    14.     void Update()
    15.     {
    16.         moveInput.y = Input.GetAxisRaw("Vertical");
    17.         moveInput.Normalize();
    18.         rb2d.velocity = moveInput * moveSpeed;
    19.         Debug.Log(moveInput.magnitude);
    20.     }
    21.     void OnCollisionEnter2D(Collision col)
    22.     {
    23.         if(col.gameObject.name == "Enemy")
    24.         {
    25.             rb2d.gravityScale = 5;
    26.             Debug.Log(col.gameObject.name);
    27.         }
    28.     }
    29. }
    MelvMay

    i put the debug log and its not working
     
  12. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,883
    No you haven't. It's still wrong in your code example.

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

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    oh wait what oh ye i got mixed up
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Player : MonoBehaviour
    6. {
    7.    
    8.     public float moveSpeed;
    9.     public Rigidbody2D rb2d;
    10.     private Vector2 moveInput;
    11.  
    12.     void Start()
    13.     {
    14.         rb2d = GetComponent<Rigidbody2D>();
    15.     }
    16.  
    17.     void Update()
    18.     {
    19.         moveInput.y = Input.GetAxisRaw("Vertical");
    20.  
    21.         moveInput.Normalize();
    22.  
    23.         rb2d.velocity = moveInput * moveSpeed;
    24.  
    25.         Debug.Log(moveInput.magnitude);
    26.     }
    27.  
    28.     void OnCollisionEnter2D(Collision2D col)
    29.     {
    30.         if(col.gameObject.name == "Enemy")
    31.         {
    32.             rb2d.gravityScale = 5;
    33.             Debug.Log(col.gameObject.name);
    34.         }
    35.     }
    36.  
    37. }
    38.  
     
  14. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    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.
     
  15. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,883
    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:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. public class Player : MonoBehaviour
    5. {
    6.  
    7.     public float moveSpeed;
    8.  
    9.     public Rigidbody2D rb2d;
    10.  
    11.     private Vector2 moveInput = Vector2.zero;
    12.  
    13.     private float hitStun = 0f;
    14.  
    15.     private void Start()
    16.     {
    17.         rb2d = GetComponent<Rigidbody2D>();
    18.     }
    19.  
    20.     private void Update()
    21.     {    
    22.         if (hitStun > 0)
    23.         {
    24.             hitStun -= Time.deltaTime;
    25.             return;
    26.         }
    27.    
    28.         moveInput.y = Input.GetAxisRaw("Vertical");
    29.         moveInput.Normalize();
    30.     }
    31.  
    32.     private void FixedUpdate()
    33.     {
    34.         if (hitStun > 0)
    35.         {
    36.             return;
    37.         }
    38.    
    39.         rb2d.velocity = moveInput * moveSpeed;
    40.     }
    41.  
    42.     private void OnCollisionEnter2D(Collision2D col)
    43.     {
    44.         if(col.gameObject.name == "Enemy")
    45.         {
    46.             hitStun = 2f;
    47.             rb2d.gravityScale = 5;
    48.             Debug.Log(col.gameObject.name);
    49.         }
    50.     }
    51. }
    Though you should probably just being using regular Ridigbody(2D).AddForce methods here, to be honest.
     
  16. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    "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.
     
    spiney199 likes this.
  17. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    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
     
  18. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    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.
     
  19. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    so, whys this not showing up in console?

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Player : MonoBehaviour
    6. {
    7.    
    8.     public float moveSpeed;
    9.     public Rigidbody2D rb2d;
    10.     private Vector2 moveInput;
    11.  
    12.     void Start()
    13.     {
    14.         rb2d = GetComponent<Rigidbody2D>();
    15.     }
    16.  
    17.     void Update()
    18.     {
    19.         moveInput.y = Input.GetAxisRaw("Vertical");
    20.  
    21.         moveInput.Normalize();
    22.  
    23.         rb2d.velocity = moveInput * moveSpeed;
    24.  
    25.         Debug.Log(moveInput.magnitude);
    26.     }
    27.  
    28.     void OnTriggerEnter2D(Collider2D col)
    29.     {
    30.         Debug.Log("hit detected!");
    31.     }
    32.  
    33. }
    34.  
     
  20. BABIA_GameStudio

    BABIA_GameStudio

    Joined:
    Mar 31, 2020
    Posts:
    488
    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.
     
  21. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    heres the photo and yes i did set the tirgger

    upload_2023-1-21_19-16-45.png
     
  22. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    Just confirming, do your enemies have colliders?
    In future, specify exactly what is "not showing up" instead of leaving it for the reader to infer.
     
  23. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    Sorry, yes i have trigger on player but not enemies in the tutorial they didnt show that you put trigger on emenies. i do have colliders on bot objects. the debug,log is not showing up in console which is what i want.
     
  24. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    oh ye, sorry i have collider on player object and collider on the enemy prefab not object is that what wrong?
     
  25. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    In order for OnTriggerEnter to fire:
    - all objects which are colliding need to have colliders.
    - at least one of the colliding objects needs to be marked as a trigger.
    - at least one of the colliding objects needs to have a rigidbody attached

    You player has a rigidbody, and your player is marked as a trigger, so at least we know the last 2 conditions are met.

    Maybe english isn't your first language. Either way, you unfortunately still haven't made if clear if your enemies have colliders.
     
    Last edited: Jan 22, 2023
  26. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    yes i have a collider on my enemy sprite not enemy game object

    upload_2023-1-22_0-18-19.png
     
  27. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    I do not understand your definitions. A gameobject is something which exists within a scene. A prefab is a gameobject that isn't in a scene, but can be referenced for instantiating duplicates. A sprite is an imported image with some metadata for Unity to understand what to do with it. You can only add components to gameobjects and prefabs and nothing else.

    So when you say you have a collider on your sprite and not game object, it does not make sense.

    A sprite is not a gameobject, and therefore cannot contain a collider.

    If "sprite" refers to the prefab you are using, your gameobject should have a collider since the gameobject is supposed to be a clone of the prefab.
     
  28. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    by sprite i meant my prefab. so i have a collider on my prefab which is in the prefab folder. and the enemy gameobject is the one in the higharchy and i do not have collider on this.
     
  29. BABIA_GameStudio

    BABIA_GameStudio

    Joined:
    Mar 31, 2020
    Posts:
    488
    I would definitely not name your enemy prefab
    EnemySprite
    as that is just asking for confusion. You would be better just naming it
    Enemy
    .

    I think the next things you need to check are:
    - Are your Player object and EnemySprite prefab set up on layers that allow 2D collision between those layers?
    - What happens if you change the Player and EnemySprite prefab RigidBody2Ds so that they have Collision Detection set as Continuous, rather than Discrete?
    - We have seen your Player script, but not your EnemyMovement script. Are you perhaps not using the physics commands for the Enemy when moving it, therefore bypassing the physics collision checks?
     
  30. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    i dont knon what you mean by layers. i set the rigidbody detections to continuous. and my enemymovement script is using rigidbody physics

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

    public class EnemyMovement : MonoBehaviour
    {
    public float moveSpeed;
    public Rigidbody2D rb2d;
    private float deadZone = -10;
    // Start is called before the first frame update
    void Start()
    {
    rb2d = GetComponent<Rigidbody2D>();
    }

    // Update is called once per frame
    void Update()
    {
    rb2d.velocity = Vector2.left * moveSpeed;

    if(transform.position.x <= deadZone)
    {
    Destroy(gameObject);

    Debug.Log("Enemy Destroyed");
    }
    }
    }
     
  31. BABIA_GameStudio

    BABIA_GameStudio

    Joined:
    Mar 31, 2020
    Posts:
    488
    There's this wonderful thing called the manual. You're going to have to get used to actually going and having a look at it yourself. Take a look at Layers. You can see what layer something is on at the top of the Inspector, where it says "Layer".
    There is an entire Layer Collision Matrix that can be setup in Unity for which layers can collide with which other layers.

    I'm assuming (because you haven't actually said either way) that this did not make any difference?

    Use code tags. We shouldn't have to ask for this again just because it is a different script.
     
    Last edited: Jan 22, 2023
  32. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    is this right, because its not working still

    upload_2023-1-22_20-13-7.png
     
  33. BABIA_GameStudio

    BABIA_GameStudio

    Joined:
    Mar 31, 2020
    Posts:
    488
    Not possible for me to tell.
    You have not shown what layer the Player or the Enemy prefab are on (like I said before it is at the top of the Inspector).
    I can see in that matrix that you have set the CollisionLayer to only allow 2D collisions with anything on that same layer. So if you have one of your game objects on that layer and the other gameobject that you want to collide with on another layer, it won't happen.
     
  34. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    heres the layers in the inspector
    upload_2023-1-22_20-35-30.png



    upload_2023-1-22_20-35-56.png



    heres a picture thats showing the "hit detected" not showing
    upload_2023-1-22_20-36-46.png
     
  35. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    Are the enemies you spawn not the same as your enemy prefab? If your spawned enemies indeed have no collider, that would be why OnTriggerEnter isn't firing, although it is weird at all that the spawned gameobject would be different from your enemy prefab.
     
    Last edited: Jan 23, 2023
  36. BABIA_GameStudio

    BABIA_GameStudio

    Joined:
    Mar 31, 2020
    Posts:
    488
    Can you show what object it is that your Player is actually colliding with? You have several instantiated EnemyPrefab object instances, however you also have that Enemy gameobject in your hierarchy and you said earlier that it did not have the colliders, etc.
    Are you actually colliding with one of the EnemyPrefab instances in your scene? Or in your screenshots is your Player touching the Enemy gameobject instead?
     
  37. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    Okay, i have the collider on the enemy prefab NOT enemy gameobject.

    although what im spawning is the enemy gameobject it seems in this script which is inside my enemy gameobject

    (i added the code tags)

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class EnemySpawn : MonoBehaviour
    6. {
    7.     public GameObject Enemy;
    8.     public float spawnRate;
    9.     public float timer;
    10.     public float heightOffset;
    11.     private float lowestPoint = transform.position.y - heightOffset;
    12.     private highestPoint = transform.position.y + heightOffset;
    13.     // Start is called before the first frame update
    14.     void Start()
    15.     {
    16.         SpawnEnemys();
    17.     }
    18.  
    19.     // Update is called once per frame
    20.     void Update()
    21.     {
    22.         if (timer < spawnRate)
    23.         {
    24.             timer = timer + Time.deltaTime;
    25.         }
    26.         else
    27.         {
    28.             SpawnEnemys();
    29.             timer = 0;
    30.         }
    31.        
    32.     }
    33.  
    34.     void SpawnEnemys()
    35.     {
    36.         Instantiate(Enemy, new Vector2(transform.position.x, Random.Range(lowestPoint, highestPoint)), transform.rotation);
    37.  
    38.         Debug.Log("Enemy Spawned");
    39.     }
    40. }
    41.  
     
  38. BABIA_GameStudio

    BABIA_GameStudio

    Joined:
    Mar 31, 2020
    Posts:
    488
    Yes, you already said that before.

    What I was asking is whether your Player is actually colliding with any instantiated EnemyPrefab objects, as you showed that you still have a single Enemy object in your scene and that one does not have the necessary colliders on it.

    I don't understand what you mean by this as you are supposed to be instantiating your EnemyPrefab objects. Just because your Spawner script has
    public GameObject Enemy
    it will just be any prefab object that has the Enemy script on it. Prefabs are just gameobjects.
    Show us a screenshot of your Inspector for the Spawner object so that we can see what it is you have actually put into that field, as that is what you will be spawning. It should be the EnemyPrefab.
     
  39. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    yes its spawning the prefabs in the enemy gameobject inspector is what i meant to say. its collding with my prefab or thats what my collider is on

    upload_2023-1-23_18-31-49.png



    upload_2023-1-23_18-35-4.png
     
  40. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    is that what you meant?
     
  41. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    This thread has gone on for a ridiculous amount of time. All we are trying to find out is if your spawned enemies have colliders. Either follow the steps I am about to outline, or just start an entirely new project.
    1. delete the "Enemy" gameobject in your scene.
    2. run your game
    3. after some enemy game objects have spawned, pause the game from the editor
    4. go to the scene and click on one of the spawned enemies
    5. screenshot the inspector details.
     
  42. BABIA_GameStudio

    BABIA_GameStudio

    Joined:
    Mar 31, 2020
    Posts:
    488
    @junior333istall - Do not delete this object as nothing will then be spawned.
    A lot of the problems and confusion we have been having with this topic are because you are naming things badly in your project.
    The
    Enemy
    object in your hierarchy is actually your spawner object, so it should never have been named
    Enemy
    in the first place. You should rename it to something like
    EnemySpawner
    .
    Just do all the other steps that Laperen has provided, but not step 1.
     
  43. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
  44. BABIA_GameStudio

    BABIA_GameStudio

    Joined:
    Mar 31, 2020
    Posts:
    488
    You need to re-read the steps that Laperen posted as your screenshot is not showing what was asked for. It looks like you have just done a screenshot of the Canvas in your hierarchy.
     
  45. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    oop wrong photo
    upload_2023-1-23_21-41-39.png

    upload_2023-1-23_21-42-2.png
     

    Attached Files:

  46. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    So now we know
    - both your player and spawned enemies have colliders
    - both your player and spawned enemies have rigidbodies
    - the player is marked as trigger

    All of this by right, should be enough for OnTriggerEnter on your player to trigger when it collides with an enemy.

    I have only just noticed one of your print statements in one of your screenshots reads "Enemy Destroyed". I assume this is print statement occurs when you destroy a spawned enemy. As a sanity, check, see if you have your desired print statement from the player script if you do not destroy spawned enemies when they collide with the player.
     
  47. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    ahhh uhhh soo, i figured why it wasnt working but now it is. so apparently the script wasnt compiling, but i always did do ctrl + s to save. i also went to the file and press the save. i somewhat just thought it was compiling even though i didnt see the message. i think this was due to me not closing the app or something idk. so yeah now its working heh whoops!