Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何最大限度地减少else if语句的使用?_C#_Unity3d - Fatal编程技术网

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; 
}