首页 > 解决方案 > 即使不应该运行代码行

问题描述

我正在尝试为统一制定自己的移动解决方案。这是代码:

private void Update()
    {
        //Movement
        HandleMouseLooking(canLook); //HandleMouseLooking() should go before HandleMoving()   
        HandleMoving(canMove); //HandleMoving() and HandleCrouching() have the same importance so it doesn't matter
        HandleCrouching(canCrouch);
        HandleLedgeClimbing(canClimb);
        HandleSprinting(canSprint); //HandleSprinting() must be the last Handle of the Movement category
    }


bool[] DetectLedge()
    {
        /*
         * table of truth:
         * indexes:
         *   0       1        2
         * upper | lower | canClimb
         *   0   |   0   |    0     /0
         *   1   |   0   |    0     /1
         *   0   |   1   |    1     /2
         *   1   |   1   |    0     /3
        */

        bool[] ledgeInfo = new bool[3] { false, false, false }; //0
        ledgeInfo[0] = Physics.CheckBox(upperLedgeDetector.position, upperLedgeDetector.lossyScale, upperLedgeDetector.rotation, 128);
        ledgeInfo[1] = Physics.CheckBox(lowerLedgeDetector.position, lowerLedgeDetector.lossyScale, lowerLedgeDetector.rotation, 128);
        ledgeInfo[2] = ledgeInfo[1] && !ledgeInfo[0] ? true : false;

        return ledgeInfo;
    } 

    void HandleLedgeClimbing(bool isEnabled)
    {
        if(isEnabled)
        {
            Debug.Log(DetectLedge()[0] + " " + DetectLedge()[1] + " " + DetectLedge()[2]);
            if(DetectLedge()[2])
            {
                Debug.LogWarning("Ledge!");

                canMove = false; //<--------------------Here it is!

                Vector3 calculatedPos = Vector3.zero;
                RaycastHit hit;
                Physics.Raycast(upperLedgeDetector.position, Vector3.down, out hit, 3f, 128);
                calculatedPos = new Vector3(lowerLedgeDetector.position.x, upperLedgeDetector.position.y - hit.distance, lowerLedgeDetector.position.z);
                if(transform.position != calculatedPos)
                    transform.position = Vector3.Lerp(transform.position, calculatedPos, Time.deltaTime);
            }
        }
    }

这就是我认为导致问题的所有代码。好的,现在来解释什么不起作用。每当我运行场景时,我的播放器都会停止移动。这根本不是预期的,因为它应该停止移动的唯一原因是canMove变量是否为假,但我从未将其设置为假。现在,代码中唯一从 true 变为 false 的地方是在HandleLedgeClimbing()void 中。但它永远不应该被设置为假。

我用一个大箭头标记了它的位置。

现在,我不是专家,但我很确定if statement只有在 if 语句中的条件为真时才会运行。那么为什么 canMove = false;在 if 语句为 false 时运行,由 that 检查Debug.Log(DetectLedge()[0] + " " + DetectLedge()[1] + " " + DetectLedge()[2]); (当我运行场景时,所有三个变量都返回 false;注意:在 if 语句中只检查最后一个变量)

还有,是的,你没看错,“只有

出于某种原因,该 if 语句中没有其他内容被调用!这就是为什么我把它放在Debug.LogWarning("Ledge!");那里,看看是什么导致 if 语句突然变为真的。但它从未被调用过!有点毛骨悚然哈哈-

TL/DR:在我们在场景中呈现的条件下,它不应该被调用时调用了一部分代码。最好的部分是:只调用特定的行。甚至不是整个街区。我想消除这种情况的发生。

条件:DetectLedge[2] 必须为真,if 语句才能运行。调试证明它总是错误的(除非我们靠近壁架)并且之前的测试证实了这一事实。

标签: c#unity3d

解决方案


,我修好了……以最奇怪的方式?我不确定是什么导致了这个问题,但如果有人知道,请分享。有些人会觉得这很有趣。

无论如何,这是修复:

EdgeDetectInformation DetectLedge()
    {
        /*
         * table of truth:
         * indexes:
         *   0       1        2
         * upper | lower | canClimb
         *   0   |   0   |    0     /0
         *   1   |   0   |    0     /1
         *   0   |   1   |    1     /2
         *   1   |   1   |    0     /3
        */

        bool[] ledgeInfo = new bool[3] { false, false, false }; //0
        ledgeInfo[0] = Physics.CheckBox(upperLedgeDetector.position, upperLedgeDetector.lossyScale, upperLedgeDetector.rotation, 128);
        ledgeInfo[1] = Physics.CheckBox(lowerLedgeDetector.position, lowerLedgeDetector.lossyScale, lowerLedgeDetector.rotation, 128);
        ledgeInfo[2] = ledgeInfo[1] && !ledgeInfo[0] ? true : false;

        return new EdgeDetectInformation(ledgeInfo[0], ledgeInfo[1], ledgeInfo[2]);
    } 

基本上,bool[]我使用的是结构而不是 a。这有点像@derHugo 的想法,所以谢谢你!

Debug.Log()在另一个函数中,我没有一遍又一遍地调用它:

 void HandleLedgeClimbing(bool isEnabled)
    {
        if(isEnabled)
        {
            EdgeDetectInformation EDI = DetectLedge();
            Debug.Log(EDI.upper + " " + EDI.lower + " " + EDI.canClimb);
            if(EDI.canClimb)
            ...

而且......解决了它。


推荐阅读