我是编程新手,目前正在尝试在Unity中做一个简单的游戏。
该代码使某些东西在碰到地面时消失了,并且效果很好,但是Unity Inspector中的“ Evaporated”变量没有更新。当有物体接触地面时,蒸发量应该增加,但仍保持在0。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading;
public class EnemyEvaporate : MonoBehaviour
{
public GameObject Enemy;
public int Evaporated;
void OnCollisionEnter(Collision CollisionInfo)
{
if (CollisionInfo.gameObject.name == "Map" || CollisionInfo.gameObject.name == "Player")
{
Thread.Sleep(15);
gameObject.SetActive(false);
Evaporated++;
}
}
}
答案 0 :(得分:0)
我不太确定您要在此脚本中尝试执行的操作。如果“蒸发”是某种分数的“全局计数器”,则需要用不同的方式编写它,而不是将其存储在此gameObject的脚本中。 它可能与您的gameObject.SetActive(false)有关,后者将停用您的对象,因此实际上,它还将同时禁用与之关联的脚本(尤其是此SetActive documentation)并将脚本从Update()中删除。给定一个gameObject(给定敌人)。如果场景中有4个敌人对象,那么实际上您有4个此脚本实例,每个实例都有自己的Evaporated变量)
答案 1 :(得分:0)
您为什么不将空白OnCollisionEnter(Collision CollisionInfo)
移到Enemy
呢?我认为Enemy
现在应该与任何东西(而不是某些外部脚本)发生冲突。
检测冲突时,也可以使用标签代替名称。
此外,gameObject.SetActive(false)
-如果将gameObject设置为Disabled,除非再次将其设置为active,否则脚本中不会发生其他事情。例如取消所有协程。我想说,gameObject只是在“睡觉”。它没有被销毁-您仍然可以在“层次结构”窗口中看到它-但它无能为力。 (顺便说一句,在这种情况下,您将EnemyEvaporate
gameObject设置为禁用,而不是Enemy
gameObject。)
此外,您可以使用Coroutine代替Thread.Sleep(15)
。在Unity中,使用协程比使用线程更常见。
现在,蒸发。如果要计算蒸发出多少个敌人(我想看一下Evaporated++;
),则应该有一些外部对象来对其进行计数。我现在建议的最简单方法是创建一个附加了EvaporationCounter : MonoBehaviour
脚本的GameObject。您还可以使用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++;
}
}
您的敌人职业可能看起来像:
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()
并不是最好的解决方案,因为它不适用于Dependency Inversion principle,但我想说这对于从Unity开始是有好处的。