Advertisement

Questions about inheritance in Unity

Started by April 24, 2018 01:41 AM
1 comment, last by Nypyren 6 years, 4 months ago

I've got a custom Brick class. I need at least one other type of Brick subclass, maybe more. These classes should do most of what the Brick class does, but have a bit of modified or added behavior. Normally I would assume inheriting from the Brick class would be the best choice for this, but when I tried to do it I was having some issues because of having to make additional instances of variables referencing manager objects. I'm not sure if I was just doing it wrong, or if maybe inheritance isn't the right solution here. Here is the Brick class:


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

public class Brick : MonoBehaviour {

	public AudioClip crack;
	public Sprite[] hitSprites;
	public static int breakableCount = 0;
	public GameObject smoke;

	private LevelManager levelManager;
	private int timesHit;
	private bool isBreakable;
	private float delay = 1.5f;                //Delay till bricks move down 1 row.
	private float timer = 0;				  // update ever frame and compare to delay. 

	// Use this for initialization
	void Start () {
		isBreakable = (this.tag == "Breakable");

		//keep track of breakable bricks
		if (isBreakable){
			breakableCount++;
		}
		timesHit = 0;
		levelManager = GameObject.FindObjectOfType<LevelManager>();
	}

	// Update is called once per frame
	void Update ()
	{
		timer += Time.deltaTime;

		if (timer >= delay) 
		{
			transform.Translate(0.0f, -1.0f,0.0f);
			timer = 0;
		}
	}

	void OnCollisionEnter2D (Collision2D collision)
	{
		if (collision.gameObject.tag == "EndScreen") {
			levelManager = GameObject.FindObjectOfType<LevelManager>();

			levelManager.LoadLevel("Lose");
		}
		AudioSource.PlayClipAtPoint (crack,transform.position);
		if (isBreakable) {
			HandleHits ();
		}
	}

	void HandleHits ()
	{
		timesHit++;
		int maxHits = hitSprites.Length + 1;
		if (timesHit >= maxHits) {
			breakableCount--;
			levelManager.BrickDestroyed();
			PuffSmoke();
			Destroy (gameObject);
		} else {
			LoadSprites();
		}
	}

	void LoadSprites ()
	{
		int spriteIndex = timesHit - 1;
		if (hitSprites [spriteIndex] != null) { //if statement keeps it from loading nothing if level designer forgets to assign a sprite
			this.GetComponent<SpriteRenderer> ().sprite = hitSprites [spriteIndex];
		} else {
			Debug.LogError("Brick sprite missing");
		}
	}

	void PuffSmoke ()
	{
		var smokePuff = Instantiate(smoke, transform.position, Quaternion.identity);
			var effect = smokePuff.GetComponent<ParticleSystem>().main;

			effect.startColor = GetComponent<SpriteRenderer>().color;
	}
}

What I need is for a different kind of brick to destroy all other adjacent bricks when the ball hits it. I considered just adding this functionality in to the brick class, and have it activate based on tags, but that didn't seem like the best solution. I'm open to any ideas. Thanks!

Overriding HandleHits seems like a reasonable thing for a derived class to do.  You might want to make a separate virtual method to replace the "if" part of HandleHits which actually destroys the brick, and keep the rest in HandleHits without overriding it.

You can create those other brick types the same way as your current Brick:  either put them on a prefab/scene, or use AddComponent<DerivedBrickType>().

You can change some (or all) of your private members to protected to allow derived classes to use the same variables and methods.

This topic is closed to new replies.

Advertisement