2013-10-21 2 views
0

이것은 현재 follow on from my last question입니다. 기능을 확장하려고 합니다만 일부 주요 도로 블록을 치고 있습니다.Unity의 레이 캐스팅 및 타이머 관련 문제

내가 특정 태그로 오브젝트를 칠 광선을 투사하는 카메라를 가지고 다음과 같이

내 목표이다. 레이가 일정 시간 동안 태그를 때리면 나는 뭔가를 찾고있다. 단지 내가 바라는 것은 디버그 메시지 나 간단한 것이다. 레이가 태그가있는 객체를 히트하지 않으면 타이머가 업데이트되지 않기를 원합니다. 사용자가 객체를 보았고 되돌아 오는 경우 타이머가 0에서 다시 시작되기를 원하며 사용자가 태그 중 다른 태그, 즉 타이머가 다시 시작될 때 비슷한 기능을 원합니다.

내 타이머는 의도 한대로 작동하지 않으며 내가보고있는 것에 상관없이 계속 계산됩니다. 나는 이것에 3 시간을 보냈다. 그리고 나는 동일한 코드 행을 반복해서 시도하는 터널 비전을 얻었다.

신선한 눈빛을 가진 사람이 지금까지 내가 한 일을 살펴보고 나에게 그것이 무엇인지를 지적 할 수 있습니까?

public float end_time; 
public float start_time; 
private float running_time; 

public Texture2D progress_bar_empty; 
public Texture2D progress_bar_full; 
public Material highlight_material; 
public float progress = 0; 
public bool hited = false; 


public List<string> _tags = new List<string>(); 

private GameObject hit_object; 
private Material oldMat; 


RaycastHit hit; 
// Use this for initialization 
void Start() 
{ 
    start_time = Time.deltaTime; 
    running_time = 0; 
} 

// Update is called once per frame 
void Update() 
{ 
    EyeTarget(); 
    Check(hited); 
} 

void EyeTarget() 
{ 
    try 
    { 
     Vector3 fwd = transform.TransformDirection(Vector3.forward); 
     if (Physics.Raycast(transform.position, fwd, out hit)) 
     { 
      foreach(string t in _tags) 
      { 
       if(hit.collider.gameObject.tag == t) 
       { 
        HighLight(); 

       }     
      } 
     } 
     Debug.DrawRay(transform.position, fwd, Color.red); 
    } 
    catch(Exception e) 
    { 
     Debug.Log(e.Message); 
    } 
} 

void ResetTimer() 
{ 
    start_time = Time.time; 
    running_time = 0f; 
    //Debug.Log("resetting timer"); 
} 


void HighLight() 
{ 
    if(hit_object == null) 
    { 
     ResetTime(); 
     oldMat = hit.transform.renderer.material; 
     hit.collider.gameObject.renderer.material = highlight_material; 
     hit_object = hit.collider.gameObject; 
     hited = true; 
    }  
    else if(hit.transform.tag != hit_object.tag) 
    { 
     //hit.collider.gameObject.renderer.material = oldMat; 
     hit_object = null; 
     hit_object.renderer.material = oldMat; 
     progress = 0; 
     Debug.Log("hi"); 
     hited = false; 
    } 
} 
// see if ray has hit object 
void Check(bool hit) 
{ 

    if(hit) 
    { 
     start_time = Time.time - end_time; 
     running_time += Time.deltaTime; 
     if (running_time >= end_time) 
     { 

      hited = false; 
     } 
    } 
    else if(hited == false) 
     ResetTime(); 

} 

void ResetTime() 
{ 
     start_time = Time.time; 
    running_time = 0f; 
    Debug.Log("restting timer"); 
} 
+0

몇 가지 문제가 있지만 주요 문제는 레이크 캐스트가 올바른 태그가있는 객체에 도달하지 않는 한 '하이라이트'를 호출하지 않는다는 것입니다. 처음에'hit_object = null'을 설정 한 다음 그 자료를 설정하려고 시도한 'else if'의 'Highlight'에도 오류가 있습니다. – Jerdak

답변

1

최대한 혼자있는 버전을 남기려고했습니다. 이 버전은 커서가 태그가있는 객체에서 벗어 났을 때 타이머를 멈추고 다른 태그가있는 객체가 raycast 아래에있을 때 0에서 다시 시작합니다.

내 코드는 약간 장황하지만 상황을 더 쉽게 볼 수 있습니다.

public float end_time; 
public float start_time; 
public float running_time; 

public Texture2D progress_bar_empty; 
public Texture2D progress_bar_full; 
public Material highlight_material; 
public float progress = 0; 

public bool trackTimer = false; 

public List<string> _tags = new List<string>(); 

public GameObject lastHitObject = null; 
private Material oldMat; 

// Use this for initialization 
void Start() 
{ 
    ResetTimer(); 
} 

// Update is called once per frame 
void Update() 
{ 
    EyeTarget(); 

    // Update the timer if and only if we are tracking time AND 
    // the last ray cast hit something. 
    bool updateTimer = (trackTimer && lastHitObject != null); 
    Check(updateTimer); 
} 

void EyeTarget() 
{ 
    RaycastHit hit; 
    bool hitTaggedObject = false; 

    Vector3 fwd = transform.TransformDirection(Vector3.forward); 
    if (Physics.Raycast(transform.position, fwd, out hit)) 
    { 
     foreach(string t in _tags) 
     { 
      if(hit.collider.gameObject.tag == t) 
      { 
       HighLight(hit.collider.gameObject); 
       hitTaggedObject = true; 
      }     
     } 
    } 

    // ** Make sure to clean up highlighting if nothing new was hit 
    if (!hitTaggedObject){ 
     HighLight(null); 
    } 
} 

void ResetTimer() 
{ 
    start_time = Time.time; 
    running_time = 0f; 
} 


void HighLight(GameObject nextHitObject) 
{ 
    // Case1: Last ray and new ray both hit objects 
    if(lastHitObject != null && nextHitObject != null){ 

     //1a: same objects, do nothing 
     if(lastHitObject.tag == nextHitObject.tag)return; 

     { //1b: different objects, swap highlight texture 
      lastHitObject.renderer.material = oldMat; 
      lastHitObject = nextHitObject; 
      oldMat = lastHitObject.renderer.material; 
      lastHitObject.renderer.material = highlight_material; 
      trackTimer = true; 
      return; 
     } 
    } 

    // Case2: Last ray hit nothing, new ray hit object. 
    if(lastHitObject == null && nextHitObject != null){ 
     ResetTimer(); 
     lastHitObject = nextHitObject; 
     oldMat = lastHitObject.renderer.material; 
     lastHitObject.renderer.material = highlight_material; 
     trackTimer = true; 
     return; 
    } 

    // Case3: Last ray hit something, new ray hit nothing 
    if(lastHitObject != null && nextHitObject == null){ 
     lastHitObject.renderer.material = oldMat; 
     lastHitObject = null; 
     trackTimer = false; 
     return; 
    } 
} 
// see if ray has hit object 
void Check(bool updateTimer) 
{ 
    if(updateTimer) 
    { 
     start_time = Time.time - end_time; 
     running_time += Time.deltaTime; 
     if (running_time >= end_time) 
     { 
      trackTimer = false; 
     } 
    } 
} 

trackTimer

running_timeend_time에 도달 할 때 추적 선택한 객체의 상태, 별도의 상태 플래그입니다. 이들 2 개가 동일 해지면 trackTimer이 false로 전환되고 타이머가 다시 시작되기 전에 새 개체를 강조 표시하거나 현재 개체를 다시 강조해야합니다.