Почему бы вам не переместить пустоту OnCollisionEnter(Collision CollisionInfo)
в свой Enemy
скипет? Я думаю, что Enemy
должен теперь, если он столкнулся с чем-то, а не каким-то внешним скриптом.
Вы также можете использовать теги вместо имен при обнаружении коллизий.
Кроме того, gameObject.SetActive(false)
- если вы отключите ваш gameObject, ничего из его скрипта не произойдет, если вы не установите его в снова активен. Например, он отменяет все сопрограммы. Я бы сказал, что GameObject просто «спит». Он не разрушен - вы все еще можете видеть его в окне Иерархии - но он ничего не может сделать. (Кстати, в этом случае вы устанавливаете EnemyEvaporate
gameObject как отключенный, а не Enemy
gameObject.)
Кроме того, вы можете использовать Coroutine вместо Thread.Sleep(15)
. В Unity более распространено использование сопрограмм, чем потоков.
Теперь, испарение. Если вы хотите посчитать, сколько врагов испарилось (я полагаю, глядя на Evaporated++;
), у вас должен быть какой-то внешний объект для его подсчета. Самым простым способом, который я могу предложить сейчас, является создание GameObject с прикрепленным к нему скриптом EvaporationCounter : MonoBehaviour
. Вы также можете использовать шаблон Singleton, чтобы убедиться, что есть только один объект этого типа.
public class EvaporationCounter : MonoBehaviour
{
private int evaporates;
public int Evaporates {
get { return evaporates; }
private set
{
if (value >= 0) evaporates = value;
}
}
public void AddEvaporation()
{
Evaporates++;
}
}
Ваш класс Enemy может выглядеть следующим образом:
public class Enemy : MonoBehaviour
{
private IEnumerator coroutine;
private EvaporationCounter evaporationCounter;
private void Start()
{
evaporationCounter = FindObjectOfType<EvaporationCounter>();
}
private IEnumerator WaitAndSetInactive(float waitTime)
{
yield return new WaitForSeconds(waitTime);
gameObject.SetActive(false);
}
private void OnCollisionEnter(Collision CollisionInfo)
{
if (!CollisionInfo.gameObject.CompareTag("Map") && !CollisionInfo.gameObject.CompareTag("Player")) return;
if (evaporationCounter != null)
evaporationCounter.AddEvaporation();
StartCoroutine(WaitAndSetInactive(15f));
}
}
Вызов evaporationCounter.AddEvaporation()
из сценария Enemy это не лучшее решение, так как оно не относится к принципу инверсии зависимости , но я бы сказал, что это хорошо для начала с Unity.