【发布时间】:2017-03-31 00:58:45
【问题描述】:
我在同一个 GameObject 上有两个同心的 Box Collider。 Outer Box Collider 旋转对象(在滑动屏幕时),而 inner Box Collider 在我们触摸屏幕时播放动画。
但是当光线从我的手机屏幕到达外部碰撞器时,它会破坏并且不会穿过那个碰撞器。
有什么办法吗?
【问题讨论】:
我在同一个 GameObject 上有两个同心的 Box Collider。 Outer Box Collider 旋转对象(在滑动屏幕时),而 inner Box Collider 在我们触摸屏幕时播放动画。
但是当光线从我的手机屏幕到达外部碰撞器时,它会破坏并且不会穿过那个碰撞器。
有什么办法吗?
【问题讨论】:
您可以通过在检查器中选中 Is Trigger 来将外部的设置为 Trigger Collider:
并将内部对撞机作为一个对撞机。然后你可以用OnTriggerEnter检查外层,用OnCollisionEnter检查内层。
或者,您可以给它们不同的Tags,并通过检查标签来检查每条射线命中(为此使用OnTriggerEnter)。
void OnTriggerEnter (Collider other)
{
if (other.gameObject.tag == "Inner Cube")
{
// We have hit the inner cube
}
else if (other.gameObject.tag == "Outer Cube")
{
// We have hit the outer cube
}
}
不过,看看你想在你的问题中做什么,使用 2 个同心碰撞器不如简单地检测用户执行的输入操作(点击或滑动)并根据该操作进行操作。
【讨论】:
看看Physics.RayCastAll。使用 RayCastAll,您的 Ray 不会只返回第一次碰撞,而是返回所有碰撞的数组。
RayCastHit[] hits;
Ray ray = camera.ScreenPointToRay(Input.mousePosition);
hits = Physics.RaycastAll(ray);
// If you have objects behind your object then sort the hit array by distance:
// hits = hits.OrderBy(l => l.distance).ToArray();
for(int i = 0; i < hits.Length; i++)
{
RaycastHit hit = hits[i];
// From here you can use a tag approach similar to what Flaming Zombie posted to check whether the collision object supports swipes or touches.
// Once you find the first valid object then you can perform your action and break out of this loop.
}
但是,这种方法有几点需要注意:
如果您没有使用两个对撞机的特定原因,那么我会按照 Flaming Zombie 的建议使用单个对撞机。这是一个简单的实现:
对撞机上的组件:
public class ExampleComponent : MonoBehaviour
{
public void OnInteract(bool isSwipe)
{
if (isSwipe)
{
//Rotate
}
else
{
//Animate
}
}
}
光线投射逻辑:
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
ExampleComponent c = hit.transform.GetComponent<ExampleComponent>()
if(c != null)
{
c.OnInteract(isSwipe); // You'll need to implement isSwipe
}
}
【讨论】: