using UnityEngine;
public interface IHealth
{
void TakeDamage(int damage);
void Death();
WarSide GetWarSide();
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BotHelth : MonoBehaviour, IHealth
{
public int health;
[SerializeField]
private WarSide _warSide;
private KnightAnimation _knightAnimation_cs;
void Start()
{
_knightAnimation_cs = GetComponent<KnightAnimation>();
}
public void TakeDamage(int damage)
{
health -= damage;
if (_knightAnimation_cs != null)
_knightAnimation_cs.SetTrigger("TakeDamage");
if (health <= 0)
{
Death();
}
}
void OnTriggerEnter(Collider other)
{
if (other.gameObject.GetComponent<IDamage>() != null)
{
TakeDamage(other.gameObject.GetComponent<IDamage>().Damage);
}
}
public void Death()
{
_knightAnimation_cs.SetBool("Death", true);
Destroy(GetComponent<KnightAttack>());
Destroy(GetComponent<KnightBrain>());
Destroy(GetComponent<KnightMove>());
Destroy(GetComponent<KnightAnimation>());
Destroy(this);
}
public WarSide GetWarSide()
{
return _warSide;
}
}
public IHealth _health;
void Start()
{
_health = GetComponent<IHealth>();
}
if (obj.GetComponent().GetWarSide() != _health.GetWarSide()), или Unity просто отказывается работать с обьектами на которых есть скрипт реализующий IHealth.
public GameObject FindTarget()
{
foreach (GameObject obj in _botsee_cs.GetObjectThatISee())
{
if (obj.GetComponent<IHealth>() != null)
{
if (obj != gameObject)
{
if (obj.GetComponent<IHealth>() != null)
{
if (obj.GetComponent<IHealth>().GetWarSide() != _health.GetWarSide())
{
return obj;
}
}
}
}
}
return null;
}
if (other.gameObject.GetComponent<IDamage>().GetMyHealth().GetWarSide() != GetWarSide())
NullReferenceException: Object reference not set to an instance of an object
BotHelth.OnTriggerEnter (UnityEngine.Collider other) (at Assets/Scripts/BotHelth.cs:44)
Что я не так делаю с интерфейсами?
namespace Health
{
public interface IHealth
{
void Lose(int amount);
void Restore(int amount);
}
public interface IMutable<out T>
{
T Current { get; }
}
public interface IFinal
{
event Action Over;
}
}
using System;
using UnityEngine;
namespace Health
{
public class Health : IHealth, IFinal, IMutable<int>
{
public event Action Over;
private readonly int _max;
private const int Min = 0;
public Health(int max)
{
_max = max;
Current = _max;
}
public int Current { get; private set; }
public void Lose(int amount)
{
SetCurrent(Current - amount);
}
public void Restore(int amount)
{
SetCurrent(Current + amount);
}
private void SetCurrent(int amount)
{
Current = Mathf.Clamp(amount, Min, _max);
if (Current == Min) Over?.Invoke();
}
}
}
namespace Health
{
public interface IDamageable
{
void ApplyDamage(int amount);
}
}
using UnityEngine;
namespace Health
{
public class Knight : MonoBehaviour, IDamageable
{
[SerializeField] private int _maxHealth = 100;
private Health _health;
private void Awake()
{
_health = new Health(_maxHealth);
}
private void OnEnable()
{
_health.Over += Die;
}
private void OnDisable()
{
_health.Over -= Die;
}
public void ApplyDamage(int amount)
{
_health.Lose(amount);
Debug.Log($"Damaged, hp left - {_health.Current}");
}
private void Die()
{
Debug.Log("Died");
Destroy(gameObject);
}
}
}
using UnityEngine;
namespace Health
{
public class Enemy : MonoBehaviour
{
[SerializeField] private int _damage = 50;
private void OnTriggerEnter2D(Collider2D other)
{
if (other.TryGetComponent(out IDamageable damageable))
{
damageable.ApplyDamage(_damage);
}
}
}
}
using System;
using UnityEngine;
[RequireComponent(typeof(BoxCollider))]
public class PlayerDetector : MonoBehaviour
{
internal event Action OnPlayerEnter, OnPlayerExit, OnPlayerStay;
protected virtual void OnTriggerEnter(Collider other)
{
if (OnPlayerEnter != null)
if (IsPlayer(other.gameObject))
{
OnPlayerEnter.Invoke();
}
}
protected virtual void OnTriggerExit(Collider other)
{
if (OnPlayerExit != null)
if (IsPlayer(other.gameObject))
{
OnPlayerExit.Invoke();
}
}
protected virtual void OnTriggerStay(Collider other)
{
if (OnPlayerStay!=null)
if (IsPlayer(other.gameObject))
{
OnPlayerStay.Invoke();
}
}
public static bool IsPlayer(GameObject ob)
{
if (ob.CompareTag("Player"))
return true;
return false;
}
}