Unity中的Ray转换和计时器问题

时间:2013-10-21 16:24:19

标签: c# unity3d

这是一个follow on from my last question现在我正在寻求扩展它的功能,但我正在寻找一些主要的障碍。

我的目标如下:

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

1 个答案:

答案 0 :(得分: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_time到达end_time的时间。一旦这两个相等,trackTimer翻转为假,您需要突出显示一个新对象,或者在计时器重新开始之前重新点亮当前对象。