2016-08-22 5 views
1

저는 당구 게임을 만들려고하고 있으며, 다른 볼을 치고 나서 큐볼 (하얀 공)이 움직이는 방향을 계산하고 싶습니다.Unity3D : Raycasthit 방향을 찾으십시오.

Visuals

당신은 내가 광선이 볼과 레이 캐스트가로 방향이 변경됩니다되는 각도/방향에 도달하는 각도/방향을 계산 싶어 볼 수 있듯이. linerenderer (3)에서 사용할 수 있도록 Vector3 변수로 표시하려면 각도가 필요합니다.

벌써 치는 공의 방향이 계산되었습니다.

당신이 위대한 도움이 될 수 있다면 도와주세요!

현재 코드 :

RaycastHit hitz; 
if (Physics.SphereCast(transform.position, 0.8f, location - transform.position, out hitz, Mathf.Infinity, lmm2)) 
{ 

    lineRenderer2 = hitz.collider.GetComponentInChildren<LineRenderer>(); 
    lineRenderer2.SetVertexCount(2); 

    if (!Input.GetKey(KeyCode.Mouse0)) 
     lineRenderer2.SetPosition(0, hitz.point); 

    if (!Input.GetKey(KeyCode.Mouse0)) 
     { 
      Vector3 start = hitz.point; 
      Vector3 end = start + (-hitz.normal * 4); 

      if (lineRenderer2) 
      { 
       if (!Input.GetKey(KeyCode.Mouse0)) 
        lineRenderer2.SetPosition(1, end); 
      } 

      if(lineRenderer3) 
      { 
       anglelel = Vector3.Angle(hitz.normal, hitz.point); 
       Vector3 cross = Vector3.Cross(hitz.normal, hitz.point); 
       if(cross.y > 0) 
       { 

        tzt = Quaternion.AngleAxis(90f, hitz.normal) *realStick.transform.forward; 
       } 
       if (cross.y < 0) 
       { 
        anglelel = -anglelel; 
        tzt = Quaternion.AngleAxis(270f, hitz.normal) * realStick.transform.forward; 
       } 
       Vector3 start2 = hitz.point; 
       Vector3 end2 = start2 + ((tzt) * 5f); 
       lineRenderer3.SetPosition(0, hitz.point); 
       lineRenderer3.SetPosition(1, end2); 
      } 
     } 
} 

이 시간 내 주셔서 감사합니다.

편집 :

코드의이 부분은 현재 일부 진전을 makign,이 변경되었습니다하지만 여전히, 그것은 충분하지 않습니다.

if(lineRenderer3) 
{ 
    anglelel = Vector3.Angle(hitz.normal, hitz.point); 
    Vector3 cross = Vector3.Cross(hitz.normal, hitz.point); 
    if(cross.y > 0) 
    { 

      tzt = Quaternion.AngleAxis(90f, hitz.normal) *realStick.transform.forward; 
    } 
     if (cross.y < 0) 
     { 
      anglelel = -anglelel; 
      tzt = Quaternion.AngleAxis(270f, hitz.normal) * realStick.transform.forward; 
     } 
     Vector3 start2 = hitz.point; 
     Vector3 end2 = start2 + ((tzt) * 5f); 
     lineRenderer3.SetPosition(0, hitz.point); 
     lineRenderer3.SetPosition(1, end2); 
    } 
+0

이것은 엄격하게 게임을 코딩하는 것보다 더 많은 물리학적인 문제입니다. 큐볼의 그 지점에서 힘을 적용한 결과를 시각화하려한다면, 얼굴 법선과 같은 물리적 속성을 사용하여 계산을 수행해야합니다. 시작을위한 개념은 다음과 같습니다. 코드로 변환해야합니다. http://physics.stackexchange.com/questions/43232/force-applied-off-center-on-an-object – Serlite

+0

나는 찾고 있었다. 그들이 말하고있는 문제는 2D 공간에서, 게임은 3D에서입니다. – Ssiro

+0

게임은 3D로 렌더링되지만 당구대가 평평하지 않으면 모든 물리학이 모두 XZ 평면에 남아 있기 때문에 모든 물리학을 2D로 단순화 할 수 있습니다. – Serlite

답변

3

if(lineRenderer3) 
     { 
      Vector3 start2 = hitz.point; 
      //THIS IS WHERE I'M CURRENTLY STUCK AT 
      Vector3 end2 = start2 + (hitz.point * 0.7f); 
      lineRenderer3.SetPosition(0, hitz.point); 
      lineRenderer3.SetPosition(1, end2); 
     } 

전에하는의이 작품으로이 작품을 보자. 우선, 이것은 고전적인 Physics 101 문제입니다. 충돌시 각도 2 당구 공은 완벽한 90도 각도입니다. 다음 그림에서 녹색과 파란색 벡터가 직각으로 만드는 방법 참고 : 이제

Physics of a pool ball

을, 당신은 또한 모두 공의 센터로 연락의 관점에서 모두의 표면에 정상입니다주의해야 불알. 이것은 화합을 통해 hit.normal을 사용하여 우리가 쳤던 공의 이동 방향을 알 수 있음을 의미합니다. -1 * hit.normal

이제 큐볼이 움직이는 방향을 얻으려면 이전 벡터를 90도 회전시켜야합니다. 우리는 쿼터니온으로이 작업을 수행 할 수 있습니다. Quaternion.AngleAxis(-90, Vector3.up)

우리는 원래의 이동 벡터와 큐볼이 이동할 각도 사이의 각도를 계산할 수 있습니다 (예 : 풀 테이블에 수직 인 방향). 내 테스트 장면이 시각적 인 예에서 Vector3.Angle(-1 * cue.up, rotate90 * hit.normal)

살펴 보자 일 :

Unity pool table

나는 색상 연합 벡터를 코딩하는 것은 위의 그림과 일치합니다. 유일한 차이점은 우리의 hit.normal을 나타내는 검은 색 벡터입니다.

여기에 코드입니다 :

public class Main : MonoBehaviour { 
    public Transform cue,cueBallPostHit; 
    public int dist = 10; 
    public Color red,green,blue; 

    RaycastHit hit; 
    float scale,ballAngle; 
    Quaternion rotate90; 
    Vector3 cueBallHitPosition; 

    void Start() { 
     rotate90 = Quaternion.AngleAxis(-90, Vector3.up); 
    } 

    void FixedUpdate() { 
     if(Physics.SphereCast(cue.position, .5f, cue.up, out hit, dist)) 
     { 
      // Calculate variables 
      cueBallHitPosition = hit.point + (.5f * hit.normal); 
      scale = (cue.position - hit.point).magnitude; 
      ballAngle = Vector3.Angle(-1 * cue.up, rotate90 * hit.normal); 
      print(ballAngle); 

      // Cue Ball Direction and normal 
      Debug.DrawLine(cue.position, cueBallHitPosition, red); 
      Debug.DrawRay(cueBallHitPosition, hit.normal, Color.black); 
      // Ball direction 
      Debug.DrawRay(hit.point + (-.5f * hit.normal), -1 * hit.normal * scale, blue); 
      // Cue Ball Direction 
      Debug.DrawRay(cueBallHitPosition, rotate90 * hit.normal * scale, green); 

      // Visual for where the ball will hit 
      cueBallPostHit.position = cueBallHitPosition; 
     } 
     else 
     { 
      Debug.DrawRay(cue.position, cue.up * dist, blue); 
      cueBallPostHit.position = cue.position + (2 * cue.up); 
     } 
    } 
} 

희망 당신이 올바른 방향으로 시작하는 데 도움이 충분히 있어야하지만 당신은 질문이 있으면 알려 주시면 좀 더 설명을 추가합니다.