Unityでコマンド式ターン制-2DJRPG-を制作する
解決したいこと
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