_ohuton
@_ohuton

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Unityでコマンド式ターン制-2DJRPG-を制作する

Q&A

Closed

解決したいこと

Unityの2Dプロジェクトでヒット作のRPGのようなフリーゲームを作っています。
ターンのUIを実装途中にバグが発生しました。
ターンUIの不具合を解決したいです。
解決方法を教えて下さい。

発生している問題

プレイヤーターンの時だけ2度表示非表示の切り替えが起きてしまいます。

該当するソースコード

// --やっていること--
// UIの切り替え
// PlayerのHP
// NPCのHP
// NPC攻撃の制御
// Player攻撃の制御
// Battle終了後シーン遷移

public class CommandBattleController : MonoBehaviour
{
    public GameObject turnPanelUI;      // ターンを表示する用Panel
    public Text turnText;               // ターンを表示する用Text
    public GameObject playerCommandUI;  // PlayerStatusPanel
    public GameObject[] playerUI;       // 0:SelectUI,1:AttackUI,2:ItemUI
    public Text[] commandOptions;  // Command種類
    public Text[] attackOptions;   // 攻撃種類
    public Text[] itemOptions;     // アイテム種類
    public Text playerStatusText;  // Status表示
    public Text npcStatusText;     // Status表示
    public Text endText;           // 勝敗判定Text

    private int selectedCommandIndex = -1;
    private int selectedAttackIndex = -1;
    private int selectedItemIndex = -1;
    [SerializeField] private bool isPlayerTurn = true;
    [SerializeField] private bool isBattleOver = false;
    [SerializeField] private bool isBattleTurnPlayerUI = true;
    [SerializeField] private bool isBattleTurnNPCUI = false;

    private int playerHP = 100;        // PlayerStatus
    private int playerStamina = 100;
    private int playerAttack = 20;
    private int playerDefense = 10;

    private int npcHP = 200;           // NPCStatus
    private int npcAttack = 15;
    private int npcDefense = 8;

    private int npcTurnCount = 3;
    private int playerTurnCount = 3;

    private void Start()
    {
        playerStatusText.text = "HP: " + playerHP + "\n Stamina: " + playerStamina+ "\n AT:" + playerAttack+ "\n DF:" + playerDefense;
        npcStatusText.text = "HP: " + npcHP + "\n AT:" + npcAttack + "\n DF:" + npcDefense;
        endText.text = "";

        // コマンドUI初期化
        for (int i = 0; i < commandOptions.Length; i++)
        {
            commandOptions[i].color = Color.white;
        }
        // 攻撃UI初期化
        for (int i = 0; i < attackOptions.Length; i++)
        {
            attackOptions[i].color = Color.white;
        }
        // アイテムUI初期化
        for (int i = 0; i < itemOptions.Length; i++)
        {
            itemOptions[i].color = Color.white;
        }
    }

    private void Update()
    {
        if (isBattleOver)
        {
            return;
        }

        StartCoroutine(Battler());
    }

    IEnumerator Battler()
    {
        if (isPlayerTurn)
        {
            if (isBattleTurnPlayerUI)
            {
                turnText.text = "プレイヤーターン";
                turnPanelUI.SetActive(true);
                yield return new WaitForSeconds(2f);
                turnPanelUI.SetActive(false);
                isBattleTurnPlayerUI = false;
            }
            HandlePlayerTurn();
            isBattleTurnNPCUI = false;
        }
        else
        {
            if (!isBattleTurnNPCUI)
            {
                turnText.text = "NPCターン";
                turnPanelUI.SetActive(true);
                yield return new WaitForSeconds(2f);
                turnPanelUI.SetActive(false);
                isBattleTurnNPCUI = true;
            }
            HandleNPCTurn();
            isBattleTurnPlayerUI = true;
        }
    }

    private void HandlePlayerTurn()
    {
        OpenOptions();

        if (Input.GetKeyDown(KeyCode.Return))
        {
            if (selectedCommandIndex != -1)
            {
                if (selectedCommandIndex == 0)
                {
                    OpenAttackOptions();

                    if (selectedAttackIndex != -1)
                    {
                        if (selectedAttackIndex == 0)
                        {
                            AttackNPC(10);
                        }
                        else if (selectedAttackIndex == 1)
                        {
                            AttackNPC(12);
                        }
                        else if (selectedAttackIndex == 2)
                        {
                            AttackNPC(15);
                        }
                        else if (selectedAttackIndex == 3)
                        {
                            AttackNPC(19);
                        }
                    }
                }
                else if (selectedCommandIndex == 1)
                {
                    Flee();
                }
                else if (selectedCommandIndex == 2)
                {
                    Defend();
                }
                else if (selectedCommandIndex == 3)
                {
                    OpenItemOptions();

                    if (selectedItemIndex != -1)
                    {
                        if (selectedItemIndex == 0)
                        {
                            UseItem(0);
                        }
                        else if (selectedItemIndex == 1)
                        {
                            UseItem(1);
                        }
                        else if (selectedItemIndex == 2)
                        {
                            UseItem(2);
                        }
                        else if (selectedItemIndex == 3)
                        {
                            UseItem(3);
                        }
                    }
                }
            }
        }

        else if (Input.GetKeyDown(KeyCode.UpArrow))
        {
            if (playerUI[0].activeInHierarchy)
            {
                UpdateSelectedCommandIndex(-1);
            }
            if (playerUI[1].activeInHierarchy)
            {
                UpdateSelectedAttackIndex(-1);
            }
            if (playerUI[2].activeInHierarchy)
            {
                UpdateSelectedItemIndex(-1);
            }
        }
        else if (Input.GetKeyDown(KeyCode.DownArrow))
        {
            if (playerUI[0].activeInHierarchy)
            {
                UpdateSelectedCommandIndex(1);
            }
            if (playerUI[1].activeInHierarchy)
            {
                UpdateSelectedAttackIndex(1);
            }
            if (playerUI[2].activeInHierarchy)
            {
                UpdateSelectedItemIndex(1);
            }
        }
        else if (Input.GetKeyDown(KeyCode.C))
        {
            if (playerUI[1].activeInHierarchy)
            {
                OpenCommandOptions();
            }
            if (playerUI[2].activeInHierarchy)
            {
                OpenCommandOptions();
            }
        }
    }

    private void HandleNPCTurn()
    {
        // NPCの行動ロジック
        AttackPlayer();
    }

    private void UpdateSelectedCommandIndex(int increment)
    {
        if (selectedCommandIndex != -1)
        {
            commandOptions[selectedCommandIndex].color = Color.white;
        }

        selectedCommandIndex += increment;
        selectedCommandIndex = Mathf.Clamp(selectedCommandIndex, 0, commandOptions.Length - 1);

        commandOptions[selectedCommandIndex].color = Color.yellow;
    }

    private void UpdateSelectedAttackIndex(int increment)
    {
        if (selectedAttackIndex != -1)
        {
            attackOptions[selectedAttackIndex].color = Color.white;
        }

        selectedAttackIndex += increment;
        selectedAttackIndex = Mathf.Clamp(selectedAttackIndex, 0, attackOptions.Length - 1);

        attackOptions[selectedAttackIndex].color = Color.yellow;
    }

    private void UpdateSelectedItemIndex(int increment)
    {
        if (selectedItemIndex != -1)
        {
            itemOptions[selectedItemIndex].color = Color.white;
        }

        selectedItemIndex += increment;
        selectedItemIndex = Mathf.Clamp(selectedItemIndex, 0, itemOptions.Length - 1);

        itemOptions[selectedItemIndex].color = Color.yellow;
    }

    private void OpenCommandOptions()
    {
        // コマンドUIを切り替え
        playerUI[0].gameObject.SetActive(true);
        playerUI[1].gameObject.SetActive(false);
        playerUI[2].gameObject.SetActive(false);
    }

    private void OpenAttackOptions()
    {
        // コマンドUIを切り替え
        playerUI[0].gameObject.SetActive(false);
        playerUI[1].gameObject.SetActive(true);
        playerUI[2].gameObject.SetActive(false);
    }

    private void OpenItemOptions()
    {
        // コマンドUIを切り替え
        playerUI[0].gameObject.SetActive(false);
        playerUI[1].gameObject.SetActive(false);
        playerUI[2].gameObject.SetActive(true);
    }

    private void CloseOptions()
    {
        // コマンドUIを切り替え
        playerCommandUI.gameObject.SetActive(false);
    }

    private void OpenOptions()
    {
        // コマンドUIを切り替え
        playerCommandUI.gameObject.SetActive(true);
    }

    private void AttackNPC(int attackPower)
    {
        if (playerTurnCount <= 0)
        {
            isPlayerTurn = false;
            npcTurnCount = 3;
            CloseOptions();
            return;
        }

        int damage = attackPower - npcDefense;
        npcHP -= damage;

        npcStatusText.text = "HP: " + Mathf.Max(npcHP, 0) + "\n AT:" + npcAttack + "\n DF:" + npcDefense;

        playerTurnCount--;

        if (npcHP <= 0)
        {
            EndBattle();
            return;
        }
    }

    private void AttackPlayer()
    {
        // NPCのターン
        if(npcHP <= 0 || playerHP <= 0)
        {
            EndBattle();
            return;
        }

        if (npcTurnCount <= 0)
        {
            isPlayerTurn = true;
            playerTurnCount = 3;
            OpenOptions();
            return;
        }

        if (npcHP > 0 && npcHP <= 20 && Random.Range(0, 100) == 50)
        {
            // NPCの毒攻撃
            Debug.Log("NPC uses poison attack!");
            int poisonDamage = 10;
            playerHP -= poisonDamage;
            playerStatusText.text = "HP: " + Mathf.Max(playerHP, 0) + "\n Stamina: " + playerStamina + "\n AT:" + playerAttack + "\n DF:" + playerDefense;

            npcTurnCount--;

            if (playerHP <= 0)
            {
                EndBattle();
                return;
            }
        }
        else if(Random.Range(0, 100) == 50)
        {
            // NPCの通常攻撃
            Debug.Log("NPC attacks!");
            int damage = (npcAttack - playerDefense) / 4;
            playerHP -= damage;
            playerStatusText.text = "HP: " + Mathf.Max(playerHP, 0) + "\n Stamina: " + playerStamina + "\n AT:" + playerAttack + "\n DF:" + playerDefense;

            npcTurnCount--;

            if (playerHP <= 0)
            {
                EndBattle();
                return;
            }
        }
    }

    private void Flee()
    {
        // 逃走ロジック
        SceneManager.LoadScene("MainBattle");
    }

    private void Defend()
    {
        // 防御ロジック
        int damage = Mathf.Max(npcAttack - playerDefense / 2, 0);
        playerHP -= damage;

        playerStatusText.text = "HP: " + Mathf.Max(playerHP, 0) + "\n Stamina: " + playerStamina + "\n AT:" + playerAttack + "\n DF:" + playerDefense;

        if (playerHP <= 0)
        {
            EndBattle();
        }
    }

    private void UseItem(int itemIndex)
    {
        // アイテムの効果ロジック
        if (itemIndex == 0) // 回復薬
        {
            int healAmount = 20;
            playerHP = Mathf.Min(playerHP + healAmount, 100);
            playerStatusText.text = "HP: " + Mathf.Min(playerHP, 0) + "\n Stamina: " + playerStamina + "\n AT:" + playerAttack + "\n DF:" + playerDefense;
        }
        else if (itemIndex == 1) // 魔力の薬
        {
            int restoreAmount = 30;
            playerStamina = Mathf.Min(playerStamina + restoreAmount, 100);
            playerStatusText.text = "HP: " + Mathf.Min(playerHP, 0) + "\n Stamina: " + playerStamina + "\n AT:" + playerAttack + "\n DF:" + playerDefense;
        }
        else if (itemIndex == 2) // 炎の爪
        {
            // プレイヤーの攻撃力を一時的に増加させるロジック
            int addAttack = 10;
            playerAttack += addAttack;
        }
        else if (itemIndex == 3) // 防御の指輪
        {
            // プレイヤーの防御力を一時的に増加させるロジック
            int addDefence = 5;
            playerDefense += addDefence;
        }

        // アイテム使用後、ターンを終了する
        isPlayerTurn = false;
    }

    private void EndBattle()
    {
        isBattleOver = true;

        if (playerHP <= 0)
        {
            Debug.Log("Player loses!");
            endText.text = "Player loses!";
        }
        else if (npcHP <= 0)
        {
            Debug.Log("Player wins!");
            endText.text = "Player wins!";
        }
        else
        {
            Debug.Log("Battle ends in a draw!");
            endText.text = "Battle ends in a draw!";
        }

        Invoke("MainBattleScene", 3f);
    }

    private void MainBattleScene()
    {
        SceneManager.LoadScene("MainBattle");
    }
}

自分で試したこと

自分なりにDebug.Log($"{}");で何回実行されているのか試しました。

0

No Answers yet.

Your answer might help someone💌