So when enemy is spawned i try to init him here enemy.Init();
but had error Object reference not set to an instance of an object. But here Debug.Log(enemy._enemyHealth);
i get number of enemy health. How i can Init my enemy from here if enemy has class 'Usual Enemy' and it extends from this class 'Enemy' and i wiil have more enemy child cllases?
I vave class Enemy
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public abstract class Enemy : MonoBehaviour
{
private GameObject _player;
private Animator _animator;
private Rigidbody _rigidbody;
private bool _isSpawned;
private const int _enemySpavnTime = 5;
[SerializeField] public float _enemyHealth;
[SerializeField] protected float _rotationSpeed = 10f;
[SerializeField] protected float _moveSpeed;
[SerializeField] protected float _damage;
[SerializeField] protected DamageBox _damageBox;
[SerializeField] protected TriggerBox _triggerBox;
private EnemyCondition _enemyCondition = EnemyCondition.Dead;
private enum EnemyCondition
{
Spawn,
Run,
Attack,
Dead
}
void Start()
{
_rigidbody = GetComponent<Rigidbody>();
_animator = GetComponent<Animator>();
_player = GameObject.FindWithTag("Hero");
_damageBox.HeroHited += enemyAttack;
_triggerBox.HeroInAttackRange += enemyGetAngry;
_triggerBox.HeroOutAttackRange += enemyGetChill;
}
void Update()
{
if (_player != null)
{
if (_enemyCondition == EnemyCondition.Run)
{
EnemyPlayerRotation(_player);
} else if (_enemyCondition == EnemyCondition.Attack)
{
EnemyPlayerRotation(_player);
}
}
}
void FixedUpdate() {
if (_enemyCondition == EnemyCondition.Run)
{
EnemyPlayerFollow();
}
}
public virtual void Init() {
enemySpawn();
}
protected virtual void EnemyPlayerFollow() {
Vector3 direction = transform.TransformDirection(new Vector3(0, 0, 1));
_rigidbody.velocity = direction * _moveSpeed;
}
protected virtual void EnemyPlayerRotation(GameObject target) {
Vector3 direction = (target.transform.position - transform.position).normalized;
Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x, 0, direction.z));
transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * _rotationSpeed);
}
public virtual void EnemyDamage(float damage)
{
_enemyHealth -= damage;
if (_enemyHealth <= 0) {
PoolManager.Instanse.Despawn(gameObject);
}
}
public virtual void enemySpawned() {
_enemyCondition = EnemyCondition.Run;
_rigidbody.isKinematic = false;
_animator.SetTrigger("Run");
StopCoroutine(SpawnMoveUp());
Debug.Log("enemySpawned");
}
protected virtual void enemyAttack(Hero trigger)
{
if (_enemyCondition == EnemyCondition.Attack) {
trigger.HeroDamage(_damage);
}
}
protected virtual void enemyGetAngry() {
_enemyCondition = EnemyCondition.Attack;
_animator.SetTrigger("Attack");
}
protected virtual void enemyGetChill() {
_enemyCondition = EnemyCondition.Run;
_animator.SetTrigger("Run");
}
protected virtual void enemySpawn() {
_animator.SetTrigger("Spawn");
_animator.speed = 0.0f;
StartCoroutine(SpawnMoveUp());
}
IEnumerator SpawnMoveUp()
{
float spawnStage = 0.0f;
Vector3 startPoint = transform.position;
while(spawnStage <= 1.0f) {
transform.position = Vector3.Slerp(startPoint, new Vector3(transform.position.x, 0, transform.position.z), spawnStage);
spawnStage += Time.deltaTime/_enemySpavnTime;
yield return null;
}
_animator.speed = 1.0f;
}
}
And I have class that spawns enemies
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemiesSpawner : MonoBehaviour
{
[SerializeField] private Levels[] _levelsList;
private List<GameObject> _enemiesQueue = new List<GameObject>();
private List<GameObject> _levelEnemiesList = new List<GameObject>();
private List<int> _levelEnemiesCount = new List<int>();
private bool _isBossSpawned = false;
// private int _currentLevel = PlayerPrefs.GetInt("currentLevel") - 1;
private int _currentLevelNumber = 0;
private float _reloadPause = 0;
private int currentEnemiesListPos = 0;
private int allEnemiesCount = 0;
private float _reloadTime;
private float _spawnRadius;
private float _spawnOfsetRadius = 2f;
[SerializeField] private GameObject _boss;
[SerializeField] private GameObject _spawnPoint;
void Start() {
Levels currentLevelObj = _levelsList[_currentLevelNumber];
_levelEnemiesCount.AddRange(currentLevelObj.enemiesCount.ToArray());
_levelEnemiesList = currentLevelObj.enemiesPrefabs;
_spawnRadius = currentLevelObj.spawnRadius;
_reloadTime = currentLevelObj.spawnReload;
foreach(int num in _levelEnemiesCount) {
allEnemiesCount += num;
}
while(_enemiesQueue.Count < allEnemiesCount){
int randomIndex = Random.Range(0, _levelEnemiesCount.Count);
if (_levelEnemiesCount[randomIndex] == 0) {
continue;
} else {
_enemiesQueue.Add(_levelEnemiesList[randomIndex]);
_levelEnemiesCount[randomIndex] --;
}
}
}
public void SetPlayerForSpawn (GameObject player) {
_spawnPoint = player;
}
void Update ()
{
if (_spawnPoint != null){
SpawnEnemies();
}
}
public void SpawnEnemies()
{
_reloadPause += Time.deltaTime;
if (_reloadPause >= _reloadTime && currentEnemiesListPos < allEnemiesCount) {
GameObject go = PoolManager.Instanse.Spawn(_enemiesQueue[currentEnemiesListPos],new Vector3((Random.value < 0.5f) ? Random.Range(_spawnPoint.transform.position.x + _spawnOfsetRadius, _spawnPoint.transform.position.x + _spawnRadius) : Random.Range(_spawnPoint.transform.position.x - _spawnOfsetRadius, _spawnPoint.transform.position.x - _spawnRadius), -5, (Random.value < 0.5f) ? Random.Range(_spawnPoint.transform.position.z + _spawnOfsetRadius, _spawnPoint.transform.position.z + _spawnRadius) : Random.Range(_spawnPoint.transform.position.z - _spawnOfsetRadius, _spawnPoint.transform.position.z - _spawnRadius)), Quaternion.identity);
Enemy enemy = go.GetComponent<Enemy>();
Debug.Log(enemy._enemyHealth);
enemy.Init();
_reloadPause = 0;
currentEnemiesListPos ++;
} else if (currentEnemiesListPos == allEnemiesCount && _isBossSpawned == true) {
Instantiate(_boss,new Vector3(0,0,0), Quaternion.identity);
_isBossSpawned = true;
}
}
}
So when enemy is spawned i try to init him here enemy.Init();
but had error Object reference not set to an instance of an object. But here Debug.Log(enemy._enemyHealth);
i get number of enemy health. How i can Init my enemy from here if enemy has class 'Usual Enemy' and it extends from this class 'Enemy' and i wiil have more enemy child cllases?