Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Trying to make a life system in a Arkanoid game (Block breaker) but can't get ball to respawn right

Discussion in 'Scripting' started by danmct1995, Jul 7, 2020.

  1. danmct1995

    danmct1995

    Joined:
    Apr 21, 2020
    Posts:
    70
    I currently have a script for lives that subtracts a life when there is no longer a ball on the screen and I'd like it to re-spawn the ball on top of the paddle so that it can fire again. What is happening is that I can instantiate it, but I can't figure out how to tell the ball where to be at or to stick to the paddle again. I also tried making the death barrier at the bottom of the screen just teleport the ball back to the paddle and was going to make it subtract a life upon collision, but the transportation doesn't work and I imagine even if it did, the ball wouldn't be stuck to the paddle again.

    How would I actually go about building a proper life system in this style of game or how would I fix what I have currently laid out. This is one of the last (and longest) steps I am on to completing my first game, but I've been struggling a lot with it. Any help, tips, or solutions would be greatly appreciated!


    The Lives script

    Code (CSharp):
    1. public class Lives : MonoBehaviour
    2. {
    3.     // number of lives & images
    4.     public GameObject[] hearts;
    5.     private int life;
    6.  
    7.     // are we alive?
    8.     private bool dead;
    9.  
    10.     // subtract a life
    11.     private int MinusALife = 1;
    12.  
    13.     // checking for respawn
    14.     private bool WeDied = false;
    15.  
    16.     // access sceneManager for gameover on zero lives
    17.     SceneManager sceneManager;
    18.  
    19.     // delay for death
    20.     [SerializeField] float waitingAfterDeath = 5f;
    21.  
    22.     // The ball object
    23.     [SerializeField] Ball ball;
    24.  
    25.     private void Start()
    26.     {
    27.         life = hearts.Length;
    28.     }
    29.     void Update()
    30.     {
    31.         CheckIfNoBallsAreLeft();
    32.         if(dead == true)
    33.         {
    34.             // if lives reach zero death is confirmed and start scene is reloaded
    35.             FindObjectOfType<SceneLoader>().LoadStartScene();
    36.         }
    37.     }
    38.  
    39.  
    40.     public void CheckIfNoBallsAreLeft()
    41.     {
    42.         int NumberOfBallsLeft = FindObjectsOfType<Ball>().Length;
    43.         int currentSceneIndex = SceneManager.GetActiveScene().buildIndex;
    44.  
    45.  
    46.  
    47.         if (NumberOfBallsLeft == 0 && currentSceneIndex != 5)
    48.         {
    49.             life -= MinusALife;
    50.             Destroy(hearts[life].gameObject);
    51.             if (life < 1)
    52.             {
    53.                 dead = true;
    54.             }
    55.             else
    56.             {
    57.                 // create a new ball attached to the paddle
    58.             }
    59.         }
    60.     }
    The Death Barrier Script

    Code (CSharp):
    1. public class DeathBarrier : MonoBehaviour
    2. {
    3.  
    4.     [SerializeField] private Transform ball;
    5.     [SerializeField] private Transform RespawnPoint;
    6.     private void OnTriggerEnter2D(Collider2D losing)
    7.     {
    8.         int NumberOfBallsLeft = FindObjectsOfType<Ball>().Length;
    9.         // Destroy balls incase of multiball powerup
    10.         if (losing.gameObject.name == "Ball" && NumberOfBallsLeft > 1 || losing.gameObject.name == "Ball(Clone)" && NumberOfBallsLeft > 1)
    11.         {
    12.             Destroy(losing.gameObject);
    13.         }
    14.         else if (NumberOfBallsLeft <= 1)
    15.         {
    16.             ball.transform.position = RespawnPoint.transform.position;
    17.         }
    18.  
    19.     }
    20. }
    The Balls script + Locking to paddle

    Code (CSharp):
    1.  
    2. public class Ball : MonoBehaviour
    3. {
    4.     // config parameter
    5.     [SerializeField] KeyboardControls paddle1;
    6.     [SerializeField] float pushX = 0.1f;
    7.     [SerializeField] float pushY = 10f;
    8.     [SerializeField] float randomFactor = 0.2f;
    9.     [SerializeField] float LowRandomFactor = -0.2f;
    10.  
    11.  
    12.     // cached component references
    13.     Vector2 paddleToTheBall;
    14.  
    15.     Rigidbody2D rb;
    16.  
    17.     private bool hasStarted = false;
    18.  
    19.     /* Variables over */
    20.  
    21.     void Start()
    22.     {
    23.         paddleToTheBall = transform.position - paddle1.transform.position;
    24.  
    25.         // rigidbody to rb
    26.         rb = GetComponent<Rigidbody2D>();
    27.     }
    28.  
    29.     // Update is called once per frame
    30.     void Update()
    31.     { // ball lock & stick
    32.         if (!hasStarted)
    33.         {
    34.             LockBallToPaddle();
    35.             LaunchOnClick();
    36.         }
    37.     }
    38.  
    39.     public void LaunchOnClick()
    40.     {
    41.         int NumberOfBallsLeft = FindObjectsOfType<Ball>().Length;
    42.         if (Input.GetKeyDown("space"))
    43.         {
    44.             hasStarted = true;
    45.             GetComponent<Rigidbody2D>().velocity = new Vector2(pushX, pushY);
    46.         }
    47.         else if (NumberOfBallsLeft == 0)
    48.         {
    49.             hasStarted = false;
    50.         }
    51.     }
    52.  
    53.    public void LockBallToPaddle()
    54.     {
    55.         Vector2 paddlePos = new Vector2(paddle1.transform.position.x, paddle1.transform.position.y);
    56.         transform.position = paddlePos + paddleToTheBall;
    57.     }
    58.  
    59.     private void OnCollisionEnter2D(Collision2D collision)
    60.     {
    61.       Vector2 velocityAdjustment = new Vector2
    62.             //X axis
    63.             (Random.Range(LowRandomFactor,randomFactor),
    64.             //Y axis
    65.             Random.Range(0, randomFactor));
    66.         if (hasStarted)
    67.         {
    68.             rb.velocity += velocityAdjustment;
    69.         }
    70.     }
    71.  
    72. }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,515
    Without getting into the scripts above specifically, if I remember Arkanoid, when you died the ball was on the paddle, then launched, but I think it was on a timer: if you didn't launch within a few seconds, it would auto-launch.

    The way to do that is to have a timer that is the "hold countdown" timer (a float number), and reduce it by Time.deltaTime every frame. When it reaches zero, release the ball. When the player hits "GO" also set it to zero, which would trigger the release.

    As for setting the ball where you want, make a child empty GameObject under your paddle where you want the ball to be, and give the ball spawning script a way to get at it, usually by dragging a reference into the spawner. That way it makes the ball, then moves its transform.position to where the empty GameObject is.
     
    danmct1995 likes this.
  3. danmct1995

    danmct1995

    Joined:
    Apr 21, 2020
    Posts:
    70
    what I have now allows the player to launch the ball by pressing the space bar so that part should be fine, but I’m struggling to basically reset a level if the player dies. I have a life system set up and a point attached to the paddle to Respawn, but the object won’t spawn there for some reason.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,515
    Start inserting Debug.Log() outputs of all relevant variables, positions, etc., at all points in the stage of that ball respawning, and I'm sure you will soon discover the reason!