I'm making a breakout game, and I wanted to add a healthbar that decreases when the ball touches a certain object with the tag "hazard". I have a Game Manager Script, and A Pickup interact script, but with the way I set it up, I'm kind of confused with how to trigger takedamage from my GM script to my pickup script, considering I put my playerhealth elements into my GM script, so I can attach it to empty gameobject call Game Manager, since the actual player isnt in the hierarchy, but instantiated during runtime. I'm hoping I don't have to redo the whole thing just for this purpose. If someone could help me figure this out, I'd appreciate it.
Here's my GM script:
public class GM : MonoBehaviour
{
public int lives = 3;
public int bricks = 20;
public float resetDelay = 1f;
public Text livesText;
public GameObject gameOver;
private GameObject clonePaddle;
public GameObject youWon;
public GameObject bricksPrefab;
public GameObject paddle;
public GameObject deathParticles;
public static GM instance = null;
public int startingHealth = 100;
public int currentHealth;
public Slider healthSlider;
bool isDead;
bool damaged;
void Awake()
{
currentHealth = startingHealth;
TakeDamage(10);
if (instance == null)
instance = this;
else if (instance != this)
Destroy(gameObject);
Setup();
}
public void TakeDamage(int amount)
{
damaged = true;
currentHealth -= amount;
healthSlider.value = currentHealth;
if (currentHealth <= 0)
{
LoseLife();
}
}
public void Setup()
{
clonePaddle = Instantiate(paddle, transform.position, Quaternion.identity) as GameObject;
Instantiate(bricksPrefab, transform.position, Quaternion.identity);
}
void CheckGameOver()
{
if (bricks < 1)
{
youWon.SetActive(true);
Time.timeScale = .25f;
Invoke("Reset", resetDelay);
}
if (lives < 1)
{
gameOver.SetActive(true);
Time.timeScale = .25f;
Invoke("Reset", resetDelay);
}
}
void Reset()
{
Time.timeScale = 1f;
Application.LoadLevel(Application.loadedLevel);
}
public void LoseLife()
{
lives--;
livesText.text = "Lives: " + lives;
Instantiate(deathParticles, clonePaddle.transform.position, Quaternion.identity);
Destroy(clonePaddle);
Invoke("SetupPaddle", resetDelay);
CheckGameOver();
}
void SetupPaddle()
{
clonePaddle = Instantiate(paddle, transform.position, Quaternion.identity) as GameObject;
}
public void DestroyBrick()
{
bricks--;
CheckGameOver();
}
}
And here's my Pickup Script:
public class Pickups : MonoBehaviour {
public float PaddleSpeedValue = 0.5f;
private bool isActive = false;
public float thrust=20f;
public Rigidbody rb;
GameObject player;
private void OnTriggerEnter(Collider other)
{
if (other.tag == "Hazard")
{
isActive = true;
Destroy(other.gameObject);
}
}
}
The Pickups class should not have or store a reference to the player at all (although it is not clear from your question if this is a script attached to the player or attached to something else). Your Game Manager class should. Afterall, it is the class that is responsible for managing the game which includes the player. From there, you can use GetComponent<?>() to access any scripts attached to the player GameObject.
Then as the GM contains a public static reference to itself, any other class can get a reference to the player by doing GM.instance.player as needed, even if the player is created and destroyed several times (as the GM should always have a reference to the current one!)
Presumably the clonePaddle field is the player('s GameObject), all you have to do is make it public.
Related
I am working on a 2D platformer and I am using cinemachine to follow my player.
When a player drops off a platform under -20 y, the player is destroyed and instantiated as a clone to the spawn point as expected, but the camera is not following, as the original player is destroyed: it says missing on the "Follow" Slot.
Is there any way to solve it? I prefer using Destroy and Instantiate as respawning instead of teleporting the original player to the respawn point.
This is the respawn script (GameMaster)
public class GameMaster : MonoBehaviour
{
public static GameMaster gm;
void Start()
{
if (gm == null)
{
gm = GameObject.FindGameObjectWithTag("GM").GetComponent<GameMaster>();
}
}
public Transform playerPrefab, spawnPoint;
public int spawnDelay = 2;
public void RespawnPlayer() {
//yield return new WaitForSeconds(spawnDelay);
Instantiate(playerPrefab, spawnPoint.position, spawnPoint.rotation);
Debug.Log("ADD SPAWN PARITCAL");
}
public static void Killplayer(Player player) {
Destroy(player.gameObject);
gm.RespawnPlayer();
}
}
here is the player script if it is needed
public class Player : MonoBehaviour
{
[System.Serializable]
public class PlayerStats
{
public int Health = 100;
}
public PlayerStats playerStats = new PlayerStats();
public int FallBoundary = -20;
void FixedUpdate()
{
if (transform.position.y <= FallBoundary)
{
DamagePlayer(1000);
}
}
public void DamagePlayer(int damage) {
playerStats.Health -= damage;
if (playerStats.Health<=0)
{
Debug.Log("Kill Player");
GameMaster.Killplayer(this);
}
}
}
You can cache the cinemachine inside your start method and then assign to follow the player at respawn.
Your code will become
using Cinemachine;
public class GameMaster : MonoBehaviour
{
public static GameMaster gm;
public CinemachineVirtualCamera myCinemachine;
void Start()
{
if (gm == null)
{
gm = GameObject.FindGameObjectWithTag("GM").GetComponent<GameMaster>();
}
myCinemachine = GetComponent<CinemachineVirtualCamera>();
}
public Transform playerPrefab, spawnPoint;
public int spawnDelay = 2;
public void RespawnPlayer() {
//yield return new WaitForSeconds(spawnDelay);
var newPlayer = Instantiate(playerPrefab, spawnPoint.position, spawnPoint.rotation);
Debug.Log("ADD SPAWN PARITCAL");
myCinemachine.m_Follow = newPlayer;
}
public static void Killplayer(Player player) {
Destroy(player.gameObject);
gm.RespawnPlayer();
}
}
You must assign the new object to follow like this:
myCinemachine.m_Follow = spawnedPlayer;
I made two scripts. One that'll keep track of the player's health, health bar and cause the screen to flash when the player is damaged. The other script is meant to be placed on any object I wish to do damage to the player, on contact. My problem is, Nothing seems to be doing any damage to the player.
PlayerHealth.cs:
using UnityEngine;
using UnityEngine.UI;
public class PlayerHealth : MonoBehaviour
{
public int currentHealth;
public float flashSpeed = 5;
public Slider healthSlider;
public Color flashColour = new Color(1, 0, 0, 0.1f);
bool isDead;
bool damaged;
private void Awake()
{
currentHealth = 100;
}
private void Update()
{
damaged = false;
}
public void TakeDamage(int amount)
{
damaged = true;
currentHealth -= amount;
healthSlider.value = currentHealth;
}
}
AttackPlayer.cs:
using UnityEngine;
public class AttackPlayer : MonoBehaviour
{
public float timeBetweenAttacks = 0.5f;
public int attackDamage = 10;
GameObject player;
PlayerHealth playerHealth;
float timer;
private void Awake()
{
player = GameObject.FindGameObjectWithTag("Player");
playerHealth = player.GetComponent<PlayerHealth>();
}
private void OnTriggerEnter2D(Collider2D col)
{
if (col.gameObject == player)
{
Attack();
}
}
private void Update()
{
timer += Time.deltaTime;
if(playerHealth.currentHealth <=0)
{
// TODO: add death script here.
}
}
void Attack()
{
timer = 0f;
if(playerHealth.currentHealth > 0)
{
playerHealth.TakeDamage(attackDamage);
}
}
}
The player has a rigidbody2D. The player and damaging objects have Box Collider 2D's on them.
Make sure that the players Collider has isTrigger enabled.
attackDamage is public -> set in the inspector. Make sure it is not 0.
You could use
[Range(1,100)] public int attackDamage = 10;
to automatically clamp the value in the inspector.
A guess but I'ld say your Collider might not be on the GameObject player but probably on one of its children => the condition col.gameObject == player is not true.
Instead of GameObject references rather compare the PlayerHealth (since there is only one) reference like
private void OnTriggerEnter2D(Collider2D col)
{
// gets PlayerHealth component on this or any parent object
var health = col.GetComponentInParent<PlayerHealth>();
if (health == playerHealth)
{
Attack();
}
}
You have
private void Update()
{
damaged = false;
}
public void TakeDamage(int amount)
{
damaged = true;
currentHealth -= amount;
healthSlider.value = currentHealth;
}
I don't know what else should happen on TakeDamage but the value of damaged is resetted in Update so right after it was set by the Trigger because Physics events like OnTriggerEnter are executed before Update (see execution Order).
Hint: Instead of
player = GameObject.FindGameObjectWithTag("Player");
playerHealth = player.GetComponent<PlayerHealth>();
you could also use
playerHealth = FindObjectOfType<PlayerHealth>();
if that component exists only once in your scene.
Or to be more flexible (having multiple Players) all you have to do is change your OnTriggerEnter2D and Attack method to
private void OnTriggerEnter2D(Collider2D col)
{
// gets PlayerHealth component on this or any parent object
var health = col.GetComponentInParent<PlayerHealth>();
if (health != null)
{
Attack(health);
}
}
void Attack(PlayerHealth health)
{
timer = 0f;
if(health.currentHealth > 0)
{
health.TakeDamage(attackDamage);
}
}
So you wouldn't need to get the reference before.
The playerLife variable doesn't update visibly in the Inspector or the on-screen Health Text, but the Player still dies because the playerLife drops below zero.
I've determined that the Player prefab attached to the Zombie GameObject is solely the Player prefab rather than the in-scene active Player. How do I make it so that the zombies always reference the in-scene active Player rather than the basic Player prefab, by script? (Also, it won't allow me to manually drag the active Player into the Zombie)
Call hierarchy for playerLife
public class Player : MonoBehaviour
{
public RaycastHit hit;
public int gunDamage = 1;
public Zombie zombie;
private float hitForce = 100f;
public float playerLife;
private Vector3 flareLower = new Vector3(0, -0.5f, 0);
void Start()
{
spawnPoints = playerSpawnPoint.GetComponentsInChildren<Transform>();
playerLife = 200;
}
void Update() //T-toggle
{
if (Input.GetButton("Fire1"))
{
LazerBeam();
}
if (reSpawn != lastToggle)
{
ReSpawn();
reSpawn = false;
}
else
lastToggle = reSpawn;
}
public void Life (float damage)
{
playerLife -= damage;
if (playerLife <=0)
{
playerLife = 100;
SceneManager.LoadScene(2);
}
}
}
public class Zombie : MonoBehaviour
{
public int currentHealth;
public Player player;
public PlayerLifeCollider playerCollider;
private int damage;
public void Damage(int damageAmount)
{
currentHealth -= damageAmount;
if (currentHealth <= 0)
{
PlayerLifeCollider.instance.ObjectsInRange.Remove(gameObject);
DestroyZombie();
}
}
public void DestroyZombie()
{
Destroy(gameObject);
// gameObject.SetActive(false);
}
public void DamagePlayer(float damage)
{
player.Life(damage);
}
}
As you said, the problem is that you are not referencing the Player object on your scene, but a prefab one. To avoid that, you can add a Start function to the Zombie script and ask to look for what should be the only Player instance in the scene. For this, you can use the FindObjectOfType function:
void Start()
{
player = FindObjectOfType<Player>();
}
Considering you will only have one Player script in your entire scene, what you can also do is to save in your Player class a static reference to your Player instance.
public class Player : MonoBehaviour
{
private static Player _instance;
public static Player Instance
{
get
{
if (_instance == null)
{
_instance = FindObjectOfType<Player>();
}
return _instance;
}
}
// Reset of your class
}
You can then get this reference in your Zombie script:
public class Zombie : MonoBehaviour
{
static Player player;
void Start()
{
if(player == null)
{
player = Player.Instance;
}
}
// Rest of your class content
}
This way, you will only have one call to the FindObjectOfType function instead of once per object using the Zombie script.
public void Damage(int damageAmount)
{
currentHealth -= damageAmount;
print(currentHealth);// will show in terminal if thats what you are asking
if (currentHealth <= 0)
{
PlayerLifeCollider.instance.ObjectsInRange.Remove(gameObject);
DestroyZombie();
}
}
The issue I am having is with a dropped item i pick up adding ammo to a gun.
Built a Gun class with all the methods and variables.
Built a Rifle class derived from the Gun class
The Rifle works perfect No Issues
I now am adding a "PickUp" system where x amount of enemies drop a pickup.
This is the script on the item to pick up
public class AddARAmmo : MonoBehaviour
{
private Rifle rifle;
private void Awake()
{
rifle = FindObjectOfType<Rifle>();
}
private void OnTriggerEnter(Collider other)
{
if (other.tag == string.Format("Player"))
{
rifle.AddAmmo(30);
Destroy(gameObject);
}
}
}
The rifle and gun scripts are kind of long but here is the relevant stuff from the Gun base class is public abstract class ......
public int bulletsInStock;
public void AddAmmo(int ammoToAdd)
{
bulletsInStock += ammoToAdd;
UpdateAmmo();// updates on screen Ammo
}
......
Then in the Rifle Class
public override void Modifiers() // This is where the guns starts are stored
{
bulletSpeed = 2777f;
bulletsInStock = 200;
bulletsInMag = 30;
bulletPoolSize = 40;
desiredRPS = 15;
muzzleFlashPoolSize = 10;
}
I am getting an Object Reference Not Set To An Instance
The Rifle script is on the rifle in the game hierarchy so it should find it.
Does anyone see anything wrong?
Here is the full Gun script
public abstract class Gun : MonoBehaviour
{
[SerializeField] protected GameObject muzzleFlash;// spawns on barrelEnd
[SerializeField] protected Transform muzzleFlashFolder;
[SerializeField] protected Transform bulletFolder;// is the parent of bullets
[SerializeField] protected Transform barrelEnd;// Gameobject at the end of barrel
[SerializeField] protected Rigidbody bullet; // The bullet Prefab
[SerializeField] protected Text ammo; // OSD
[SerializeField] protected Text weaponType; // OSD
[HideInInspector] protected float bulletSpeed;
[HideInInspector] public int bulletsInStock;
[HideInInspector] protected int bulletsInMag;
[HideInInspector] protected float desiredRPS;// Rounds Per Second
[HideInInspector] protected List<Rigidbody> poolOfBullets; // Make pool for bullets
[HideInInspector] protected int bulletPoolSize; // The size off the buletpool 10 works really well
[HideInInspector] protected List<GameObject> muzzleFlashPool;// pool for muzzleflash
[HideInInspector] protected int muzzleFlashPoolSize; // size of the muzzle pool
[HideInInspector] protected int bulletsLeft; // In mag
[HideInInspector] protected bool isReloading = false;
[HideInInspector] protected float timeLeft;// for fire speed
[HideInInspector] protected float fireSpeedTimer;
[HideInInspector] protected Weapons weaponsScript;
[HideInInspector] protected PlayerController playerController;
protected void FixedUpdateStuff()
{
if (playerController.canMove && Input.GetAxisRaw(string.Format("Fire1")) > 0)
{
FireSpeedControl();// call the fire timer controller
}
if (playerController.canMove && Input.GetAxisRaw(string.Format("Fire1")) == 0)
{
timeLeft = 0f;
}
if (playerController.canMove && Input.GetKeyDown(KeyCode.R) && !isReloading)
{
Reload();
}
UpdateAmmoOnInput();
}
protected void UpdateStuff()
{
if (gameObject.activeInHierarchy)// when a gun become active it updates OSD
{
UpdateWeaponType();// With its Name
}
}
protected void RPSFinder()// finds the Rounds Per Second the gun will fire
{
fireSpeedTimer = (100 / desiredRPS) / 100;
timeLeft = fireSpeedTimer;
}
protected void Fire()// Instatiates a clone of the desired bullet and fires it at bulletSpeed
{
if (!Empty())
{
Rigidbody bulletClones = GetPooledBullet();
if (bulletClones != null)
{
bulletClones.transform.SetPositionAndRotation(barrelEnd.position, barrelEnd.rotation);
bulletClones.gameObject.SetActive(true);
}
GameObject muzzleFlashClone = GetMuzzleFlash();
if (muzzleFlashClone != null)
{
muzzleFlashClone.transform.position = barrelEnd.position;
muzzleFlashClone.gameObject.SetActive(true);
}
bulletClones.AddForce(-bulletClones.transform.up * bulletSpeed * .304f); //add the force in FPS * .304 = MPS
bulletsLeft--;// the holder to know how many bullets are left in the magazine
isReloading = false;// Gun cannot reload unless it has been fired
UpdateAmmo();// Updates the on screen ammo count and the stock usage
return;
}
}
protected void Reload()
{// this removes full magazine from the stock and the stock can still go negitive FIX FIX FIX FIX FIX FIX FIX
if (bulletsInStock > 0)
{
isReloading = true;
bulletsInStock -= bulletsInMag;
bulletsLeft = bulletsInMag;
UpdateAmmo();
}
}
protected bool Empty()// Checks the magazine to see if there are bullets in it
{
if (bulletsLeft == 0)
return true;
else
return false;
}
protected void FireSpeedControl()// controls the RPS fired by the gun Controled by Update() Input
{
if (timeLeft > 0f)
{
timeLeft -= Time.deltaTime;
}
else if (timeLeft <= 0f)
{
Fire();
timeLeft = fireSpeedTimer;
}
}
protected Rigidbody GetPooledBullet()// retrieve a preInstatiated bullet from the pool to use when shooting
{
for (int i = 0; i < poolOfBullets.Count; i++)
{
if (!poolOfBullets[i].gameObject.activeInHierarchy)
{
return poolOfBullets[i];
}
}
return null;
}
protected GameObject GetMuzzleFlash()
{
for (int i = 0; i < muzzleFlashPool.Count; i++)
{
if (!muzzleFlashPool[i].gameObject.activeInHierarchy)
{
return muzzleFlashPool[i];
}
}
return null;
}
protected void UpdateAmmo()// Update the on screen ammo information
{
ammo.text = bulletsLeft + string.Format( " : ") + bulletsInStock;
}
protected abstract void UpdateWeaponType();
protected void UpdateAmmoOnInput()
{
if (weaponsScript.updateAmmo)
{
UpdateAmmo();
weaponsScript.updateAmmo = false;
}
}
public abstract void Modifiers();
protected void StartStuff()
{
Modifiers();// Call first to store indvidual gun stats
playerController = FindObjectOfType<PlayerController>();
weaponsScript = FindObjectOfType<Weapons>();
poolOfBullets = new List<Rigidbody>();
for (int i = 0; i < bulletPoolSize; i++)
{
Rigidbody bulletClone = (Rigidbody)Instantiate(bullet);
bulletClone.gameObject.SetActive(false);// Builds the Inspector list
poolOfBullets.Add(bulletClone); //and populates the elements with clones
bulletClone.transform.parent = bulletFolder.transform;
}
muzzleFlashPool = new List<GameObject>();
for (int i = 0; i < muzzleFlashPoolSize; i++)
{
GameObject muzzleFlashClone = (GameObject)Instantiate(muzzleFlash);
muzzleFlashClone.gameObject.SetActive(false);
muzzleFlashPool.Add(muzzleFlashClone);
muzzleFlashClone.transform.parent = muzzleFlashFolder.transform;
}
bulletsLeft = bulletsInMag;
ammo.text = string.Format( " 0 : 0 ");
RPSFinder();// Run last to set the RPS of the gun
}
public void AddAmmo(int ammoToAdd)
{
bulletsInStock += ammoToAdd;
UpdateAmmo();
}
}
}
and here is the full Rifle script
public class Rifle : Gun
{
//All variables are stored in the "Gun" Script
//Copy this onto guns
void Start()
{
StartStuff();
}
private void FixedUpdate()
{
FixedUpdateStuff();
}
void Update()
{
UpdateStuff();
}
public override void Modifiers() // This is where the guns starts are stored
{
bulletSpeed = 2777f;
bulletsInStock = 200;
bulletsInMag = 30;
bulletPoolSize = 40;
desiredRPS = 15;
muzzleFlashPoolSize = 10;
}
protected override void UpdateWeaponType()
{
weaponType.text = string.Format("Assault Rifle");
}
}
There are three reasons why FindObjectOfType may return null:
Let's say the script name to find is Rifle:
And FindObjectOfType<Rifle>() is returning null.
1.The GameObject the Rifle script is attached to is in-active. You must make sure that the GameObject is active.
2.The Rifle is not attached to any GameObject at-all. Make sure that the Rifle script is attached to a GameObject..
It doesn't matter if the script is enabled or disabled, it should find it as long as the GameObject it is attached to is active. See #1.
3.When loading new scene:
When you trigger scene loading with functions such as SceneManager.LoadScene
and Application.LoadLevel, FindObjectOfType will not be able to find anything until the scene loading it done.
See here for how to check when scene has finished loading.
If you still have problems which you shouldn't, simply find the GameObject then get the Rifle component from it. Assuming that the name of the GameObject is "Rifle" too.
GameObject.Find("Rifle").GetComponent<Rifle>();
I figured out how to fix this for anyone having a similar issue.
The issue was when the enemy dropped the item, the Awake() method ran. When it ran the gun was inactive in the scene so FindObjectOfType did not find the reference script because as mentioned above, It has to be active in the scene to be found.
So what I did was create a Holder script i called EnemyDrops and this script calls the findobjectoftypes for the guns. That way the call is done on the initial game start .
I then changed the pickup to find the EnemyDrops script(which is on en empty game object) and send the call to it.
EnemyDrops Script
private Handgun handgun;
private void Awake()
{
handgun = FindObjectOfType<Handgun>();
}
public void AddHandgunAmmo(int x)
{
handgun.AddAmmo(x);
}
and the new pickup script
public class AddHandgunAmmo : MonoBehaviour
{
private EnemyDrops enemyDrops;
private void Awake()
{
enemyDrops = FindObjectOfType<EnemyDrops>();
}
private void OnTriggerEnter(Collider other)
{
if (other.tag == string.Format("Player"))
{
enemyDrops.AddHandgunAmmo(50);
Destroy(gameObject);
}
}
}
As you can see it all still works with passing values through the methods just had to have a "middle man" to relay the information. But this works just fine
Thanks for everyones feedback and I hope this helps someone
I have made a breakout game using unity tutorials and everything seemed to work well, but when I played it in the game mode there were some errors. So after I tried fixing the errors, the bricks wont get destroyed anymore. I tried undoing it, writing the code anew or even writing the same project anew but nothing works. What can I do?
These are the codes for my game which are exactly like the codes in the tutorial!
Paddle:
public class Paddle : MonoBehaviour {
public float paddleSpeed = 1f;
private Vector3 playerPos = new Vector3(0, -9f, 0);
void Update ()
{
float xPos = transform.position.x + (Input.GetAxis("Horizontal")*paddleSpeed);
playerPos = new Vector3(Mathf.Clamp(xPos, -7.5f, 7.5f), -9f, 0f);
transform.position = playerPos;
}
}
Ball:
public class Ball : MonoBehaviour {
private float ballInitialVelocity = 600f;
private Rigidbody rb;
private bool ballInPlay;
void Awake ()
{
rb = GetComponent<Rigidbody>();
}
void Update ()
{
if(Input.GetButtonDown("Fire1") && ballInPlay==false)
{
transform.parent = null;
ballInPlay = true;
rb.isKinematic = false;
rb.AddForce(new Vector3(ballInitialVelocity, ballInitialVelocity, 0));
}
}
}
GM:
using UnityEngine; using System.Collections;
public class deathZone : MonoBehaviour {
void OnTriggerEnter(Collider col)
{
GM.instance.loseLife();
}
}
public class GM : MonoBehaviour {
public int Lives = 3;
public int bricks = 16;
public float resetDelay = 1f;
public Text livesText;
public GameObject gameOver;
public GameObject bricksPrefab;
public GameObject youWon;
public GameObject paddle;
public GameObject deathParticles;
public static GM instance = null;
private GameObject clonePaddle;
void Start()
{
if (instance == null)
instance = this;
else if (instance != this)
instance = null;
setup();
}
public void setup()
{
clonePaddle = Instantiate(paddle, new Vector3(0, -9,0), Quaternion.identity) as GameObject;
Instantiate(bricksPrefab, new Vector3((float)18.5, (float)-61.14095, (float)238.4855), Quaternion.identity);
}
void checkGameOver()
{
if (bricks < 1)
{
youWon.SetActive(true);
Time.timeScale = .25f;
Invoke("Reset", resetDelay);
}
if (Lives < 1)
{
gameOver.SetActive(true);
Time.timeScale = .25f;
Invoke("Reset", resetDelay);
}
}
void Reset()
{
Time.timeScale = 1f;
Application.LoadLevel(Application.loadedLevel);
}
public void loseLife()
{
Lives--;
livesText.text = "Lives: " + Lives;
Instantiate(deathParticles, clonePaddle.transform.position, Quaternion.identity);
Destroy(clonePaddle);
Invoke("SetupPaddle", resetDelay);
checkGameOver();
}
void SetupPaddle()
{
clonePaddle = Instantiate(paddle, new Vector3(0, -9, 0), Quaternion.identity) as GameObject;
}
public void destroyBrick()
{
bricks--;
checkGameOver();
}
}
Bricks:
public class Bricks : MonoBehaviour {
public GameObject brickParticle;
void OnCollisionEnter(Collision other)
{
Instantiate(brickParticle, transform.position, Quaternion.identity);
GM.instance.destroyBrick();
Destroy(gameObject);
}
}
deathZone:
public class deathZone : MonoBehaviour {
void OnTriggerEnter(Collider col)
{
GM.instance.loseLife();
}
}
In this tutorial you have to make sure all of the bricks GameObject have both the Bricks script and a BoxCollider components. Also the ball should have a Rigidbody and a SphereCollider components.
An easy way to debug Collisions or Triggers is to simply use a Debug.Log("something"); as a first command in the OnCollisionEnter/OnTriggerEnter/... methods.
It seems that the issue is with colliders. You should check them in Editor if they are placed right ( since no debug.log on collision is written). Also make sure that you are using Colliders and not colliders2D ( collision is called by diffrent method)