I'm making a breakout game in 3D and it's my first time making a game and using Unity so I'm a bit clueless. I've got to the point where my game works fine up until the ball goes off the screen and into the "dead zone". Can someone advise how to respawn the paddle and ball together and carry on with the game? I've included my ball and paddle scripts below, I have a script for the bricks as well but not sure that was relevant. I also made a prefab of the ball and paddle together but no idea what to do with it. Thanks to anyone who can help :)
Code for my ball
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BallScript : MonoBehaviour
{
public Rigidbody rbody;
public float MinVertMovement = 0.1f;
public float MinSpeed = 10f;
public float MaxSpeed = 10f;
private bool hasBeenLaunched = false;
void Start()
{
}
private float minVelocity = 10f;
private Vector3 lastFrameVelocity;
void FixedUpdate()
{
if (hasBeenLaunched == false)
{
if (Input.GetKey(KeyCode.Space))
{
Launch();
}
}
if (hasBeenLaunched)
{
Vector3 direction = rbody.velocity;
direction = direction.normalized;
float speed = direction.magnitude;
if (direction.y>-MinVertMovement && direction.y <MinVertMovement)
{
direction.y = direction.y < 0 ? -MinVertMovement : MinVertMovement;
direction.x = direction.x < 0 ? -1 + MinVertMovement : 1 - MinVertMovement;
rbody.velocity = direction * MinSpeed;
}
if (speed<MinSpeed || speed>MaxSpeed)
{
speed = Mathf.Clamp(speed, MinSpeed, MaxSpeed);
rbody.velocity = direction*speed;
}
}
lastFrameVelocity = rbody.velocity;
}
void OnCollisionEnter(Collision collision)
{
Bounce(collision.contacts[0].normal);
}
private void Bounce(Vector3 collisionNormal)
{
var speed = lastFrameVelocity.magnitude;
var direction = Vector3.Reflect(lastFrameVelocity.normalized, collisionNormal);
Debug.Log("Out Direction: " + direction);
rbody.velocity = direction * Mathf.Max(speed, minVelocity);
}
public void Launch()
{
rbody = GetComponent<Rigidbody>();
Vector3 randomDirection = new Vector3(-5f, 10f, 0);
randomDirection = randomDirection.normalized * MinSpeed;
rbody.velocity = randomDirection;
transform.parent = null;
hasBeenLaunched = true;
}
}
Code for my paddle
public class PaddleScript : MonoBehaviour
{
private float moveSpeed = 15f;
void Start()
{
}
void Update()
{
if (Input.GetKey(KeyCode.RightArrow) && transform.position.x<9.5)
transform.Translate(moveSpeed *Input.GetAxis("Horizontal")*Time.deltaTime, 0f, 0f);
if (Input.GetKey(KeyCode.LeftArrow) && transform.position.x>-7.5)
transform.Translate(moveSpeed *Input.GetAxis("Horizontal")*Time.deltaTime, 0f, 0f);
}
}
The simplest thing you can do to check wether the ball goes off screen is to place a trigger immediately off the perimeter of the camera, and add an OnTriggerEnter2D method to your ball.
/* Inside the ball script */
private void OnTriggerEnter() { // Use the 2D version if you're using 2D colliders
/* Respawning stuff */
}
Since you may want a bunch of different things to happen when that method triggers, you may want to use a Unity Event, which is not the king of performance but it probabily doesn't matter for a game like breakout.
using UnityEngine.Events;
public class BallScript : MonoBehaviour
{
public UnityEvent onBallOut;
/* ... */
private void OnTriggerEnter() {
onBallOut.Invoke();
}
}
You then probabily want a Respawn() method (not Reset() because that's a default MonoBehaviour call) which places the ball back to its original position, which you can store in a field as soon as the scene loads:
private Vector3 defaultPosition;
private void Start() {
defaultPosition = transform.position;
}
PS: If you aren't using the Start() method in your paddle script then remove it, cause it will be called by Unity even if empty.