2013-10-21 46 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

有幾件事情是錯誤的,但您遇到的主要問題是除非您的raycast命中帶有正確標記的對象,否則不會調用「Highlight」。如果您首先設置了'hit_object = null',那麼'else if'中的'Highlight'也會出錯,然後嘗試設置其材質。 – Jerdak

回答

1

我試着儘可能地離開你的版本。當光標離開加標籤的對象時,此版本將停止計時器,並且將從0開始,當另一個加標籤的對象位於raycast下時。

我的代碼有點冗長,但它更容易看到發生了什麼。

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_time單獨end_time。一旦這兩者相等,trackTimer翻轉爲false,並且您需要在定時器重新開始之前突出顯示一個新對象或重新亮起當前對象。