针对'敌人(克隆)'的Transform.position分配尝试无效。输入位置为{NaN,NaN,NaN}

时间:2014-08-24 16:47:16

标签: unity3d

从我的研究中我可以看到我遇到了一个向量问题(看起来我除以0但是我的脚本中没有划分)。

我检查了每个脚本的位置,并尝试在trace语句之间捕获它。无法做到。看起来它在某些更新或固定更新中,但我不知道在哪里。

当敌人被杀时,这个错误就会出现。

我觉得它与它的位置有关。点击这个错误什么都不做,但有时它会突出显示传递给它的错误转换的游戏对象。

你的代码中是否有某个地方可以获得我可以找到的NAN矢量?

当敌人死亡时,我会得到很多这些,一旦死亡(被摧毁),这个问题就会消失。它将播放一些动画,每帧触发错误,然后当敌人死亡时,错误停止。

单击该错误只会突出显示游戏对象,但不会打开发生这种情况的脚本。

每当敌人被杀时,它可能会出现5次......

这是敌人死亡的剧本(它没有设置位置所以问题可能不在这里)

public void killSelf()
    {
        _animator.SetBool("isAttacking",false);
        _animator.SetBool("isDead",true);
        StartCoroutine(processKillSelf());
    }

    IEnumerator processKillSelf()
    {
        yield return new WaitForSeconds(1f);//its a 30 frame animation
        Destroy(gameObject);
    }

有没有办法让FORCE unity3D打破这个错误并让我查看堆栈跟踪?

没有堆栈跟踪是我无法找到这种情况的唯一原因。

3 个答案:

答案 0 :(得分:0)

在没有看到更多代码的情况下,我无法肯定地说,但听起来内部没有更新引用(即某些东西指向已经被破坏的向量。)我会捅你的动画代码到看看是否有任何结果。

它的值Object.Destroy有一个可选的第二个参数,它是一个延迟计时器。 (http://docs.unity3d.com/ScriptReference/Object.Destroy.html)所以你可以像这样重写你的代码:

public void killSelf() 
{
    _animator.SetBool("isAttacking",false);
    _animator.SetBool("isDead",true);
    Destroy(gameObject, 1f);
}

并完全省略processKillSelf()协程。

答案 1 :(得分:0)

我发现了问题:

这不是角色,而是角色上的HP栏。 HP栏的局部比例在死亡时将其中一个值设置为0。确保该值至少为0.1f修复此问题:

float x = _hpBarMaxScale * health/healthmax>0?(_hpBarMaxScale * health/healthmax):0.1f;
hpBar.transform.localScale = new Vector3(x,hpBar.transform.localScale.y,hpBar.transform.localScale.z); 

答案 2 :(得分:0)

我知道这很晚了,但是我也遇到了类似的问题,也许将来会对某人有所帮助。

您已经注意到,如果在某个地方尝试用0来指定值,这种情况总是会发生。

就我而言,我只是找不到容易和不幸的类似

的地方0
try
{
    transform.position = possiblyBrokenVector3;
}
catch
{
}

也没有抓住它,因此自Update中调用它以来,我无法设置适当的制动点。


您通常可以做的实际上是检查NaN的值。我直接将其作为检查Vector3的扩展方法:

public static Vector3Extensions
{
    public static bool ContainsNaN(this Vector3 vector)
    {
        return float.IsNaN(vector.x) || float.IsNaN(vector.y) || float.IsNaN(vector.z);
    }
}

现在我可以在分配喜欢之前随时检查

if(possiblyBrokenVector3.ContainsNaN)
{
    Debug.LogWarning("Ignoring a NaN vector here!", this);
}
else
{
    transform.position = possiblyBrokenVector3;
}

在“调试”行上设置制动点,最后逐步浏览调用历史记录,以查看实际产生中断输入值的方式。