ふりかえり
前回は設定画面を実装しました!
プレイヤーの詳細なステータス確認や、BGM・SEの音量調整ができるようになり、ゲームがより快適に遊べるようになりました。
ガチャを実装!
いよいよ、RPGの醍醐味でもある「ガチャ」を実装します!
使うのは、今まで用途がなかったダイヤ。
ガチャで排出されるのは「アーティファクト」という装備のような存在です。
- アーティファクトとは? 攻撃力やHP、会心率など、ステータスを強化してくれる特殊な装備のようなものです。 さらに、強化することで効果量がアップします!
スクリプトの変更
ArtifactManager.cs
アーティファクトの管理・表示・ガチャ機能を統括するクラスです。主な機能は以下の通り:
- ガチャでランダムにアーティファクトを排出
- プレイヤーの所持ダイヤを消費して実行
- 未所持のアーティファクトを優先して排出
- 所持しているアーティファクトはリスト表示
- アーティファクトごとに強化ボタンがあり、ダイヤでレベルアップ可能
- アーティファクトの効果は攻撃力、HP、会心率などに反映
using UnityEngine; using UnityEngine.UI; using TMPro; using System.Collections.Generic; public class ArtifactManager : MonoBehaviour { [Header("UI References")] public GameObject artifactPanel; // アーティファクトパネル public Button artifactButton; // アーティファクトボタン(開閉用) [Header("ガチャUI")] public Button gachaButton; // ガチャボタン public TextMeshProUGUI gachaCostText; // ガチャコスト表示 public TextMeshProUGUI gachaResultText; // ガチャ結果表示 [Header("アーティファクトリストUI")] public GameObject artifactListContent; // アーティファクトリストのコンテンツ public GameObject artifactItemPrefab; // アーティファクトアイテムのプレハブ public ScrollRect artifactScrollRect; // スクロールエリア [Header("参照")] public PlayerManager playerManager; public AudioManager audioManager; [Header("ガチャ設定")] public int gachaCost = 10; // ガチャコスト(ダイヤ) public int upgradeCost = 5; // 強化コスト(ダイヤ) [Header("アーティファクトデータ")] public List<ArtifactData> availableArtifacts = new List<ArtifactData>(); private bool isPanelOpen = false; private List<ArtifactData> ownedArtifacts = new List<ArtifactData>(); // 所持アーティファクトリスト private List<GameObject> artifactItemObjects = new List<GameObject>(); // アーティファクトアイテムのGameObjectリスト void Start() { // アーティファクトボタンのイベントリスナーを設定 if (artifactButton != null) { artifactButton.onClick.AddListener(ToggleArtifactPanel); } // ガチャボタンのイベントリスナーを設定 if (gachaButton != null) { gachaButton.onClick.AddListener(PerformGacha); } // 初期設定:アーティファクトパネルは閉じた状態 if (artifactPanel != null) { artifactPanel.SetActive(false); } isPanelOpen = false; // アーティファクトデータを初期化 InitializeArtifactData(); // UIを更新 UpdateUI(); } // アーティファクトパネルの表示/非表示を切り替え public void ToggleArtifactPanel() { isPanelOpen = !isPanelOpen; if (artifactPanel != null) { artifactPanel.SetActive(isPanelOpen); } if (isPanelOpen) { UpdateArtifactList(); UpdateUI(); } } // アーティファクトデータを初期化 private void InitializeArtifactData() { availableArtifacts.Clear(); // アーティファクトデータを追加 availableArtifacts.Add(new ArtifactData { name = "勇者の剣", description = "攻撃力を大幅に上昇させる伝説の剣", artifactType = ArtifactType.Attack, baseValue = 10, valuePerLevel = 5, }); availableArtifacts.Add(new ArtifactData { name = "守護者の盾", description = "防御力を大幅に上昇させる神聖な盾", artifactType = ArtifactType.Defense, baseValue = 5, }); availableArtifacts.Add(new ArtifactData { name = "生命の宝石", description = "HPを大幅に上昇させる神秘的な宝石", artifactType = ArtifactType.HP, baseValue = 50, valuePerLevel = 25, }); availableArtifacts.Add(new ArtifactData { name = "会心の指輪", description = "会心率を上昇させる魔術的な指輪", artifactType = ArtifactType.CriticalRate, baseValue = 0.05f, valuePerLevel = 0.02f, }); availableArtifacts.Add(new ArtifactData { name = "破壊の斧", description = "会心ダメージ倍率を上昇させる凶悪な斧", artifactType = ArtifactType.CriticalDamage, baseValue = 0.5f, valuePerLevel = 0.2f, }); availableArtifacts.Add(new ArtifactData { name = "a", description = "a", artifactType = ArtifactType.CriticalDamage, baseValue = 0.5f, valuePerLevel = 0.2f, }); } // ガチャを実行 public void PerformGacha() { if (playerManager == null || playerManager.player == null) return; if (playerManager.player.diamond >= gachaCost) { playerManager.player.diamond -= gachaCost; // 指定されたランクの未所持アーティファクトを取得 List<ArtifactData> unownedArtifacts = GetUnownedArtifacts(); List<ArtifactData> rankArtifacts = new List<ArtifactData>(); foreach (var artifact in unownedArtifacts) { if (artifact.rank == randomRank) { rankArtifacts.Add(artifact); } } // 指定されたランクのアーティファクトがない場合は、他のランクから選択 if (rankArtifacts.Count == 0) { rankArtifacts = unownedArtifacts; } if (rankArtifacts.Count > 0) { int randomIndex = Random.Range(0, rankArtifacts.Count); ArtifactData newArtifact = rankArtifacts[randomIndex]; // すでに所持していないか念のためチェック bool alreadyOwned = false; foreach (var owned in ownedArtifacts) { if (owned.name == newArtifact.name) { alreadyOwned = true; break; } } if (!alreadyOwned) { ArtifactData ownedArtifact = new ArtifactData { name = newArtifact.name, description = newArtifact.description, artifactType = newArtifact.artifactType, baseValue = newArtifact.baseValue, valuePerLevel = newArtifact.valuePerLevel, level = 1, rank = newArtifact.rank // ランクもコピー }; ownedArtifacts.Add(ownedArtifact); } // アーティファクト効果を適用 ApplyAllArtifactEffects(); // ガチャSEを再生 if (audioManager != null) { audioManager.PlayPowerUpSE(); } if (gachaResultText != null) { gachaResultText.text = $"獲得: {newArtifact.name} ({newArtifact.rank}ランク) Lv.1"; } UpdateArtifactList(); UpdateUI(); Debug.Log($"アーティファクトガチャ成功: {newArtifact.name} ({newArtifact.rank}ランク) Lv.1"); } else { if (gachaResultText != null) { gachaResultText.text = "全てのアーティファクトを獲得済みです"; } Debug.Log("全てのアーティファクトを獲得済みです"); } } else { if (gachaResultText != null) { gachaResultText.text = "ダイヤが足りません"; } Debug.Log("ダイヤが足りません"); } } // 未所持のアーティファクトを取得 private List<ArtifactData> GetUnownedArtifacts() { List<ArtifactData> unownedArtifacts = new List<ArtifactData>(); foreach (var artifact in availableArtifacts) { bool isOwned = false; foreach (var ownedArtifact in ownedArtifacts) { if (ownedArtifact.name == artifact.name) { isOwned = true; break; } } if (!isOwned) { unownedArtifacts.Add(artifact); } } return unownedArtifacts; } // 指定されたランクのアーティファクトを取得 private ArtifactData GetRandomArtifactByRank(ArtifactRank rank) { List<ArtifactData> rankArtifacts = new List<ArtifactData>(); foreach (var artifact in availableArtifacts) { if (artifact.rank == rank) { rankArtifacts.Add(artifact); } } if (rankArtifacts.Count > 0) { return rankArtifacts[Random.Range(0, rankArtifacts.Count)]; } return availableArtifacts[0]; } // アーティファクトを強化(個別) public void UpgradeArtifact(int artifactIndex) { if (playerManager == null || playerManager.player == null) return; if (artifactIndex < 0 || artifactIndex >= ownedArtifacts.Count) return; if (playerManager.player.diamond >= upgradeCost) { playerManager.player.diamond -= upgradeCost; // 指定されたアーティファクトを強化 ArtifactData artifactToUpgrade = ownedArtifacts[artifactIndex]; artifactToUpgrade.level++; // アーティファクト効果を再適用 ApplyAllArtifactEffects(); // 強化SEを再生 if (audioManager != null) { audioManager.PlayPowerUpSE(); } UpdateArtifactList(); UpdateUI(); Debug.Log($"アーティファクト強化成功: {artifactToUpgrade.name} Lv.{artifactToUpgrade.level}"); } else { Debug.Log("ダイヤが足りません"); } } // 全てのアーティファクト効果を適用 private void ApplyAllArtifactEffects() { if (playerManager == null || playerManager.player == null) return; // アーティファクトステータスをリセット ResetArtifactStats(); // 所持している全てのアーティファクトの効果を適用 foreach (var artifact in ownedArtifacts) { float effectValue = artifact.baseValue + (artifact.valuePerLevel * (artifact.level - 1)); switch (artifact.artifactType) { case ArtifactType.Attack: playerManager.player.artifactPowerUpAttack += Mathf.RoundToInt(effectValue); break; case ArtifactType.Defense: playerManager.player.artifactPowerUpDefense += Mathf.RoundToInt(effectValue); break; case ArtifactType.HP: playerManager.player.artifactPowerUpHP += Mathf.RoundToInt(effectValue); break; case ArtifactType.CriticalRate: playerManager.player.artifactPowerUpCriticalRate += effectValue; break; case ArtifactType.CriticalDamage: playerManager.player.artifactPowerUpCriticalDamage += effectValue; break; } } // 最終ステータスを再計算 UpdateFinalStats(); } // アーティファクトステータスをリセット private void ResetArtifactStats() { if (playerManager == null || playerManager.player == null) return; playerManager.player.artifactPowerUpHP = 0; playerManager.player.artifactPowerUpAttack = 0; playerManager.player.artifactPowerUpDefense = 0; playerManager.player.artifactPowerUpCriticalRate = 0f; playerManager.player.artifactPowerUpCriticalDamage = 0f; } // 最終ステータスを更新 private void UpdateFinalStats() { if (playerManager == null || playerManager.player == null) return; // 最終ステータスは自動的に計算されるため、特に何もしない // PlayerDataのプロパティが自動的に計算する } // アーティファクトリストを更新 private void UpdateArtifactList() { if (artifactListContent == null) return; // 既存のアイテムを削除 foreach (var item in artifactItemObjects) { if (item != null) { Destroy(item); } } artifactItemObjects.Clear(); // 所持アーティファクトがない場合 if (ownedArtifacts.Count == 0) { // 空のメッセージを表示する処理を追加できます return; } // 所持アーティファクトのアイテムを作成 for (int i = 0; i < ownedArtifacts.Count; i++) { CreateArtifactItem(i, ownedArtifacts[i]); } } // アーティファクトアイテムを作成 private void CreateArtifactItem(int index, ArtifactData artifact) { if (artifactItemPrefab == null || artifactListContent == null) return; GameObject itemObject = Instantiate(artifactItemPrefab, artifactListContent.transform); artifactItemObjects.Add(itemObject); // アーティファクト情報を設定 ArtifactItemUI itemUI = itemObject.GetComponent<ArtifactItemUI>(); if (itemUI != null) { itemUI.Initialize(artifact, index, this); } } // UIを更新 private void UpdateUI() { if (playerManager == null || playerManager.player == null) return; // ガチャコスト表示 if (gachaCostText != null) { gachaCostText.text = $"ガチャコスト: {gachaCost}ダイヤ"; } // ボタンの有効/無効設定 if (gachaButton != null) { bool hasUnownedArtifacts = GetUnownedArtifacts().Count > 0; gachaButton.interactable = playerManager.player.diamond >= gachaCost && hasUnownedArtifacts; } } // アーティファクトパネルが開いているかどうかを取得 public bool IsPanelOpen() { return isPanelOpen; } } // アーティファクトデータクラス [System.Serializable] public class ArtifactData { public string name; public string description; public ArtifactType artifactType; public float baseValue; public float valuePerLevel; public int level = 1; } // アーティファクトタイプ public enum ArtifactType { Attack, Defense, HP, CriticalRate, CriticalDamage }
ArtifactItemUI.cs
- アーティファクト1つ1つを表示するUIコンポーネント
- 名前・効果・説明・レベル・強化ボタンを管理
- ダイヤが足りない場合はボタンを無効にする処理もあり
using UnityEngine; using UnityEngine.UI; using TMPro; public class ArtifactItemUI : MonoBehaviour { [Header("UI References")] public TextMeshProUGUI artifactNameText; public TextMeshProUGUI artifactLevelText; public TextMeshProUGUI artifactEffectText; public TextMeshProUGUI artifactDescriptionText; public Button upgradeButton; public TextMeshProUGUI upgradeCostText; private ArtifactData artifactData; private int artifactIndex; private ArtifactManager artifactManager; public void Initialize(ArtifactData artifact, int index, ArtifactManager manager) { artifactData = artifact; artifactIndex = index; artifactManager = manager; UpdateDisplay(); SetupUpgradeButton(); } private void UpdateDisplay() { if (artifactNameText != null) artifactNameText.text = artifactData.name; if (artifactLevelText != null) artifactLevelText.text = $"レベル: {artifactData.level}"; if (artifactEffectText != null) { float effectValue = artifactData.baseValue + (artifactData.valuePerLevel * (artifactData.level - 1)); string effectDescription = GetEffectDescription(artifactData.artifactType, effectValue); artifactEffectText.text = effectDescription; } if (artifactDescriptionText != null) artifactDescriptionText.text = artifactData.description; if (upgradeCostText != null) upgradeCostText.text = $"強化コスト: {artifactManager.upgradeCost}ダイヤ"; } private void SetupUpgradeButton() { if (upgradeButton != null) { upgradeButton.onClick.RemoveAllListeners(); upgradeButton.onClick.AddListener(OnUpgradeButtonClicked); // ボタンの有効/無効設定 bool canUpgrade = artifactManager.playerManager.player.diamond >= artifactManager.upgradeCost; upgradeButton.interactable = canUpgrade; } } private void OnUpgradeButtonClicked() { artifactManager.UpgradeArtifact(artifactIndex); UpdateDisplay(); SetupUpgradeButton(); } private string GetEffectDescription(ArtifactType type, float value) { switch (type) { case ArtifactType.Attack: return $"攻撃力 +{value}"; case ArtifactType.Defense: return $"防御力 +{value}"; case ArtifactType.HP: return $"HP +{value}"; case ArtifactType.CriticalRate: return $"会心率 +{value * 100:F1}%"; case ArtifactType.CriticalDamage: return $"会心倍率 +{value:F1}倍"; default: return ""; } } }
Unityでの設定
ArtifactManagerとArtifactItemUIのUnityでの設定手順を詳細に説明します。
アーティファクトプレハブ(ArtifactItemPrefab)の作成
- Hierarchy で右クリック → UI → Panel を選択
- 作成されたPanelを
ArtifactItemPrefab
にリネーム - Project ウィンドウで
Prefabs
フォルダを作成(なければ) ArtifactItemPrefab
をPrefabs
フォルダにドラッグ&ドロップしてプレハブ化
- 名前・効果・レベル・説明のText(TextMeshPro)を追加
- 強化ボタン(Button)とそのコスト表示も設置
- ArtifactItemUI スクリプトをアタッチし、各UI要素を紐付け


アーティファクトパネル
- アーティファクト用のパネルを作成
- ガチャボタンやガチャ結果表示用のTextも配置
- ScrollView を使用して、所持アーティファクトを縦並びに表示

管理オブジェクト ArtifactManager
- パネルやボタン、PrefabなどすべてをInspectorで接続
- PlayerManager と AudioManager もドラッグ&ドロップで設定

動作確認
アーティファクトボタンを押すと専用パネルが開く
ガチャを回すと新しいアーティファクトが表示される

強化ボタンを押すとダイヤが消費され、アーティファクトの効果がアップ

アーティファクトの内容によって、プレイヤーの攻撃力・HP・会心系ステータスに反映!

まとめ
今回はガチャとアーティファクトの実装を行いました!
強化要素が追加されて、育成のやりがいがアップしました!
ガチャがあることで「ゲームらしさ」もグッと引き立ちますね!
次回予告
次回はアーティファクトにランク(レア度)を設定し、ガチャの排出率調整を行います!
お楽しみに!