Why don't these GameObjects respond to a delegate
I have been following the Brackeys 2D platformer series and have come to episode 28 but for some reason enabling the Upgrade Menu doesn’t disable the enemy AI. Here is my code. I’m using FlyingEyeballAI in place of enemyAI. Link To Tutorial
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Enemy : MonoBehaviour
{
[System.Serializable]
public class EnemyStats
{
public int maxHealth = 100;
public int damage = 5;
[SerializeField]
private int _curHealth;
public int curHealth
{
get { return _curHealth; }
set { _curHealth = Mathf.Clamp(value, 0, maxHealth); }
}
public void Init()
{
curHealth = maxHealth;
}
}
public float shakeAmt = 0.1f;
public float shakeLength = 0.1f;
public EnemyStats stats = new EnemyStats();
public Transform deathParticles;
public string enemyName;
[Header("Optional: ")]
[SerializeField]
private StatusIndicator statusIndicator;
public List<GameObject> items = new List<GameObject>();
void Start()
{
stats.Init();
if (statusIndicator != null)
{
statusIndicator.SetHealth(stats.curHealth, stats.maxHealth);
}
if(deathParticles == null)
{
Debug.LogError("No deathParticles referenced on enemy");
}
GameMaster.gameMaster.onToggleUpgradeMenu += OnUpgradeMenuToggle;
}
public void DamageEnemy(int damage)
{
stats.curHealth -= damage;
if (stats.curHealth <= 0)
{
GameMaster.KillEnemy(this);
}
if (statusIndicator != null)
{
statusIndicator.SetHealth(stats.curHealth, stats.maxHealth);
}
}
void OnCollisionEnter2D(Collision2D _colInfo)
{
Player _player = _colInfo.collider.GetComponent<Player>();
if(_player != null)
{
_player.DamagePlayer(stats.damage);
}
}
public void dropRandomItem()
{
Instantiate(items[Random.Range(0, items.Count - 1)], transform.position, Quaternion.identity);
}
void OnUpgradeMenuToggle(bool active)
{
GetComponent<FlyingEyeballAI>().enabled = !active;
}
void OnDestroy()
{
GameMaster.gameMaster.onToggleUpgradeMenu -= OnUpgradeMenuToggle;
}
}
using UnityEngine;
using System.Collections;
public class GameMaster : MonoBehaviour
{
public static GameMaster gameMaster;
public AudioClip[] audioClip;
void Awake()
{
if (gameMaster == null)
{
gameMaster = GameObject.FindGameObjectWithTag("gameMaster").GetComponent<GameMaster>(); ;
}
}
public Transform playerPrefab;
public Transform spawnPoint;
public float spawnDelay = 3;
public Transform spawnPrefab;
public CameraShake cameraShake;
public AudioSource RespawnSound;
[SerializeField]
public GameObject gameOverUI;
[SerializeField]
private GameObject upgradeMenu;
public delegate void UpgradeMenuCallBack(bool active);
public UpgradeMenuCallBack onToggleUpgradeMenu;
private static int _remainingPlayerLives = 1;
public static int RemainingLives
{
get{return _remainingPlayerLives;}
}
void Start()
{
if(cameraShake == null)
{
Debug.LogError("No CameraShake referenced on gameMaster");
}
}
void Update()
{
if (Input.GetKeyDown(KeyCode.U))
{
ToggleUpgradeMenu();
}
}
private void ToggleUpgradeMenu()
{
upgradeMenu.SetActive(!upgradeMenu.activeSelf);
onToggleUpgradeMenu.Invoke(upgradeMenu.activeSelf);
}
public IEnumerator RespawnPlayer()
{
PlaySound(0);
yield return new WaitForSeconds(spawnDelay);
Instantiate(playerPrefab, spawnPoint.position, spawnPoint.rotation);
PlaySound(1);
GameObject clone = Instantiate(spawnPrefab, spawnPoint.position, spawnPoint.rotation) as GameObject;
Destroy(clone, 2f);
}
public void EndGame()
{
Debug.LogError("EndGame");
gameOverUI.SetActive(true);
}
public static void KillPlayer(Player player)
{
Destroy(player.gameObject);
_remainingPlayerLives -= 1;
if (_remainingPlayerLives <= 0)
{
gameMaster.EndGame();
}
else
{
gameMaster.StartCoroutine(gameMaster.RespawnPlayer());
}
}
public static void KillEnemy(Enemy enemy)
{
gameMaster._KillEnemy(enemy);
}
public void _KillEnemy(Enemy _enemy)
{
PlaySound(2);
_enemy.dropRandomItem();
GameObject _clone = Instantiate(_enemy.deathParticles, _enemy.transform.position, Quaternion.identity) as GameObject;
Destroy(_clone, .5f);
cameraShake.Shake(_enemy.shakeAmt, _enemy.shakeLength);
Destroy(_enemy.gameObject);
}
void PlaySound(int clip)
{
GetComponent<AudioSource>().clip = audioClip[clip];
GetComponent<AudioSource>().Play();
}
}
I'm not going to read through that mess. Remove pointless empty lines and indent your code properly. This wall of code is unreadable. This question also doesn't belong to the main / default space of UnityAnswers. We have a Help Room for such questions. I'll move it over.
Answer by Static-Dynamo · Jun 03, 2016 at 06:13 AM
So a few things.....
1) As Bunny83 mentioned you have posted a huge block of code. Most of which has nothing to do with your question and makes your question difficult to answer. However I'm going to take a stab at it.
2) I don't fully understand what your code does and I would also recommend looking into how to trace your code. Also methods for debugging your code. You can learn a lot about what is working/broken in your code with Debug.Log and tracing through your code.
3) You have a line of code here
void OnUpgradeMenuToggle(bool active)
{
GetComponent<FlyingEyeballAI>().enabled = !active;
}
But I cannot find any place in your code that calls this function appropriately.
OnUpgradeMenuToggle needs to be sent a boolean (i.e. a value of true or false) that is what the "active" variable is.
However I don't see you ever calling this function in your code while sending it a value. I see this function called in the following lines, Line #75
GameMaster.gameMaster.onToggleUpgradeMenu += OnUpgradeMenuToggle;
And line 132
GameMaster.gameMaster.onToggleUpgradeMenu -= OnUpgradeMenuToggle;
Neither of these calls pass a valid value to the function.
So.... you can either change your function OnUpGradeMenuToggle to the following
void OnUpgradeMenuToggle()
{
GetComponent<FlyingEyeballAI>().enabled = !GetComponent<FlyingEyeballAI>().enabled;
}
Or, you can actually pass it a true or false value so it can do something with it to change the FlyingEyeballAI.
Out of curiosity how much do you know about programming? If you are starting out I'd highly recommend trying to understand how functions work and what it means when there is a parameter in the () of a function.
Good luck!
By the way I'm only new to delegates. $$anonymous$$y current fix was just having the enemy check if the player was upgrading and disabling its AI until it finished upgrading. Then it would begin its path to the player again. $$anonymous$$y current fix works but I would like to learn how to use delegates.