2017-08-08 2 views
1

Aides visuelles
épaisseur vs largeur: hereComment déterminer l'épaisseur par rapport à la largeur? (L'utilisation raycasting)

S'il vous plaît voir le court gif.
L'épaisseur est ici différente de la largeur car il y a plusieurs parois car il y a des cylindres extérieurs et intérieurs. L'épaisseur est la mesure de la distance entre la paroi extérieure/intérieure de n'importe quel côté du cylindre où, comme l'épaisseur est la distance d'une extrémité à l'autre englobant l'espace creux entre.

synopsis rapide sur les gifs fourni
-Sur chaque cliquez sur le point d'origine (bleu) et le point de destination (orange) orbes sont créés pour indiquer où l'utilisateur clique et le point final interprété utilisé pour calculer la distance (affiché sur l'interface graphique). L'origine définit où l'utilisateur clique sur la surface d'un collisionneur d'objets et la destination définit le point, perpendiculaire à l'axe Y du monde de l'origine, où un second rayon lancé vers le premier rayon, frappe de l'autre côté de le collisionneur.

actuel:

Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); 
RaycastHit hit; 
if (Physics.Raycast(ray, out hit)) 
{ 

//obtain the vector where the ray hit the collider. 
    hitPoint = hit.point; //origin point 
//offset the ray, keeping it along the XZ plane of the hit 
    Vector3 offsetDirection = -1 * hit.normal; 
//offset a long way, minimum thickness of the object 
    ray.origin = hit.point + offsetDirection * 100; 
//point the ray back at the first hit point 
    ray.direction = (hit.point - ray.origin).normalized; 
//raycast all, because there might be other objects in the way 
    RaycastHit[] hits = Physics.RaycastAll(ray); 
    foreach (RaycastHit h in hits) 
    { 
     if (h.collider == hit.collider) 
     { 
      hitBack = h.point; //destination point 
     } 
    } 
} 

Actuellement, la largeur est la fonctionnalité en place. Je veux calculer l'épaisseur sans avoir à aller à l'intérieur d'un objet (comme vu dans le gif).

référence incroyable
http://answers.unity3d.com/questions/386698/detecting-how-many-times-a-raycast-collides-with-a.html

Ce type avait essentiellement la même question que moi et a une solution qui pourrait fonctionner. Je ne suis pas sûr comment Linecasting fonctionne contre Raycasting.

+0

Laissez-nous [continuer cette discussion dans le chat] (http://chat.stackoverflow.com/rooms/151438/discussion-between-ryemoss-and-jtth). – ryeMoss

Répondre

1

Keep:

Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); 
RaycastHit hit; 
if (Physics.Raycast(ray, out hit)) 
{ 

//obtain the vector where the ray hit the collider. 
    hitPoint = hit.point; //origin point 
//offset the ray, keeping it along the XZ plane of the hit 
    Vector3 offsetDirection = -1 * hit.normal; 
//offset a long way, minimum thickness of the object 
    ray.origin = hit.point + offsetDirection * 100; 
//point the ray back at the first hit point 
    ray.direction = (hit.point - ray.origin).normalized; 

Remplacer:

//raycast all, because there might be other objects in the way 
    RaycastHit[] hits = Physics.RaycastAll(ray); 
    foreach (RaycastHit h in hits) 
    { 
     if (h.collider == hit.collider) 
     { 
      hitBack = h.point; //destination point 
     } 
    } 

Avec (crédits à MirrorMirror's après perspicaces et @ryemoss pour ses conseils et de l'aide instrumentale):

int counter = 0; 
bool calculating = false; //set this to true on click 
Vector3 Point, PreviousPoint, Goal, Direction; 
Point = ray.origin; 
Goal = hit.point; 
Direction = ray.direction; 

PreviousPoint = Vector3.zero; 
while (calculating == true) 
{ 
    counter++; 
    RaycastHit hit2; 
    if (Physics.Linecast(Point, Goal, out hit2)) 
    { 
     if(counter > 100) 
     { 
      hitBack = hitPoint; 
      counter = 0; 
      calculating = false; 
      break; 
     } 
     PreviousPoint = hit2.point; 
     Point = hit2.point + (Direction/10000f); 
    } 
    else 
    { 
     if (PreviousPoint == Vector3.zero) 
      hitBack = hitPoint; 
     else 
      hitBack = PreviousPoint; 

     calculating = false; 
     counter = 0; 
    } 
} 

Linecast vs Raycast
Avec un rayon, vous définissez le point de départ, la direction et la distance à vérifier dans cette direction, avec un linéaire, vous définissez simplement les points de départ et d'arrivée et vérifie entre ces 2 points. Donc, si vous connaissez spécifiquement la destination finale, utilisez Linecast, si vous voulez vérifier dans une direction spécifique mais n'avez pas de point final spécifique, utilisez Raycast.

Solution
Tout d'abord, utilisez la raycast initiale pour obtenir le premier point, hit.point. Ensuite, placez le rayon.origin à un point dans l'espace du monde en dehors du collisionneur (le collisionneur de l'objet avec lequel nous sommes entrés en collision pour obtenir hit.point), et réglez le rayon.direction pour faire face au rayon au premier point, frapper .point. Enfin, utilisez une boucle while pour créer un nouveau linecast, à l'adresse ray.origine nouvelle position (mise à jour chaque fois par la boucle while jusqu'à ce qu'un linecast atteigne hit.point), chaque fois qu'une collision avec l'objet se produit jusqu'à ce qu'un linecast atteigne hit.point. Une fois que hit.point a été atteint, cela signifie que chaque surface de l'objet a été touchée et à chaque coup, une nouvelle ligne a été créée jusqu'à ce qu'une ligne atteigne le premier point initial, hit.point. Pour calculer l'épaisseur, prenez la distance entre le premier coup, hit.point, et le coup précédent au hit-point inverse frappant hit.point, point précédent.

UPDATE
1 Révision du code pour gérer correctement les objets 1-verso (ex: avions).
2-Compteur ajouté pour éviter les cas particuliers dans lesquels le calcul n'est pas possible.
3-Améliorer la lisibilité.