我正在尝试为unity制作自己的移动解决方案。下面是代码:
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
变量为假,但我从未将其设置为假。现在,代码中唯一一个从真变为假的地方是在HandleLedgeClimbing()
虚空中。但它不应该被设置为false。
我用大箭头标记了它的位置。
现在,我不是专家,但我很确定if statement
中的所有内容只有在if语句中的条件为真时才运行。为什么只有canMove = false;
运行时,如果语句是假的,这是由Debug.Log(DetectLedge()[0] + " " + DetectLedge()[1] + " " + DetectLedge()[2]);
检查(当我运行场景返回假所有三个变量;注意:if语句中只检查最后一个变量)。
还有,是的,你没看错,">only">
由于某些原因,if语句中没有其他内容被调用!这就是为什么我把Debug.LogWarning("Ledge!");
放在这里,看看是什么导致if语句突然为真。但它从来没有叫过!有点瘆人哈哈-
TL/博士:当我们在场景中呈现的条件下不可能调用一部分代码时,它被调用。最好的部分是:只有一个特定的线路被调用。甚至不是整个街区。我想消除这种情况的发生。
Condition: DetectLedge[2]必须为真才能运行if语句。调试证明它总是错误的(除非我们靠近一个边缘),并且先前的测试强化了这一事实。
UHM我修好了……用最奇怪的方式?我不确定是什么导致了这个问题,但如果有人知道,请分享。有些人可能会觉得有趣。
无论如何,这里是修复:
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]);
}
基本上,我使用struct代替bool[]
。这是有点@derHugo的主意,所以谢谢你!
在另一个函数中,而不是在Debug.Log()
中反复调用它我这样做了:
void HandleLedgeClimbing(bool isEnabled)
{
if(isEnabled)
{
EdgeDetectInformation EDI = DetectLedge();
Debug.Log(EDI.upper + " " + EDI.lower + " " + EDI.canClimb);
if(EDI.canClimb)
...
…固定。