装備機能の実装⑤二つ名防具編! Unityで1日1ステップ!ノンフィールドRPG開発日記

1日1歩開発日記

ふりかえり

前回は防具を作成しました。

メインオプションとランダムなサブオプション、また強化レベルに応じたサブオプションの強化とやりごたえのあるシステムになりました!

二つ名システム

今回は前回実装した防具に更なるやり込み要素を追加したいと思います。

それは二つ名システムです。

1. 概要

防具の二つ名システムは、獲得時に低確率で発動する特殊強化です。二つ名が付くと、メインオプションと一部のサブオプションが強化されます。

2. 発動条件

  • 発動確率: 5%
  • 発動タイミング: 防具生成時
        // 二つ名を付与するかチェック(5%の確率)
        if (Random.Range(0f, 1f) < epithetProbability)
        {
            ApplyEpithet(armor);
        }

3. 強化内容

3.1 メインオプション

  • 強化倍率: 1.5倍(二つ名が付いている場合、常に適用)

3.2 サブオプション

  • 強化倍率: 2.0倍
  • 強化されるサブオプション数は確率で決定:
  • 5%: 4個
  • 15%: 3個
  • 25%: 2個
  • 35%: 1個
  • 20%: 0個(メインオプションのみ強化)
        // 強化されるサブオプション数を決定
        // 5%: 4個, 15%: 3個, 25%: 2個, 35%: 1個, 20%: 0個
        float random = Random.Range(0f, 1f);
        int enhancedCount = 0;
        if (random < 0.05f)
        {
            enhancedCount = 4;
        }
        else if (random < 0.20f)
        {
            enhancedCount = 3;
        }
        else if (random < 0.45f)
        {
            enhancedCount = 2;
        }
        else if (random < 0.80f)
        {
            enhancedCount = 1;
        }
        else
        {
            enhancedCount = 0;
        }

        // 実際のサブオプション数を超えないように調整
        enhancedCount = Mathf.Min(enhancedCount, armor.subOptions.Count);

        // 強化されるサブオプションのインデックスをランダムに選択
        if (enhancedCount > 0 && armor.subOptions.Count > 0)
        {
            List<int> availableIndices = new List<int>();
            for (int i = 0; i < armor.subOptions.Count; i++)
            {
                availableIndices.Add(i);
            }

            armor.enhancedSubOptionIndices.Clear();
            for (int i = 0; i < enhancedCount; i++)
            {
                int randomIndex = Random.Range(0, availableIndices.Count);
                int selectedIndex = availableIndices[randomIndex];
                armor.enhancedSubOptionIndices.Add(selectedIndex);
                availableIndices.RemoveAt(randomIndex);
            }
        }

4. 二つ名の表示

4.1 語句の生成

強化されたサブオプション数に応じて、異なる語句リストから選択されます:

  • epithetWords1: 1個強化時の語句リスト
  • epithetWords2: 2個強化時の語句リスト
  • epithetWords3: 3個強化時の語句リスト
  • epithetWords4: 4個強化時の語句リスト

最後に「加護を受けた」が付加されます。

例:サブオプションが2個強化されたふたつ名防具の場合、「epithetWords2・epithetWords1・加護を受けた防具」となります。→「純白の大地の加護を受けた防具」

        // 二つ名の語句を生成
        armor.epithetWords.Clear();

        // 0個の場合は「加護を受けた」のみ
        if (enhancedCount == 0)
        {
            armor.epithetWords.Add("加護を受けた");
        }
        else
        {
            // 各位置に対応する語句リストから選択(逆順)
            // 1つ目の位置:epithetWords4から選択
            // 2つ目の位置:epithetWords3から選択
            // 3つ目の位置:epithetWords2から選択
            // 4つ目の位置:epithetWords1から選択
            for (int i = 0; i < enhancedCount; i++)
            {
                List<string> wordList = null;
                switch (enhancedCount - i) // 逆順で位置を計算
                {
                    case 1:
                        wordList = epithetWords1;
                        break;
                    case 2:
                        wordList = epithetWords2;
                        break;
                    case 3:
                        wordList = epithetWords3;
                        break;
                    case 4:
                        wordList = epithetWords4;
                        break;
                }

                if (wordList != null && wordList.Count > 0)
                {
                    string selectedWord = wordList[Random.Range(0, wordList.Count)];
                    armor.epithetWords.Add(selectedWord);
                }
            }

            // 最後に「加護を受けた」を追加
            armor.epithetWords.Add("加護を受けた");
        }

4.2 表示色

  • 語句の色は強化数に応じて変化:
  • 4個強化: 金色(#FFD700)
  • 3個強化: 紫色(#FF00FF)
  • 2個強化: 赤色(#FF0000)
  • 1個強化: 緑色(#00FF00)
  • 「加護を受けた」: オレンジ色(#FF8C00)
        // 二つ名が付いている場合、名前の前に二つ名を追加(色付き)
        if (hasEpithet && epithetWords != null)
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            if (epithetWords.Count > 0)
            {
                // epithetWordsの構造:
                // enhancedCount=4の場合: [0]=epithetWords4, [1]=epithetWords3, [2]=epithetWords2, [3]=epithetWords1, [4]="加護を受けた"
                // enhancedCount=2の場合: [0]=epithetWords2, [1]=epithetWords1, [2]="加護を受けた"
                // 最後の要素は常に「加護を受けた」
                int totalWords = epithetWords.Count;
                int enhancedCount = totalWords - 1; // 「加護を受けた」を除いた語句数

                for (int i = 0; i < totalWords; i++)
                {
                    string word = epithetWords[i];
                    string colorTag = "";

                    // 最後の語句が「加護を受けた」かどうかを判定
                    bool isLastWord = (i == totalWords - 1);
                    bool isBlessingWord = (word == "加護を受けた");

                    if (isLastWord && isBlessingWord)
                    {
                        // 「加護を受けた」はオレンジ色
                        colorTag = "<color=#FF8C00>";
                    }
                    else
                    {
                        // 各語句がどのepithetWordsリストから来たかを判定
                        // i=0の位置は、enhancedCount-i=enhancedCountに対応
                        // つまり、i=0の位置は、epithetWords(enhancedCount)から来ている
                        // 実際には、i=0の位置は、epithetWords4, epithetWords3, epithetWords2, epithetWords1のどれか
                        // 位置iは、enhancedCount-i番目のepithetWordsリストから来ている
                        int epithetWordsIndex = enhancedCount - i;

                        if (epithetWordsIndex == 4)
                        {
                            colorTag = "<color=#FFD700>"; // Gold (epithetWords4)
                        }
                        else if (epithetWordsIndex == 3)
                        {
                            colorTag = "<color=#FF00FF>"; // Magenta/Purple (epithetWords3)
                        }
                        else if (epithetWordsIndex == 2)
                        {
                            colorTag = "<color=#FF0000>"; // Red (epithetWords2)
                        }
                        else if (epithetWordsIndex == 1)
                        {
                            colorTag = "<color=#00FF00>"; // Green (epithetWords1)
                        }
                    }

                    if (!string.IsNullOrEmpty(colorTag))
                    {
                        sb.Append(colorTag).Append(word).Append("</color>");
                    }
                    else
                    {
                        sb.Append(word);
                    }
                }
            }
            else
            {
                // epithetWordsが空の場合は「加護を受けた」のみ(オレンジ色)
                sb.Append("<color=#FF8C00>加護を受けた</color>");
            }
            // 防具名とレベルを白色で囲む
            sb.Append("<color=white>").Append(baseName).Append(levelText).Append("</color>");
            return sb.ToString();
        }

5. フレーム表示

5.1 フレームアイコン

  • 二つ名が付いている場合、専用フレームアイコンを使用
  • フレームは強化されたサブオプション数に対応(1〜4個用)
        // 二つ名用フレームを設定(サブオプション数に対応)
        if (enhancedCount > 0 && enhancedCount <= epithetFrameIcons.Length)
        {
            armor.epithetFrameIconIndex = enhancedCount - 1; // インデックスは0始まり
        }
        else if (enhancedCount == 0)
        {
            // 0個の場合は1個用のフレームを使用
            armor.epithetFrameIconIndex = 0;
        }

5.2 フレームの色

  • 強化されたサブオプション数に応じて色が変化:
  • 0個: 白色
  • 1個: 緑色
  • 2個: 赤色
  • 3個: 紫色
  • 4個: 金色
        // フレームの色を設定(強化サブオプション数に応じて)
        switch (enhancedCount)
        {
            case 0:
                armor.epithetFrameColor = Color.white; // デフォルト(白)
                break;
            case 1:
                armor.epithetFrameColor = Color.green; // 緑色
                break;
            case 2:
                armor.epithetFrameColor = Color.red; // 赤色
                break;
            case 3:
                armor.epithetFrameColor = Color.magenta; // 紫色
                break;
            case 4:
                armor.epithetFrameColor = new Color(1f, 0.84f, 0f, 1f); // 金色
                break;
            default:
                armor.epithetFrameColor = Color.white;
                break;
        }

6. 効果の適用

装備時に、二つ名による強化が適用されます:

        // 二つ名が付いている場合、倍率を適用
        float effectiveValue = option.value;
        if (armor != null && armor.hasEpithet)
        {
            // メインオプションの場合(subOptionIndex == -1)
            if (subOptionIndex == -1)
            {
                // メインオプションは1.5倍
                effectiveValue = option.value * 1.5f;
            }
            // サブオプションの場合
            else if (armor.enhancedSubOptionIndices != null && armor.enhancedSubOptionIndices.Contains(subOptionIndex))
            {
                // 強化されたサブオプションは2倍
                effectiveValue = option.value * 2.0f;
            }
        }

7. UI表示

  • 強化されたオプションはオレンジ色で表示されます
        // 強化されている場合はオレンジ色で表示
        if (isEnhanced)
        {
            // UnityのRich Textでオレンジ色(#FF8C00に近い色)
            baseText = $"<color=#FF8C00>{baseText}</color>";
        }

8. まとめ

  • 発動確率: 5%
  • メインオプション: 常に1.5倍
  • サブオプション: 0〜4個がランダムで2倍(確率で決定)
  • 視覚的表現: 専用フレームと色、色付き二つ名表示
  • 効果表示: 強化されたオプションはオレンジ色で表示

このシステムにより、レアな防具を獲得する楽しみと、装備の多様性が向上します。

皆さんも自分だけの最強防具をゲットしてください!

次回予告

次回は拠点機能を実装したので、紹介をします。

拠点機能はThe放置ゲームという感じで作っていてとても楽しかったです!

皆様に楽しんでいただけるように頑張って実装していきます!

お楽しみに!

タイトルとURLをコピーしました