C# 如何最大限度地减少else if语句的使用?
如何设置方向的值而不必每隔一个选项抛出一次C# 如何最大限度地减少else if语句的使用?,c#,unity3d,C#,Unity3d,如何设置方向的值而不必每隔一个选项抛出一次 if (Input.GetKey(right_button)) { direction = 1; } else if(Input.GetKey(left_button)) { direction = -1; } else { direction = 0; } if (direction!=0) { rb.velocity = new Vector2(player_speed*direction, rb.velocity.y); }
if (Input.GetKey(right_button)) { direction = 1; }
else if(Input.GetKey(left_button)) { direction = -1; }
else { direction = 0; }
if (direction!=0) { rb.velocity = new Vector2(player_speed*direction, rb.velocity.y); }
我需要将玩家的输入转换为移动。我不能使用轴,因为我不能像使用此方法那样轻松地修改它们
如何优化这段代码?在没有if/else的情况下编写上述代码的另一种方法是:
direction = Input.GetKey(right_button)
? 1
: Input.GetKey(left_button)
? -1
: 0;
// set the value of 0 to direction from the start and change it if it is needed
direction = 0;
if (Input.GetKey(right_button))
{
direction = 1;
}
if(Input.GetKey(left_button))
{
direction = -1;
}
我不知道这是否更具可读性。在这种情况下,我认为这是一种关于如何编写这段代码的偏好,而不是更具可读性。换句话说,我不认为if/else语句不可读——作为一个轻微的修改,我建议您将正文放在另一行,而不是同一行——但这也是个人偏好:)
关于第二个问题,代码中没有任何性能问题
另一种方法是:
direction = Input.GetKey(right_button)
? 1
: Input.GetKey(left_button)
? -1
: 0;
// set the value of 0 to direction from the start and change it if it is needed
direction = 0;
if (Input.GetKey(right_button))
{
direction = 1;
}
if(Input.GetKey(left_button))
{
direction = -1;
}
本质上,我们从一开始就将
direction
的值设置为0,并且仅当需要时才重新设置该值(无论是Input.GetKey(right_按钮)
还是Input.GetKey(left_按钮)
返回true)。您可以定义一个集合来确定哪些输入提供了哪个方向:
var directionMap = new List<(bool isInputPressed, int directionalValue)>
{
(Input.GetKey(right_button), 1),
(Input.GetKey(left_button), -1)
};
如果同时按下两个按钮,在此处使用.Where()
可能会产生意外结果。如果不希望发生这种情况,您可以将上述内容改为使用.SingleOrDefault()
:
var direction = directionMap.SingleOrDefault(x => x.isInputPressed).directionalValue;
请注意,如果同时按下多个按钮,则会产生异常。您可以在try/catch块中处理此异常。或者,在调用
.SingleOrDefault()
之前,您可以验证是否只按下了一个按钮,然后继续相应的操作。您对优化的担忧已经成熟。@Christos的答案在性能方面是最好的(复制如下)
这是唯一的优化,因为它从代码路径中删除了一个分支
我想说的是,为了风格和可读性,远离terinary操作符(使用bool?1:0语法)。它们通常会导致在返回具有清晰条件的清晰可读值之后,代码变得更加混乱
在这些不同的实现中要考虑的是,如果你想让你的角色只移动四个方向(假设你可以上下加)或者支持对角线运动。删除代码中的“else”语句将使其成为对角移动。如果您保留“else-If”,那么您将只能向基本方向移动。
如果你只想左右移动,那就要考虑当两个都被按下时会发生什么。玩家不去哪里?玩家是否向上一次按下的方向移动?如果上下相加,如何跟踪是否按下了3个按钮?只有在将左侧值添加到列表时才会计算它们,因此它们永远不会更改。也许您打算存储委托,例如潜在的
Func
。如果每次计算方向时都初始化列表,那么这种方法就可以正常工作。在不知道该代码如何执行的更多上下文的情况下,说列表中的值需要更改只是一个假设。我们知道列表中的左侧值需要更改,这是一个针对用户输入的轮询,可以在任何更新()
中更改!(您将注意到OP:)上的Unity标记,这意味着必须在每一帧重新生成和解析列表。在这种情况下,正如您所说,每次执行Update()都会创建一个具有新值的列表的新实例。这意味着列表的每个实例中的值不需要更改,并且可以在列表初始化时安全地进行评估。对不起,如果我说得太多,我只是不明白问题所在。技术术语是“过度工程”。如果每一帧都被重新创建(并且每一帧都被破坏,因此还有大量额外的GC工作),那么主要的问题就是优化。您正在创建一个固定元素列表,然后对其进行迭代以测试其值,为什么不直接测试其值并保存所有列表处理?就个人而言,我将使用第三种方法,但使用direction+=1
和direction-=1
,这样,如果两个键都按下,则结果方向仍然为零。
// set the value of 0 to direction from the start and change it if it is needed
direction = 0;
if (Input.GetKey(right_button))
{
direction = 1;
}
if(Input.GetKey(left_button))
{
direction = -1;
}