最有效的评估类似结果的自变量的方法
本文关键字:结果 自变量 方法 有效 评估 | 更新日期: 2023-09-27 18:02:14
我正在做一个使用Unity和c#的项目,但我不觉得这与Unity有关。我有两只独立的手,它们由一个手类的2个实例来表示。
public class HandController
{//....class}
HandController LeftHand = new HandController();
HandController RightHand = new HandController();
我经常在很多地方做两倍的工作来影响手,因为每只手都需要独立治疗。举个例子,我正在使用一个Leap运动控制器,如果其中一只手没有被检测到,我想要通知用户。我在更新方法中改变了手的颜色。
Color notDetected = Color.red;
Color detected = new Color(189/255.0f, 165/255.0f, 134/255.0f);
if (!LeftHandTracked)
LeftHand.renderer.material.color = notDetected;
if (!RightHandTracked)
RightHand.renderer.material.color = notDetected;
if (LeftHandTracked)
LeftHand.renderer.material.color = detected;
if (RightHandTracked)
RightHand.renderer.material.color = detected;
有更有效的方法吗?我讨厌代码中到处都是重复的if条件。我还跟踪手指,所以每个手指都需要被识别,我得到了一个更糟糕的if条件链
if (TappedFingers[0] && !_keySpamBlock)
LeftHand.SetSide(true, _pointer);
if (TappedFingers[1] && !_keySpamBlock)
LeftHand.SetSide(true, _middle);
if (TappedFingers[2] && !_keySpamBlock)
LeftHand.SetSide(true, _ring);
if (TappedFingers[3] && !_keySpamBlock)
LeftHand.SetSide(true, _pinky);
if (TappedFingers[4] && !_keySpamBlock)
RightHand.SetSide(true, _pointer);
if (TappedFingers[5] && !_keySpamBlock)
RightHand.SetSide(true, _middle);
if (TappedFingers[6] && !_keySpamBlock)
RightHand.SetSide(true, _ring);
if (TappedFingers[7] && !_keySpamBlock)
RightHand.SetSide(true, _pinky);
_pinky和_ middle等。是我在HandController类中传递给SetSide方法的散列值,它允许我访问我在Unity中设置的animationcontroller布尔值。SetSide()基本上只是在用户轻击手指时发送true并在相应的手指上播放动画。
编辑:为了更清楚一点发生了什么
我正在通过继承一个类并建立一个事件侦听器来连接到一个API:
public class AppListener : ErghisListener {
public delegate void onUpdate(Data d);
public event onUpdate Updated;
public override void OnErghisFrame(Data data)
{
Loom.QueueOnMainThread(() => { this.Updated(data); });
}
}
然后我有一个MainController从API接收数据对象:
public class MainController: MonoBehaviour{
private AppListener _appListener;
private int _pointer;
private int _middle;
private int _ring;
private int _pinky;
void Start()
{
this._appListener = new AppListener();
this._appListener.Updated += callback;
this._pointer = Animator.StringToHash("Pointer");
this._middle = Animator.StringToHash("Middle");
this._ring = Animator.StringToHash("Ring");
this._pinky = Animator.StringToHash("Pinky");
}
public void callback(Data d)
{
// Here is where all my annoying if conditionals were.
bool[] TappedFingers = d.tappedF;
}
你的第一个代码片段看起来会更合乎逻辑,如果它是这样的:
class HandController : MonoBehaviour
{
bool m_Tracked;
Color NotDetected { get { return Color.red; } }
Color Detected { get { return new Color(189/255.0f, 165/255.0f, 134/255.0f); } }
public bool Tracked
{
if (m_Tracked == value) return;
m_Tracked = value;
renderer.material.color = value ? Detected : NotDetected;
}
}
// ...
LeftHand.Tracked = LeftHandTracked;
if (TappedFingers.Length != FINGERS*2)
{
Debug.LogError("Unexpected amount of fingers: " + TappedFingers.Length);
return;
}
for(int i = 0; i < FINGERS; i++)
{
LeftHand.SetSide(TappedFingers[i], i);
}
for(int i = FINGERS; i < FINGERS*2; i++)
{
RightHand.SetSide(TappedFingers[i], i-FINGERS);
}
您可以在这里简单地使用else
if (LeftHandTracked)
LeftHand.renderer.material.color = detected;
else
LeftHand.renderer.material.color = notDetected;
我更喜欢内联条件。
LeftHand.renderer.material.color = LeftHandTracked ? detected : notDetected;
对于第二个示例,您可以将所有语句包装在单个if
块中以消除视觉噪声:
if (!_keySpamBlock)
{
if (TappedFingers[0])
LeftHand.SetSide(true, _pointer);
if (TappedFingers[1])
LeftHand.SetSide(true, _middle);
}
Linq的另一个选项(不是更有效,但更漂亮):
var sides = new[] { _pointer, _middle };
if (!_keySpamBlock)
TappedFingers.Zip(sides, (x, y) => { if (x) { LeftHand.SetSide(true, y); });
我想说这很清楚,看起来足够好。我不知道多态性在这里有什么帮助,但是您可以自己研究一下。
第一部分:
LeftHand.renderer.material.color = LeftHandTracked ? detected : notDetected;
RightHand.renderer.material.color = RightHandTracked ? detected : notDetected;
第二部分:
if(!_keySpamBlock)
{
int index=Array.FindLastIndex(TappedFingers.Take(8).ToArray(), i => i);
switch (index)
{
case 0: {LeftHand.SetSide(true, _pointer); break;}
case 1: {LeftHand.SetSide(true, _middle); break;}
//.........
case 7: {RightHand.SetSide(true, _pinky); break;}
}
}