【问题标题】:Why would my switch's case be correct but the output is not?为什么我的开关的情况是正确的,但输出不是?
【发布时间】:2021-12-25 10:48:48
【问题描述】:

我的播放器有一个可以在短时间内突出显示敌人的能力,这一切都很好。我决定让它可以升级,所以能力级别越高,突出显示的东西就越多。

  • 0 级(基础级别)敌人被突出显示。
  • 1 级敌人和物品高亮显示。
  • 2 级敌人、物品和特殊物品会突出显示。
  • 3 级敌人、物品、特殊物品和隐藏区域会突出显示。

为此,我认为在 IEnumerator(协程)中运行的开关将是最有效的方式。一个函数调用协程,根据玩家的能力等级,开关应该处理实际的能力功能(见代码)。

代码如下:

public void CatsEye(){
  if (player.cateye >= 1 && !catsEyeActive) {

    player.cateye -= 1;
    StartCoroutine("CatEye");
      // Debug.Log("Cateye Active");

  }
}


IEnumerator CatEye(){
  catsEyeActive = true;

    switch(player.cateyeLevel){
      case 3:
      if (itemObject != null && enemyObject != null
          && specialObject != null && hiddenObject != null) {
        hidden.isOutlined = true;
        special.isOutlined = true;
        enemyData.isOutlined = true;
        item.isOutlined = true;
      }
      yield return new WaitForSeconds(15f);
      if (itemObject != null && enemyObject != null) {
        hidden.isOutlined = false;
        special.isOutlined = false;
        enemyData.isOutlined = false;
        item.isOutlined = false;
      }
      catsEyeActive = false;
      break;


      case 2:
        if (itemObject != null && enemyObject != null && specialObject != null) {
          special.isOutlined = true;
          enemyData.isOutlined = true;
          item.isOutlined = true;
        }
        yield return new WaitForSeconds(15f);
        if (itemObject != null && enemyObject != null) {
          special.isOutlined = false;
          enemyData.isOutlined = false;
          item.isOutlined = false;
        }
        catsEyeActive = false;
      break;


      case 1:
        if (itemObject != null && enemyObject != null) {
          enemyData.isOutlined = true;
          item.isOutlined = true;
        }
        yield return new WaitForSeconds(15f);
        if (itemObject != null && enemyObject != null) {
          enemyData.isOutlined = false;
          item.isOutlined = false;
        }
        catsEyeActive = false;
      break;


      case 0:
        if (enemyObject != null) {
          enemyData.isOutlined = true;
        }
        yield return new WaitForSeconds(15f);
        if (enemyObject != null) {
          enemyData.isOutlined = false;
        }
        catsEyeActive = false;
      break;
    }
}

问题在于,即使将player.cateyeLevel 设置为 0,该技能的行为就好像它处于 3 级并突出显示所有内容。

player.cateyeLevel 指的是播放器脚本,但那里没有设置会导致问题的变量。事实上,如果有的话,这个能力的 player.cateyeLevel 变量已经设置为 0。也没有 PlayerPrefs 存储 player.cateyeLevel,所以也不是这样。

有人有想法吗?

【问题讨论】:

  • 协程没有问题,虽然我会直接调用该函数为 StartCoroutine(CatEye());。在 switch 语句之前放置一个 Debug.Log(player.cateyeLevel.ToString()) 调用来检查你的逻辑。如果它按预期打印“0”,则必须有一些其他脚本更改 isOutline 属性。然后进行更多的 Debug.Log() 调用或使用调试器。
  • @AndulfGames-AndersBjerin 尝试了您的建议,但出现了同样的问题 :(outline.cs 文件中没有任何内容会导致该问题,因为它所做的只是启用或禁用 GameObject 上的着色器效果,如果isOutlined bool 为 true。与 player.cateyeLevel 变量没有连接。感谢您的建议
  • 奇怪,在这种情况下,我会在 CatEye() 函数的第一行添加一个断点,然后在调试器中手动单步执行以检查发生了什么。添加大量临时 Debug.Log() 调用也是一种替代方法......快乐狩猎。
  • @Twisted 我只是在评论 - 你所做的并没有什么问题。我喜欢你在下面写的方式 - 它看起来更干净。我只是说写if (x && y) {z = true;} 有时更容易阅读为z = (x && y);。当您有switch 案例基于值设置一堆相同的变量时,通常可以将其合并为更简单的 set 语句。编码既是一门艺术,也是一门科学——衡量成功的唯一标准是符合其要求的工作代码。
  • @Twisted 例如,下面代码中的第一个foreach 可能是: if (enemyObject != null) {enemyData.isOutlined = (catsEyeActive && player.cateyeLevel == 0); } }

标签: c# unity3d switch-statement


【解决方案1】:

通过完全重写功能解决了这个问题,任何感兴趣的人的新代码都使用更新作为大纲的主要部分,而协程现在只是为了计时。

    void Update()
    {

      enemyObjects = GameObject.FindGameObjectsWithTag("Enemy");
      foreach(GameObject enemyObject in enemyObjects){
        enemyData = enemyObject.GetComponent<Enemy>();
        if (enemyObject != null) {
          if (catsEyeActive && player.cateyeLevel == 0) {
            enemyData.isOutlined = true;
          }
        }
      }

      items = GameObject.FindGameObjectsWithTag("Item");
      foreach(GameObject itemObject in items){
        item = itemObject.GetComponent<Item>();
        if (item != null) {
          if (catsEyeActive && player.cateyeLevel == 1) {
            enemyData.isOutlined = true;
            item.isOutlined = true;
          }
        }
      }

      specials = GameObject.FindGameObjectsWithTag("Special");
      foreach(GameObject specialObject in specials){
        special = specialObject.GetComponent<Special>();
        if (special != null) {
          if (catsEyeActive && player.cateyeLevel == 2) {
            enemyData.isOutlined = true;
            item.isOutlined = true;
            special.isOutlined = true;
          }
        }
      }

      hiddens = GameObject.FindGameObjectsWithTag("Hidden");
      foreach(GameObject hiddenObject in hiddens){
        hidden = hiddenObject.GetComponent<Hidden>();
        if (hidden != null) {
          if (catsEyeActive && player.cateyeLevel == 3 ) {
            enemyData.isOutlined = true;
            item.isOutlined = true;
            special.isOutlined = true;
            hidden.isOutlined = true;
          }
        }
      }

      
    }


    public void CatsEye(){
      if (player.cateye >= 1 && !catsEyeActive) {    
        player.cateye -= 1;
        StartCoroutine("CatEye");
      }
    }


    IEnumerator CatEye(){
      catsEyeActive = true;
      yield return new WaitForSeconds(15f);
      catsEyeActive = false;
    }

【讨论】:

    猜你喜欢
    • 2014-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-20
    相关资源
    最近更新 更多