2017-08-08 59 views
1

視覺輔助
厚度VS寬度:here如何確定厚度與寬度? (使用光線投射)

請查看GIF短。
這裏的厚度不同於寬度,因爲有多個壁,因爲有外部和內部圓柱體。厚度是圓柱體任何一側的外壁/內壁之間的距離的測量值,其中厚度是從一端到另一端的距離,其中包括兩者之間的中空空間。

上的GIF快速概要提供
-On每次點擊原點(藍色)和目的地點被創建(橙色)球體來表示,其中用戶點擊和用於計算距離的解釋結束點(顯示在GUI上)。

原點定義了用戶在對象對象的表面上單擊的位置,並且目標定義了與原點的世界Y軸垂直的點,其中第二條射線朝向第一條射線投射,擊中另一邊對撞機。

電流:

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

目前,寬度是到位的功能。我想計算厚度而不必進入物體內部(如在gif中看到的那樣)。

驚人蔘考
http://answers.unity3d.com/questions/386698/detecting-how-many-times-a-raycast-collides-with-a.html

這傢伙基本上有同樣的問題我和有一個解決方案能夠工作。我不確定Linecasting如何與Raycasting相互作用。

+0

讓我們[在聊天中繼續討論](http://chat.stackoverflow.com/rooms/151438/discussion-between-ryemoss-and-jtth)。 – ryeMoss

回答

1

保持:

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

隨着(學分MirrorMirror's見地的帖子,@ryemoss他的器樂諮詢和援助):

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
通過射線廣播,您可以設置起點,方向和距離,以便在該方向上進行檢查,使用線陣廣播可以簡單地設置起點和終點,並在這兩點之間進行檢查。

因此,如果您明確知道最終目的地,請使用linecast,如果您想檢查特定方向但沒有特定終點,請使用raycast。

解決方案
首先,使用初始raycast來獲取第一個點hit.point。然後,將ray.origin設置到對撞機外面的世界空間中的一個點(我們首先碰撞的對象的對撞機以獲得hit.point),並將ray.direction設置爲面向第一個點處的射線,hit 。點。

最後,使用while循環在ray中創建新的linecast。創建新位置(每次通過while循環更新,直到linecast達到hit.point),每次與對象發生碰撞,直到linecast達到hit.point。一旦hit.point已經到達,這意味着物體的每個表面都被擊中,並且在每次擊中時,都會創建一條新線,直到線到達第一個初始點hit.point。要計算厚度,請取第一個hit,hit.point和hitcast之前的hitcast之間的距離,以反向linecast命中hit.point,PreviousPoint。

UPDATE
1-修改代碼正確處理單面對象(例如:平面)。
2-增加計數器以防止無法計算的特殊情況。
3-提高可讀性。