Unity 中的光线投射和计时器存在问题

本文关键字:计时器 存在 问题 光线投射 Unity | 更新日期: 2023-09-27 18:36:12

这是我

最后一个问题的后续,现在我希望扩展它的功能,但我遇到了一些主要障碍。

我的目标如下:

我有一个相机,它投射光线以击中具有特定标签的物体。当光线在设定的时间段内击中标签时,我正在寻找要发生的事情,现在我正在寻找的只是调试消息或简单的东西。当光线没有击中任何带有标签的物体时,我希望我的计时器不会更新。如果用户将视线从对象上移开并返回,我希望计时器从 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");
}

Unity 中的光线投射和计时器存在问题

我试图尽可能地不理会你的版本。 当光标移离标记对象时,此版本将停止计时器,当另一个标记对象位于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_time到达end_time的时间。 一旦这 2 个相等,trackTimer就会翻转为 false,您需要突出显示一个新对象或重新突出显示当前对象,然后计时器才会再次启动。