简体   繁体   English

Unity中的同心Box对撞机

[英]Concentric Box colliders in Unity

I have two concentric Box Colliders on same GameObject. 我在同一个GameObject上有两个同心的Box Colliders。 Outer Box Collider rotates the object (on swiping the screen) and inner Box Collider plays animation when we touch the screen. 当我们触摸屏幕时,外部Box Collider会旋转对象(在屏幕上滑动),而内部Box Collider会播放动画。

But when ray goes from my mobile screen to outer Collider it destroys and does not pass through that collider. 但是,当光线从我的手机屏幕到达外对撞机时,它会毁坏并且不会通过该对撞机。

Is there any way to do it? 有什么办法吗?

You could make the outer one a Trigger Collider by checking Is Trigger in the inspector: 您可以通过在检查器中选中“是触发器”来将外部的一个作为触发器碰撞器: 在此处输入图片说明

and have the inner collider as just a collider. 并把内部对撞机当作对撞机 Then you can check the outer one with OnTriggerEnter and the inner one with OnCollisionEnter . 然后,你可以检查外层一个OnTriggerEnter和内层一个OnCollisionEnter

Alternatively you could give them different Tags and check for each Ray hit by checking for the tag (use OnTriggerEnter for this). 另外,您可以给他们提供不同的标签,并通过检查标签来检查每个射线命中(为此使用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
    }
}

Looking at what you want to do in your question though, using 2 concentric colliders is not as good as simply detecting which input action the user performs (tap or swipe) and acting according to that. 不过,使用2个同心对撞机查看您想在问题中做什么,不如简单地检测用户执行哪个输入操作(轻击或轻扫)并根据该操作进行操作。

Take a look at Physics.RayCastAll . 看看Physics.RayCastAll With RayCastAll your Ray won't return just the first collision but an array of all collisions. 使用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.
}

However, there are a couple of things to note with this approach: 但是,此方法需要注意两点:

  1. You will need to loop through each collision. 您将需要遍历每次碰撞。
  2. You will need to determine whether or not the user swiped or touched (you probably already have this down) 您将需要确定用户是否滑动或触摸(您可能已经对此感到沮丧)
  3. Colliders behind the GameObject will also return collisions. GameObject后面的碰撞器也将返回碰撞。

If there is not a specific reason you are using two colliders then I would do what Flaming Zombie suggested and use a single collider. 如果没有特定的原因,您要使用两个对撞机,那么我会按照Flaming Zombie的建议进行操作,并使用一个对撞机。 Here is a simple implementation: 这是一个简单的实现:

Component on collider: 对撞机组件:

public class ExampleComponent : MonoBehaviour
{
    public void OnInteract(bool isSwipe)
    {
        if (isSwipe)
        {
            //Rotate
        }
        else
        {
            //Animate
        }
    }
}

Raycast logic: 射线广播逻辑:

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
    } 
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM