質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.64%

選択肢分岐する際に他のクラスの情報を取得したい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 189

Gchan

score 4

簡単なカードゲームにおいて、プレイヤーのキャラクター(Hero)に割り当てたenumの種類によって
ターン開始時に表示される選択肢パネル上のテキストを変更して、果物関連の選択肢か野菜関連の選択肢かに切り替えるスクリプトを書きたいと思っていて

プレイヤーのキャラクターに関してはプレハブをインスタンス化してスクリプタブルオブジェクトで管理しています。
とりあえず全体の流れを書いていきます。

まずHeroEntity.csでHeroのスクリプタブルオブジェクトを作成

HeroEntity.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName ="HeroEntity",menuName ="Create HeroEntity")]
public class HeroEntity : ScriptableObject
{
    public Sprite hero; //heroのアイコン画像
    public CARDLEVEL level; //heroのレベル
}
public enum CARDLEVEL //heroのレベル段階
{
    LEVEL3,
    LEVEL4,
    LEVEL5,
}

次にHeroModel.csでHeroの器を作成

HeroModel.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HeroModel
{
    public Sprite hero;
    public CARDLEVEL level;
    public bool isPlayerHero; //プレイヤーのヒーローかどうか
    public HeroModel(int heroID, bool isPlayer)
    {
        HeroEntity heroEntity = Resources.Load<HeroEntity>("HeroEntityList/Hero" + heroID);
        hero = heroEntity.hero;
        isPlayerHero = isPlayer;
    }
}


次にHeroView.csでHeroの見かけを設定

HeroView.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class HeroView : MonoBehaviour
{
    [SerializeField] Image heroImage = default;

    public void ShowHero(HeroModel heroModel)
    {
        heroImage.sprite = heroModel.hero;
    }
}


最後にHeroController.csでコントローラーを設置

HeroController.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HeroController : MonoBehaviour
{
    HeroView view;
    public HeroModel model;

    private void Awake()
    {
        {
            view = GetComponent<HeroView>();
        }
    }
    public void MakeHero(int heroID, bool isPlayer)
    {
        model = new HeroModel(heroID, isPlayer);
        view.ShowHero(model);
    }
}

Heroを表示するためのメソッドはGameManager.csに記載

GameManager.cs

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

    [SerializeField] Transform playerHeroTransform = default;  //プレイヤーHeroを表示するパネル
    [SerializeField] Transform enemyHeroTransform = default;  //エネミーHeroを表示するパネル
    [SerializeField] HeroController heroPrefab = default;  //Heroのプレハブ

    List<int> playerHero = new List<int>();
    List<int> enemyHero = new List<int>();

    List<int> HeroEvolve = new List<int>() { 1, 2, 3 };

    public bool isPlayerTurn; //プレイヤーターンかどうか

    void Start() 
    {
        //HeroEvolveのリストをそれぞれのプレイヤーのHeroリストに追加
        playerHero.AddRange(HeroEvolve);
        enemyHero.AddRange(HeroEvolve);

        //それぞれのHeroパネルの上にHeroを生成
        //この段階ではHeroEvloveの要素1番目がお互いに生成されているので
        //要素[0]の1がHeroModel.csの"HeroEntityList/Hero" + heroIDのheroIDに入るので
        //HeroEntityListフォルダに入っているHero1という名前で設定されたHeroが表示される
        GiveHero(HeroEvolve, playerHeroTransform);
        GiveHero(HeroEvolve, enemyHeroTransform);
    }


    public void GiveHero(List<int> evolve, Transform herofield) 
    {
        int heroID = evolve[0]; //取得したリストの1番目の要素をheroIDとする
        CreateHero(heroID, herofield); 
    }
    void CreateHero(int heroID, Transform herofield) 
    {
        HeroController hero = Instantiate(heroPrefab, herofield, false); //Heroプレハブのインスタンス生成
        if (herofield.transform == playerHeroTransform) //生成場所がプレイヤーのHero配置場所なら
        {
            hero.MakeHero(heroID, true); //isPlayerHeroをtrueに
        }
        else
        {
            hero.MakeHero(heroID, false); 
        }
    }


今回追加したい要素
aとbどちらを選びますか?という選択肢のパネルをHeroのenumに設定したカードレベルで条件分岐させたい。
多分スクリプトを先に書いた方が早いと思うので、変更したスクリプトを書きます

まずGameManager.cs

変更予定のGameManager.cs

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

    [SerializeField] Transform playerHeroTransform = default;  
    [SerializeField] Transform enemyHeroTransform = default; 
    [SerializeField] HeroController heroPrefab = default;
    [SerializeField] GameObject choisePanel = default; //選択肢表示パネル
    [SerializeField] Text choiseText = default; //パネル全体のテキスト。"どちら選びますか?"的な
    [SerializeField] Text achoiseText = default; //aボタン上のテキスト
    [SerializeField] Text bchoiseText = default; //bボタン上のテキスト

    List<int> playerHero = new List<int>();
    List<int> enemyHero = new List<int>();

    List<int> HeroEvolve = new List<int>() { 1, 2, 3 };

    void Start() 
    {
        choisePanel.SetActive(false); //スタート時には表示させないため
        playerHero.AddRange(HeroEvolve);
        enemyHero.AddRange(HeroEvolve);
        GiveHero(HeroEvolve, playerHeroTransform);
        GiveHero(HeroEvolve, enemyHeroTransform);
    }

    public void ChangeTurn() //ターン切り替えの処理、これをターン切り替えボタンに設置して切り替えしている
    {
        isPlayerTurn = !isPlayerTurn; //boolの真偽でターン切り替えしている
        if (isPlayerTurn == true) //プレイヤーターンの場合の処理
        {
            choisePanel.SetActive(true); //ターン切り替え時にこの選択肢表示パネルを表示させたい
        }
        else //エネミーターンの時も同様に
        {
            choisePanel.SetActive(true); 
        }
    }

    //ここからは選択肢パネル上のボタンを押した際の処理
  public void AChoise() //Aボタンを押したときの処理
    {
        choisePanel.SetActive(false); //押したら選択肢表示パネルは消す

    }
    public void BChoise() //Bボタンを押したときの処理
    {
        choisePanel.SetActive(false);
    }

・今回実装したい具体的なコード

まず直したい部分

GameManager.cs

    public void ChangeTurn() //ターン切り替えの処理、これをターン切り替えボタンに設置して切り替えしている
    {
        isPlayerTurn = !isPlayerTurn; //boolの真偽でターン切り替えしている
        if (isPlayerTurn == true) //プレイヤーターンの場合の処理
        {
            choisePanel.SetActive(true); //ターン切り替え時にこの選択肢表示パネルを表示させたい
        }
        else //エネミーターンの時も同様に
        {
            choisePanel.SetActive(true); 
        }
    }


この処理の時に

    public void ChangeTurn() //ターン切り替えの処理、これをターン切り替えボタンに設置して切り替えしている
    {
        isPlayerTurn = !isPlayerTurn; //boolの真偽でターン切り替えしている
        if (isPlayerTurn == true) //プレイヤーターンの場合の処理
        {
            if( もしプレイヤーヒーローのenumがLEVEL5なら) //本質問の冒頭のスクリプトでheroにenumを割り当てています
            {
                choiseText.text = "あなたが選ぶ果物は"; //パネル上のテキストを変更
                achoiseText.text = "リンゴ"; //aボタン上のテキストをリンゴに変更する
                bchoiseText.text = "オレンジ"; //bボタン上のテキストをオレンジに変更する
            }
            else (そうじゃないなら)
            {
                choiseText.text = "あなたが選ぶ野菜は"; //パネル上のテキストを変更
                achoiseText.text = "ニンジン"; //aボタン上のテキストをニンジンに変更する
                bchoiseText.text = "キャベツ"; //bボタン上のテキストをキャベツに変更する
            }
            choisePanel.SetActive(true); //↑でテキストを変更した選択肢表示パネルを表示
        }
        else //エネミーターンの時も同様に
        {
            choisePanel.SetActive(true); 
        }
    }

この、もしプレイヤーヒーローのenumがLEVEL5ならの部分をどうやって取得してくればいいのかが分かりません。

playerHeroTransform上に表示されているHeroインスタンスのenum CARDLEVELがLEVEL3~5のどれであるかを取得して、LEVEL5であれば、パネル上のテキストを果物関連に、LEVEL3~4であれば野菜関連の表示にしたいのですが

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

他の方法の勧め

このような場合は、後からの追加(野菜、果物の他に調味料を追加したいなど)を考えると、列挙体では無くDictionary<int, string> や、単に string を用いた方が良いと思います。

クラスから取得

これは簡単です。

≪CARDLEVEL≫ = ≪Class≫.≪CARDLEVEL≫;

このクラスは作成時の変数を変数に保管しておき、それを使用します。

class A
{
    public static ≪Enumのあるクラス≫ player;

    void Start()
    {
        GameObject v = new GameObject().AddComponent<≪Enumのあるクラス≫>();
        ≪Enumのあるクラス≫ player = v.GetComponent<≪Enumのあるクラス≫>();
    }
}
CARDLEVEL≫ = A.player.≪CARDLEVEL≫;

列挙体の分岐

列挙体にはそれぞれの値に必ず整数値が与えられていますので、その値を比較します。

▼このような列挙体があったとします。

public enum Enum
{
    Level1 = 1,
    Level2,
    Level3,
    Level4,
    Level5,
    Level6,
}
ifで値を比較する方法

この時Level5は5、Level6は6が割り振られている(先頭から順に自動的に割り当てられる)ので

if (5 =< (int)≪Enum≫) /*ここに処理を書く*/


これでOKです。

switchの方法

上記の場合あまりおすすめは出来ませんが、

switch (≪Enum≫)
{
    case Level1 :
        //Level1~Level4の処理
        break;
    case Level2 : goto case Level1;
    case Level3 : goto case Level1; 
    case Level4 : goto case Level1;
    case Level5 :
        //Level5,Level6の処理
        break;
    case Level6 :  goto case Level5;
}

このような方法をとっているのは、コードを変更する時に手間を省くためです。
ただ忌まれているgotoを使っているので良いコードとは言えませんが

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/11/01 21:55

    丁寧にありがとうございました!
    無事解決できました、助かりました!!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.64%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る