我无法为这个问题提出合适的标题,但我会解释。
我有一个碰撞盒,里面有一个脚本。此脚本有一个if语句,用于检测来自对象“Cube001”的冲突,并将Debug.Log发送到控制台。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class cubeDetect : MonoBehaviour {
void OnCollisionEnter(Collision collision) {
if (collision.gameObject.name == "Cube001")
{
Debug.Log("Cube001 hit!");
}
}
}
使用这种方法,盒子对撞机知道哪个立方体碰到了它,正如我用
指示的那样collision.gameObject.name == "Cube001"
但是说如果我有10个立方体碰撞碰撞盒,我怎么能更改if语句,而不是编写另外9个if语句来检查它是否接触到碰撞盒,我可以只有1个if语句检测到来自另一个多维数据集的冲突,知道哪个多维数据集命中框,并且凭借这些知识,能够执行Debug.Log以显示其名称点击方框
。我已尝试浏览OnCollisionEnter
的文档,但找不到任何可以帮助解决这个问题。
答案 0 :(得分:4)
一种选择是使用相同的名称标记要与之碰撞的所有相似对象。假设我们给他们标签“Cubicle”。然后我们可以做到以下几点:
Gameobject myCube;
void OnCollisionEnter(Collision collision) {
if (collision.collider.tag == "Cubicle")
{
Debug.Log(collision.gameObject.name + " hit!");
myCube = collision.gameObject; // store colliding gameobject info for use elsewhere
}
}
答案 1 :(得分:2)
您需要使用Dictionary
。这消除了对所有if
语句的需要。
这就是Dictionary
应该是这样的:
public static Dictionary<GameObject, System.Action> objToAction = new Dictionary<GameObject, Action>();
然后是一个函数,用于在实例化时将对象添加到字典中,或者如果它们已经存在,则添加到Start
函数中
public void registerObject(GameObject obj, System.Action action)
{
objToAction.Add(obj, action);
}
Dictionary
中的键是GameObject(Cube),您也可以使用string(GameObject的名称),但使用GameObject更好。 Dictionary
中的值存储了调用OnCollisionEnter
时要执行的操作。 因此应该将if
语句中的代码置于此处。这是通过Action
和delegate
完成的。您可以根据需要添加任意数量的游戏对象(立方体)。
您必须使用上述功能将这些多维数据集对象添加到词典中:
public GameObject prefab;
void Start()
{
//Create new Cube
GameObject obj = Instantiate(prefab);
obj.name = "Cube001";
//Add it to the Dictionary
registerObject(obj, delegate { Debug.Log("Hit: " + obj.name); });
}
您的新OnCollisionEnter
代码如下所示。无需if
语句。如果对象存在于Dictionary
中,则为每个关键GameObject执行我们存储在Dictionary
值中的代码。
void OnCollisionEnter(Collision collision)
{
Action action;
if (objToAction.TryGetValue(collision.gameObject, out action))
{
//Execute the approprite code
action();
}
}
请注意,objToAction
variabel应该是static
,或者放在附加到空GameObject的另一个脚本中,以便您可以访问它。应该只有一个实例。
答案 2 :(得分:1)
最适合我的是使用接口和组件并检查它。如果您在碰撞时有某些逻辑,那么这种方法很有效,但是当您不能使用tag
并将其设置为类似"collidable"
时。
接口解决方案:
public interface ICollidableObject
{
void CollidedWith(ICollidableObject other);
}
public class CollidableBlock : MonoBehaviour, ICollidableObject
{
public void CollidedWith(ICollidableObject other)
{
Debug.Log((other as MonoBehaviour).gameObject.name);
}
}
public class CollidableSphere : MonoBehaviour, ICollidableObject
{
public void CollidedWith(ICollidableObject other)
{
Debug.Log("sphere001");
}
}
就这样使用它:
void OnCollisionEnter(Collision collision)
{
ICollidableObject collidedWith = collision.gameObject.GetComponent<ICollidableObject>();
if ( collidedWith != null )
collidedWith.CollidedWith(this);
}