10
votes

Comment détecter que mon objet est complètement dans une boîte?

Je développe un jeu que vous faites glisser et déposez des objets dans des boîtes et je n'ai aucune idée de ce qui est le moyen le meilleur et le plus efficace de détecter si mes objets sont dans une boîte.

Je suis bien conscient des collidènes et j'utilise des boxcolliders et des déclencheurs pour savoir si mon objet touche une boîte, mais je veux détecter le moment où mon objet (que nous pouvons supposer être sphère pour des raisons de simplicité Mais plus tard, un maillage) est complètement dans ma boîte à gâchette / collisionneur.

J'ai lu sur la méthode "Contient" des collidènes, mais IIRC, ils vérifient simplement si un seul point à l'intérieur de cette collision, mais je suis intéressé à savoir si l'objet entier est à l'intérieur du collisionneur.

merci d'avance.


0 commentaires

9 Réponses :


1
votes

Utilisez renduer.bounds propriété pour obtenir la liaison boîte de votre objet.

En fonction de l'objet que vous avez et de la précision que vous souhaitez vérifier pour être dans un collisionneur, vous pouvez utiliser l'un des moyens simples de déterminer cela.


0 commentaires

2
votes

Réponse courte: Si vous voulez une précision de 100%, votre algorithme ne sera jamais meilleur que O (| v |) (pire des cas) où v = {tous les sommets de maillage}, ce qui signifie que vous " d Run .Collides () sur chaque sommet et à chaque pause si vous en trouvez un qui est en dehors de votre conteneur.

Réponse plus longue: Plusieurs méthodes existent aux surfaces de maille de subdivide, des exemples incluent: Arbres KD , Octrees . Celles-ci sont au-delà de la portée d'une réponse afin de fournir une mise en œuvre complète, je vous suggère de voir les pages Wiki pour plus de détails.

Vous pouvez utiliser ces méthodes pour diviser votre maillage dans des jeux de sommets plus petits. Pour accélérer votre algorithme, vous commencerez à la racine de votre arborescence de subdivision et testez si ce nœud est contenu dans votre boîte à conteneurs. Continuez à traverser l'arbre jusqu'à ce que vous trouviez un nœud qui n'est pas contenu par votre boîte. Cela permettra à votre test "contient" d'échec plus rapidement, mais vous ferez finalement tester chaque sommet si votre boîte contient votre maillage.

CAVEAT: Cette solution ne fonctionne pas si votre maillage est animé. Dans ce cas, votre meilleur pari consiste à utiliser les limites autour des objets tels que les bras, les pieds, les jambes, etc. et utiliser ces informations pour creuser vos tests (). Encore une fois, vous finirez de devoir tester chaque sommet si le maillage est complètement à l'intérieur de votre boîte.


0 commentaires

0
votes

Ajoutez un boxCollider qui entoure l'ensemble de l'objet que vous testez et vérifiez ses limites MIN et MAX contenus dans le BoxCollider sa saisie ... Cela peut ne pas convenir à des objets de maille complexes, mais vous pourrez peut-être vous échapper. avec elle et son


0 commentaires

-2
votes

Vous devez utiliser un collisionneur. C'est une description. http://docs.unity3d.com/documentation/screpripTreference/collider.html


1 commentaires

Vous devriez parler de ce que le collisionneur fait. Ce lien pourrait changer ou être handicapé :).



0
votes

simplement, Vous pouvez placer un collisionneur de boîte au bas de votre conteneur. Si votre sphère ou quel que soit votre objet touche cela, il est complètement à l'intérieur du conteneur.


0 commentaires

2
votes

Entrez la description de l'image ici

Toutes les boîtes ont un boxcollider. Si un objet touche la deuxième case, l'objet doit être à l'intérieur de la première case.

Ce n'est pas une bonne solution, mais peut-être que ce sera utile.


0 commentaires

1
votes

Pour une approche plus raffinée et plus propre. Ce serait parfait pour ce que vous faites. Vous pouvez vérifier la distance entre l'objet que vous faites glisser et la case.

La boîte a une valeur AX, Y, Z, qui représente sa position dans l'espace.

Alors, alors que vous faites glisser votre gamebject. Juste 0,2 sur le X, Y ou Z du centre de votre boîte. Donc, utilisez simplement cette méthode pour calculer la distance entre votre objet glisser et la case. xxx

Ainsi, votre gamebject sera dans la case.


0 commentaires

1
votes

the Boîte dans une boîte Solution ci-dessus est une bonne option, mais si cela ne fonctionnera pas (en raison de la variable Objets de taille / forme) Vous pourrez peut-être accomplir quelque chose avec Physique.Raycast a> ou collider.raycast. J'ai eu un problème similaire où je devais tester si des points arbitraires étaient contenus à l'intérieur des collidènes (dont beaucoup étaient des objets concave inhabituels blobby).

L'idée de base est un "lit d'ongles" approche d'où je jette des rayons vers le point de Multiples directions. Si je frappe le collisionneur extérieur sur tous les rayons, je peux alors être confiant que le point est contenu dans le collisionneur (mais toujours pas complètement certain). Voici une photo: p>

raycast contient p>

sur cette image, Nous essayons de voir si le point bleu est à l'intérieur du collisionneur jaune. Les flèches vertes représentent des rayons réussies (le collisionneur jaune est touché) et le rose est infructueux (le collisionneur jaune n'est pas touché). P>

Voici un extrait de code illustrant ceci: p>

public static class CollisionUtils {

    private static readonly Vector3[] raycastDirections;

    // These are the directions that we shoot rays from to check the collider.
    static UltrasoundCollisionUtils() {
        raycastDirections = new Vector3[5];
        raycastDirections[0] = new Vector3(0,1,0);
        raycastDirections[1] = new Vector3(0,-1,-0);
        raycastDirections[2] = new Vector3(0,0,1);
        raycastDirections[3] = new Vector3(-1.41f, 0, -0.5f);
        raycastDirections[4] = new Vector3(1.41f, 0, -0.5f);
    }

    public static bool IsContained (Vector3 targetPoint, Collider collider) {
        // A quick check - if the bounds doesn't contain targetPoint, then it definitely can't be contained in the collider

        if (!collider.bounds.Contains(targetPoint)) {
            return false;
        }

        // The "100f * direction" is a magic number so that we 
        // start far enough from the point.
        foreach (Vector3 direction in raycastDirections) {
            Ray ray = new Ray(targetPoint - 100f * direction, direction);

            RaycastHit dummyHit = new RaycastHit();
            // dummyHit because collider.Raycast requires a RaycastHit
            if (!collider.Raycast(ray, out dummyHit, 100f)) {
                return false;
            }
        }

        return true;
    }
}


0 commentaires

0
votes

Il y a une méthode cependant ... pas si précis mais fonctionnera:

  1. Faites quatre vides avec collisionneur (cercle / boîte) comme quatre roues d'une voiture et rendre l'objet parent à ces objets vides avec collisionneur.
  2. Attribuez ensuite chaque collisionneur A Bool s'il est touché ou non ....
  3. Comptez le nombre de collidènes touchés avec le collisionneur de maille actuel ... estime approximativement l'orientation du chevauchement. Si c'est 2, cela signifie touché ou recouvert de latéralement. Ex: Si deux collisionniers + le collisionneur de maille collant, ce qui signifie qu'il est chevauché de latéralement ...

0 commentaires