我目前有一些物体是从预制件中产生的,并且正在尝试销毁该预制件中产生的一件物品。我在网上搜索,发现了很多不同的示例,但我一直无法使它们工作。我尝试设置实例化实例并销毁该实例,但无法使其正常工作。如果重要的话,派生/碰撞脚本将附加到主摄像头。与游戏工作中的其他项目发生碰撞,并且预制件确实将盒碰撞器设置为isTrigger。再说一次,我知道有很多例子可以解释这一点,但我无法使其正常工作,也许我不了解我应该实际做什么。
扳手代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class bloodVialSpawner : MonoBehaviour
{
public GameObject vialOfBlood;
private GameObject vialss;
private int hunger =10;
public int numOfVials;
public int minSpawnRange, maxSpawnRange;
public int minSpawnRange2, maxSpawnRange2;
// Start is called before the first frame update
float timeSpawns = 2;
List<GameObject> vialsInstantiated = new List<GameObject>();
void Start()
{
StartCoroutine(becomeHungry());
InvokeRepeating("SpawnVials", timeSpawns, timeSpawns);
}
private void Update()
{
if (hunger == -1)
{
Debug.Log("sigh");
}
}
void SpawnVials()
{
for (int i = 0; i < numOfVials; i++)
{
vialsInstantiated.Add(Instantiate(vialOfBlood, SpawnPosition(), Quaternion.identity) as GameObject);
}
}
Vector3 SpawnPosition()
{
int x, y, z;
y = 59;
x= UnityEngine.Random.Range(minSpawnRange, maxSpawnRange);
z = UnityEngine.Random.Range(minSpawnRange2, maxSpawnRange2);
return new Vector3(x, y, z);
}
IEnumerator becomeHungry()
{
while (true)
{
hunger -= 1;
yield return new WaitForSeconds(1);
Debug.Log(hunger);
}
}
}
Spawner脚本位于主摄像机上。使用的播放器是Unity提供的第一人称播放器。
销毁生成的对象的代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class destroyVial : MonoBehaviour
{
void OnTriggerEnter(Collider col)
{
if (col.gameObject.tag == "vials")
{
Destroy(col.gameObject);
Debug.Log("yell");
}
}
}
销毁代码在预制件上。请注意,预制件不是应有的层次结构。
答案 0 :(得分:3)
我看到您每次都在for循环中生成事物并覆盖vialss
变量:
for (int i = 0; i < numOfVials; i++)
{
vialss = Instantiate(vialOfBlood,
SpawnPosition(),
Quaternion.identity) as GameObject;
}
然后,在发生冲突时,您将销毁vialss
,在这种情况下,它将是最新生成的对象。并且,如果您在1次碰撞后与任何物体发生碰撞,vialss
将被删除,并且可能引发异常。也许这在您的游戏中很好,但是逻辑看起来有些瑕疵。
此外,我假设您想销毁与之碰撞的物体?这样的东西行不通吗?
void OnTriggerEnter(Collider col)
{
if (col.gameObject.tag == "vials")
{
Destroy(col.gameObject); // <== Remove colliding object
Debug.Log("yell");
}
}
如果出于某种不相关的原因,您需要所有产卵瓶的列表,也许您想将其转换为列表:
List<GameObject> spawnedVials = new List<GameObject>();
void SpawnVials()
{
for (int i = 0; i < numOfVials; i++)
{
var vial = Instantiate<GameObject>(vialOfBlood,
SpawnPosition(),
Quaternion.identity)
spawnedVials.Add(vial);
}
}
确保碰撞检测正常。您是说脚本已附加到相机上。请确保相机上有对撞机。但是您是说其他对撞机正在工作,所以我想您已经对此进行了控制。
我猜你的问题出在我最初描述的错误逻辑中。
答案 1 :(得分:1)
OnTriggerEnter必须位于与碰撞对象或小瓶本身相连的脚本上。它不能在主摄像机上,因为永远不会调用OnTriggerEnter。
答案 2 :(得分:0)
我建议您将脚本保留为一项工作,您应该将该脚本分为Spawn脚本和Collider脚本。并创建一个空的GameObject,其唯一目的是生成预制件。 您的代码中也有一些错误:
void OnTriggerEnter(Collider col)
{
if (col.gameObject.tag == "vials")
{
Destroy(col.gameObject); // Destroy the gameObject you're colliding with
Debug.Log("yell");
}
}
变量小瓶也无法满足您的期望,小瓶仅引用最后实例化的小瓶,因此最好将所有小瓶保存在列表中:
List<GameObject> vialsInstantiated = new List<GameObject>();
然后:
void SpawnVials()
{
for (int i = 0; i < numOfVials; i++)
{
vialsInstantiated.Add(Instantiate(vialOfBlood, SpawnPosition(), Quaternion.identity) as GameObject);
}
}