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

Script for a power-up like star in Mario Bross.

Discussion in '2D' started by JackReivaj, Feb 14, 2021.

  1. JackReivaj

    JackReivaj

    Joined:
    Feb 7, 2021
    Posts:
    33
    Hi!
    I want to do a script so that when I grab a certain object for a limited time it allows me to kill the enemies just by passing by them. It would be something like the star of Mario Bross. Do you have any recommendations to start with? I don't need the solution but if you can guide me it would be very good.
     
    Last edited: Feb 14, 2021
  2. unity_g6pUasEkRJ-2jg

    unity_g6pUasEkRJ-2jg

    Joined:
    Jul 24, 2020
    Posts:
    16
    ok lets start with the "grabbing". We will use the OnCollisionEnter2D(collision) function, which is called everytime your power-up touches something. Inside the function, we will check if collision.transform==player.transform. If that is true, then you power-up just touched the player.

    When that happens, we will notify the player's script with the SendMessage(message, value) function. On the message parameter, we will put "PowerUp", and on the value, something like "Magic Star". If you add more powerups later on, you will use the same message but change the value to the power-ups name

    Lets move on to the player's script. We will have a function called PowerUp that takes a string. This is the function that will be called by sendmessage. Inside the function, we will check if the string == "Magic Star". If that is the case, then the power-up that send the message was the magic star. Then a variable "PowerupTime" will be set to something like 5, and substracted Time.DeltaTime every frame. (This way PowerupTime will be equal to 0 after 5 seconds). As long as PowerupTime > 0, your player should be invincible
     
  3. JackReivaj

    JackReivaj

    Joined:
    Feb 7, 2021
    Posts:
    33
    Sorry i can't make it work, i'm noob. Are you saying one script would be?
    Code (CSharp):
    1. public GameObject player;
    2.  
    3. private void OnCollisionEnter2D(Collision2D c1)
    4.     {
    5.  
    6.         if (c1.transform == player.transform)
    7.         {
    8.  
    9.             gameObject.SendMessage("PowerUp", "MagicStar");
    10.         }
    11.     }
    And the other one would be in the player scripts and it would be something like this?
    Code (CSharp):
    1. public float PowerupTime;
    2.  
    3. void PowerUp()
    4.     {
    5.         string m = "MagicStar";
    6.         if (m == "MagicStar")
    7.         {
    8.             PowerupTime = 5;
    9.             PowerupTime -= Time.DeltaTime;
    10.         }
    11.     }
    I tried with this but i suppose that i'm didn't understand well because it doesn't work.
     
  4. unity_g6pUasEkRJ-2jg

    unity_g6pUasEkRJ-2jg

    Joined:
    Jul 24, 2020
    Posts:
    16
    Oh, I think I see the problem.
    Code (CSharp):
    1. void PowerUp(string m)
    2.     {
    3.         if (m == "MagicStar")
    4.         {
    5.             PowerupTime = 5;
    6.             PowerupTime -= Time.DeltaTime;
    7.         }
    8.     }
    PowerUp wasnt being called because it didnt have the string parameter. If you wanna see an example, you can check the official documentation here https://docs.unity3d.com/ScriptReference/GameObject.SendMessage.html

    Sorry if I didnt explain it properly
     
  5. JackReivaj

    JackReivaj

    Joined:
    Feb 7, 2021
    Posts:
    33
    Still not working. I think that maybe could be the way i have the other scripts. I have this in the player script:
    Code (CSharp):
    1. private void OnCollisionEnter2D(Collision2D c1)
    2.     { if (c1.collider.gameObject.tag == "enemy")
    3.         {
    4.             YouLose = true;
    5.             PlayerBody.constraints = RigidbodyConstraints2D.FreezeAll;
    6.         }
    7. }
    8.  
    9.  
    and maybe it's because of this it don't work. Or i don't know why. Anyway there shouldn't be a Destroy(gameObject) in the script to kill the enemies when i hit them? Thks for answering me. I will keep trying and learning. Maybe i'm trying something hard to know only a bit of code.
     
  6. unity_g6pUasEkRJ-2jg

    unity_g6pUasEkRJ-2jg

    Joined:
    Jul 24, 2020
    Posts:
    16
    yes, to prevent garbage from accumulating you should use Destroy(gameobject) when you dont need a gameobject anymore. Although this can be a bit performance intensive. If you experiment lag in your game due to this, you should search "Object Pooling".

    I assume "doesnt work" means that there are no errors/warnings, but the player is still being killed when he touches an enemy. This could be because you arent using the PowerupTime variable for anything

    Code (CSharp):
    1. if (c1.collider.gameObject.tag == "enemy" && PowerupTime<0)
    2.         {
    3.             YouLose = true;
    4.             PlayerBody.constraints = RigidbodyConstraints2D.FreezeAll;
    5.         }
    6.  
    this condition checks if the player's powerup is still active. If it is not, then the code that kills the player isnt executed. Depending on how your game was designed this could lead to weird behavior, it is up to you to adress that.
    Also, the line
    PowerupTIme -= Time.DeltaTime;
    should be executed every frame, not only when the player collides with the star
     
  7. JackReivaj

    JackReivaj

    Joined:
    Feb 7, 2021
    Posts:
    33
    I made some changes to adapt it to my project but thanks to you it works. Here is how i did it:

    In the script of the Star i put this:
    Code (CSharp):
    1. public AudioSource sound;
    2. public int score;
    3. private void OnTriggerEnter2D(Collider2D c1)
    4.     {
    5.      
    6.         if (c1.tag == "Player")
    7.         {
    8.             SceneLogic ObjetoPadre = transform.root.GetComponent<SceneLogic>();
    9.             ObjetoPadre.score += 50;          
    10.             Destroy(gameObject);
    11.             sound.Play();
    12.         }
    13.     }
    In the script of the player:

    Code (CSharp):
    1. public float PowerupTime;
    2. public GameObject Star;
    3.  
    4. void Start()
    5.     {
    6.       PowerupTime = 0;      
    7.     }
    8. void Update()
    9. {
    10. PowerupTime -= Time.deltaTime;
    11.  
    12.         if (Input.GetKeyDown("r"))
    13.         {
    14.             PowerupTime = 0;
    15.         }
    16.  
    17.         if (Input.GetKeyDown("n"))
    18.         {
    19.             PowerupTime = 0;
    20.         }
    21. }
    22.  
    23. private void OnCollisionEnter2D(Collision2D c1)
    24. {
    25. if (c1.collider.gameObject.tag == "enemy" && PowerupTime < 0)
    26.         {
    27.             YouLose = true;
    28.             JugadorBody.constraints = RigidbodyConstraints2D.FreezeAll;
    29.         } else if (c1.collider.gameObject.tag == "enemy" && PowerupTime > 0) {
    30.  
    31.             YouLose = false;
    32.             JugadorBody.constraints = RigidbodyConstraints2D.None;
    33.             JugadorBody.constraints = RigidbodyConstraints2D.FreezeRotation;
    34.             Destroy(c1.gameObject);
    35.         }
    36. }
    37.  
    38. private void OnTriggerEnter2D(Collider2D c1)
    39. {
    40. if (c1.tag == "Star")
    41.         {
    42.             PowerUp("MagicStar");
    43.         }
    44. }
    45. void PowerUp(string m)
    46.     {            
    47.         if (m == "MagicStar")
    48.         {
    49.  
    50.             PowerupTime = 10;
    51.             PowerupTime -= Time.deltaTime;          
    52.  
    53.         }
    54.     }
    The "r" is for restart button. The "n" is for next level button.
    Maybe there are things that I could change in the code. But it works very well. Really, thank you!
     
    unity_g6pUasEkRJ-2jg likes this.
  8. unity_g6pUasEkRJ-2jg

    unity_g6pUasEkRJ-2jg

    Joined:
    Jul 24, 2020
    Posts:
    16
    I am glad I could help
     
    JackReivaj likes this.