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

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

ただいまの
回答率

90.76%

  • C#

    6581questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Unity

    3607questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

[Unity][C#]カードゲームにおいて、デッキ外から召喚するクリーチャーのPrefab描画をしたい

受付中

回答 4

投稿

  • 評価
  • クリップ 1
  • VIEW 233

imohori708

score 2

※長文となってしまったため、分けて投稿します

投稿に慣れていないため、分かりづらい点が多々あるかと思いますがよろしくお願い致します。
過不足があれば随時補足します。

 使用アセット

CCGKit
マニュアル:https://www.ccgkit.com/wiki/index.php?title=Main_Page

 実現したいこと

上記アセットを利用して、カードゲーム「ハースストーン」のコピーゲームを作成したいと考えています。
カードの能力拡張を行っているのですが、以下の点において作業が停滞しています。

・特定のカード(以下、カードAとします)を手札からボードに召喚(移動)した際、指定したカード(以下、トークンBとします)を別途、デッキ外から召喚する機能を実装したい

 現状のクラス構成

各カードの情報はUnityのエディタ拡張により、JSON形式で保存しております。
以下に、あるカードの例を記します。

            {
                "cardTypeId": 0,
                "name": "カード名を表す文字列(実際はUnicode表記です)",
                "costs": [
                    {
                        "statId": 1,
                        "value": 2,
                        "$type": "CCGKit.PayResourceCost"
                    }
                ],
                "properties": [
                    {
                        "value": "能力の内容を表現するための文字列(実際はUnicode表記です)",
                        "name": "Text",
                        "$type": "CCGKit.StringProperty"
                    },
                    {
                        "value": "Creature",
                        "name": "Picture",
                        "$type": "CCGKit.StringProperty"
                    },
                    {
                        "value": 2,
                        "name": "MaxCopies",
                        "$type": "CCGKit.IntProperty"
                    },
                    {
                        "value": null,
                        "name": "Material",
                        "$type": "CCGKit.StringProperty"
                    }
                ],
                "stats": [
                    {
                        "baseValue": 2,
                        "statId": 0,
                        "name": "Attack",
                        "originalValue": 2,
                        "minValue": 0,
                        "maxValue": 99,
                        "modifiers": []
                    },
                    {
                        "baseValue": 3,
                        "statId": 1,
                        "name": "Life",
                        "originalValue": 3,
                        "minValue": 0,
                        "maxValue": 99,
                        "modifiers": []
                    }
                ],
                "keywords": [],
                "abilities": [
                    {
                        "trigger": {
                            "zoneId": 2,
                            "$type": "CCGKit.OnCardEnteredZoneTrigger"
                        },
                        "name": "heal 2",
                        "type": "Triggered",
                        "effect": {
                            "value": {
                                "constant": 2,
                                "$type": "CCGKit.ConstantValue"
                            },
                            "duration": 0,
                            "statId": 1,
                            "gameZoneId": 2,
                            "cardTypeId": 0,
                            "$type": "CCGKit.IncreaseCardStatEffect"
                        },
                        "target": {
                            "conditions": [],
                            "$type": "CCGKit.TargetCard"
                        },
                        "$type": "CCGKit.TriggeredAbility"
                    }
                ],
                "id": 1


これらを読み込み、一枚のカードを描画する処理を組んでいます。
これらの値はRuntimeCardクラスというクラスで管理されており、カードをハンドからボードに移動する際にもこのクラスを利用しているように見えます。

using System;
using System.Collections.Generic;

namespace CCGKit
{
    /// <summary>
    /// This class represents a runtime instance of a card.
    /// このクラスは、カードのランタイムインスタンス(プログラムの実行に必要な部品の集合)を表します。
    /// </summary>
    public class RuntimeCard
    {
        /// <summary>
        /// The card identifier of this card.
        /// カードの固有ID
        /// </summary>
        public int cardId;

        /// <summary>
        /// The instance identifier of this card.
        /// このカードのインスタンス識別子。
        /// </summary>
        public int instanceId;

        /// <summary>
        /// The stats of this card, indexed by id.
        /// このカードのスタッツはidで示されます。
        /// </summary>
        public Dictionary<int, Stat> stats = new Dictionary<int, Stat>();

        /// <summary>
        /// The stats of this card, indexed by name.
        /// このカードのスタッツは名前で示されます。
        /// card.namedStats["Attack"];みたいな書き方で値を取得できる
        /// </summary>
        public Dictionary<string, Stat> namedStats = new Dictionary<string, Stat>();

        /// <summary>
        /// The keywords of this card.
        /// カードのキーワード
        /// </summary>
        public List<RuntimeKeyword> keywords = new List<RuntimeKeyword>();

        /// <summary>
        /// The player that owns this card.
        /// このカードを所有しているプレイヤー。
        /// </summary>
        public PlayerInfo ownerPlayer;

        /// <summary>
        /// The type of this card.
        /// カードタイプ
        /// ミニオン or スペル
        /// </summary>
        public CardType cardType
        {
            get
            {
                var gameConfig = GameManager.Instance.config;
                var libraryCard = gameConfig.GetCard(cardId);
                return gameConfig.cardTypes.Find(x => x.id == libraryCard.cardTypeId);
            }
        }

        /// <summary>
        /// The callback that is called when a keyword is added to this card.
        /// このカードにキーワードが追加されたときに呼び出されるコールバック。
        /// </summary>
        public Action<RuntimeKeyword> onKeywordAdded;

        /// <summary>
        /// The callback that is called when a keyword is removed from this card.
        /// このカードからキーワードが削除されたときに呼び出されるコールバック。
        /// </summary>
        public Action<RuntimeKeyword> onKeywordRemoved;

        /// <summary>
        /// Adds a keyword to this card.
        /// このカードにキーワードを追加する
        /// </summary>
        /// <param name="keyword">The identifier of the keyword.</param>
        /// <param name="value">The value of the keyword.</param>
        public void AddKeyword(int keyword, int value)
        {
            var k = keywords.Find(x => x.keywordId == keyword && x.valueId == value);
            if (k == null)
            {
                k = new RuntimeKeyword();
                k.keywordId = keyword;
                k.valueId = value;
                keywords.Add(k);
                if (onKeywordAdded != null)
                {
                    onKeywordAdded(k);
                }
            }
        }

        /// <summary>
        /// Removes a keyword from this card.
        /// カードからキーワードを削除する
        /// </summary>
        /// <param name="keyword">The identifier of this keyword.</param>
        /// <param name="value">The value of this keyword.</param>
        public void RemoveKeyword(int keyword, int value)
        {
            var k = keywords.Find(x => x.keywordId == keyword && x.valueId == value);
            if (k != null)
            {
                keywords.Remove(k);
                if (onKeywordRemoved != null)
                {
                    onKeywordRemoved(k);
                }
            }
        }

        /// <summary>
        /// Returns true if this card has the specified keyword and false otherwise.
        /// このカードに指定されたキーワードがある場合はtrueを返し、そうでない場合はfalseを返します。
        /// </summary>
        /// <param name="name">The name of the keyword.</param>
        /// <returns>True if this card has the specified keyword; false otherwise.</returns>
        public bool HasKeyword(string name)
        {
            var gameConfig = GameManager.Instance.config;
            var keywordId = -1;
            var valueId = -1;
            foreach (var keyword in gameConfig.keywords)
            {
                var selectedValue = keyword.values.FindIndex(x => x.value == name);
                if (selectedValue != -1)
                {
                    keywordId = keyword.id;
                    valueId = selectedValue;
                    break;
                }
            }
            var k = keywords.Find(x => x.keywordId == keywordId && x.valueId == valueId);
            return k != null;
        }
    }
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • SAM-tak

    2018/04/30 20:43

    ご自分で回答をつけてらっしゃいますが、追加情報という意図であればトップの質問文を編集して情報の追加を行うほうが良いと思います(ソースコードが見づら過ぎで…)

    キャンセル

  • imohori708

    2018/04/30 21:18

    ご指摘ありがとうございます、字数制限のため止む無く分けて投稿してしまいました。回答を2つに分けましたが多少は改善されましたでしょうか。慣れないことが多く、ご指摘ありがたいです。

    キャンセル

  • fiveHundred

    2018/05/01 11:28

    文字数オーバーするということは、それだけの長文を回答者が読まないといけないということになります。それだと回答しづらくなるので、文字数の範囲内になるように簡素にした方がよろしいかと思います(少なくとも私は回答する気になれないです)。内容を簡素にすることで分かりやすくなり、自己解決できるようになることもあります。

    キャンセル

回答 4

0

続き②です。

CardViewクラスは以下に記載します。

using UnityEngine;
using UnityEngine.Assertions;

using TMPro;

using CCGKit;

/// <summary>
/// カードの描画情報
/// RuntimeCardクラスも持ってる。各スタッツ、使用可能の光とか
/// </summary>
public class CardView : MonoBehaviour
{
public RuntimeCard card { get; private set; }

//使用可能の青い光
[SerializeField]
protected SpriteRenderer glowSprite;

//イラスト
[SerializeField]
protected SpriteRenderer pictureSprite;

[SerializeField]
protected TextMeshPro costText;

[SerializeField]
protected TextMeshPro nameText;

[SerializeField]
protected TextMeshPro bodyText;

protected GameObject previewCard;

public int manaCost { get; protected set; }

[HideInInspector]
public bool isPreview;

protected virtual void Awake()
{
Assert.IsNotNull(glowSprite);
Assert.IsNotNull(pictureSprite);
Assert.IsNotNull(costText);
Assert.IsNotNull(nameText);
Assert.IsNotNull(bodyText);
}

/// <summary>
/// カードの情報を取り込む
/// </summary>
/// <param name="card"></param>
public virtual void PopulateWithInfo(RuntimeCard card)
{
this.card = card;

var gameConfig = GameManager.Instance.config;
/*

var cardType = gameConfig.cardTypes.Find(x => x.id == card.cardId);
Assert.IsNotNull(cardType);
pictureSprite.sprite = Resources.Load<Sprite>(cardType.GetStringProperty("Picture"));

*/

var libraryCard = gameConfig.GetCard(card.cardId);
Assert.IsNotNull(libraryCard);
nameText.text = libraryCard.name;
bodyText.text = libraryCard.GetStringProperty("Text");

var cost = libraryCard.costs.Find(x => x is PayResourceCost);
if (cost != null)
{
var payResourceCost = cost as PayResourceCost;
manaCost = payResourceCost.value;
costText.text = manaCost.ToString();
}

pictureSprite.sprite = Resources.Load<Sprite>(string.Format("Images/{0}", libraryCard.GetStringProperty("Picture")));
var material = libraryCard.GetStringProperty("Material");
if (!string.IsNullOrEmpty(material))
{
pictureSprite.material = Resources.Load<Material>(string.Format("Materials/{0}", material));
}
}

/// <summary>
/// ライブラリーの情報を移行
/// </summary>
/// <param name="card"></param>
public virtual void PopulateWithLibraryInfo(Card card)
{
nameText.text = card.name;
bodyText.text = card.GetStringProperty("Text");

var cost = card.costs.Find(x => x is PayResourceCost);
if (cost != null)
{
var payResourceCost = cost as PayResourceCost;
manaCost = payResourceCost.value;
costText.text = manaCost.ToString();
}

pictureSprite.sprite = Resources.Load<Sprite>(string.Format("Images/{0}", card.GetStringProperty("Picture")));
var material = card.GetStringProperty("Material");
if (!string.IsNullOrEmpty(material))
{
pictureSprite.material = Resources.Load<Material>(string.Format("Materials/{0}", material));
}
}

/// <summary>
/// プレイできるか
/// </summary>
/// <param name="owner"></param>
/// <returns></returns>
public virtual bool CanBePlayed(DemoHumanPlayer owner)
{
return owner.isActivePlayer && owner.manaStat.effectiveValue >= manaCost;
}

/// <summary>
/// ハイライト付いてるか判定
/// </summary>
/// <returns></returns>
public bool IsHighlighted()
{
return glowSprite.enabled;
}

/// <summary>
/// ハイライトをセット
/// </summary>
/// <param name="enabled"></param>
public void SetHighlightingEnabled(bool enabled)
{
glowSprite.enabled = enabled;
}
}

 聞きたいこと

RuntimeCard、あるいはCardViewクラスに、上記JSONファイルから値を持ってきてPlayCardクラスに渡しトークンBを召喚するにはどのようなコードを組めば良いでしょうか。
慣れない質問で要領を得ない書き方になっているかもしれませんが、何卒よろしくお願い致します。
不足している情報があればコメントお願いします。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

続き①です

以下、手札からボードにカードを召喚する箇所と思しきソースコード

    public void PlayCard(CardView card)
    {
        if (card.CanBePlayed(this))
        {
            gameUI.endTurnButton.SetEnabled(false);

            var gameConfig = GameManager.Instance.config;
            var libraryCard = gameConfig.GetCard(card.card.cardId);
            //スペルかミニオンか
            var cardType = gameConfig.cardTypes.Find(x => x.id == libraryCard.cardTypeId);
            if (cardType.name == "Creature")
            {
                //ミニオンをボード上にプレハブ化
                var boardCreature = Instantiate(boardCreaturePrefab);

                var board = GameObject.Find("PlayerBoard");
                boardCreature.tag = "PlayerOwned";
                boardCreature.transform.parent = board.transform;
                boardCreature.transform.position = new Vector2(1.9f * playerBoardCards.Count, 0);
                boardCreature.GetComponent<BoardCreature>().ownerPlayer = this;
                boardCreature.GetComponent<BoardCreature>().PopulateWithInfo(card.card);

                //手札からプレイしたカードを消す
                playerHandCards.Remove(card);
                RearrangeHand();
                playerBoardCards.Add(boardCreature.GetComponent<BoardCreature>());

                //手札のカードのオブジェクトを削除
                Destroy(card.gameObject);

                currentCreature = boardCreature.GetComponent<BoardCreature>();

                //ボードの描画処理
                RearrangeBottomBoard(() =>{var triggeredAbilities = libraryCard.abilities.FindAll(x => x is TriggeredAbility);
                    TriggeredAbility targetableAbility = null;
                    foreach (var ability in triggeredAbilities)
                    {
                        var triggeredAbility = ability as TriggeredAbility;
                        var trigger = triggeredAbility.trigger as OnCardEnteredZoneTrigger;
                        if (trigger != null && trigger.zoneId == boardZone.zoneId && triggeredAbility.target is IUserTarget)
                        {
                            targetableAbility = triggeredAbility;
                            break;
                        }
                    }

                    // Preemptively move the card so that the effect solver can properly check the availability of targets
                    // by also taking into account this card (that is trying to be played).
                    //プレイしようとしているカードも考慮して、エフェクトソルバーがターゲットの使用可能性を適切にチェックできるように、先制してカードを移動します。
                    playerInfo.namedZones["Hand"].RemoveCard(card.card);
                    playerInfo.namedZones["Board"].AddCard(card.card);

                    //ターゲットを取るアビリティがあり、且つターゲットがいる場合
                    if (targetableAbility != null && effectSolver.AreTargetsAvailable(targetableAbility.effect, card.card, targetableAbility.target))
                    {
                        var targetingArrow = Instantiate(spellTargetingArrowPrefab).GetComponent<SpellTargetingArrow>();
                        boardCreature.GetComponent<BoardCreature>().abilitiesTargetingArrow = targetingArrow;
                        targetingArrow.effectTarget = targetableAbility.target;
                        targetingArrow.targetType = targetableAbility.target.GetTarget();
                        targetingArrow.onTargetSelected += () =>
                        {
                            PlayCreatureCard(card.card, targetingArrow.targetInfo);
                            effectSolver.MoveCard(netId, card.card, "Hand", "Board", targetingArrow.targetInfo);
                            currentCreature = null;
                            gameUI.endTurnButton.SetEnabled(true);
                        };
                        targetingArrow.Begin(boardCreature.transform.localPosition);
                    }
                    else
                    {
                        PlayCreatureCard(card.card);
                        effectSolver.MoveCard(netId, card.card, "Hand", "Board");
                        currentCreature = null;
                        gameUI.endTurnButton.SetEnabled(true);
                    }
                    boardCreature.GetComponent<BoardCreature>().fightTargetingArrowPrefab = fightTargetingArrowPrefab;
                });
            }
            //スペルの場合
            else if (cardType.name == "Spell")
            {
                var spellsPivot = GameObject.Find("PlayerSpellsPivot");
                var sequence = DOTween.Sequence();
                sequence.Append(card.transform.DOMove(spellsPivot.transform.position, 0.5f));
                sequence.Insert(0, card.transform.DORotate(Vector3.zero, 0.2f));
                sequence.Play().OnComplete(() =>
                {
                    card.GetComponent<SortingGroup>().sortingLayerName = "BoardCards";
                    card.GetComponent<SortingGroup>().sortingOrder = 1000;

                    var boardSpell = card.gameObject.AddComponent<BoardSpell>();

                    var triggeredAbilities = libraryCard.abilities.FindAll(x => x is TriggeredAbility);
                    TriggeredAbility targetableAbility = null;
                    foreach (var ability in triggeredAbilities)
                    {
                        var triggeredAbility = ability as TriggeredAbility;
                        var trigger = triggeredAbility.trigger as OnCardEnteredZoneTrigger;
                        //トリガーがあり、ボードに入ることがトリガーで、且つユーザーがターゲットを指定している場合
                        if (trigger != null && trigger.zoneId == boardZone.zoneId && triggeredAbility.target is IUserTarget)
                        {
                            targetableAbility = triggeredAbility;
                            break;
                        }
                    }

                    currentSpellCard = card;
                    //ターゲットを取るアビリティがあり、且つターゲットがいる場合、ターゲットを指定してスペルの処理をする
                    if (targetableAbility != null && effectSolver.AreTargetsAvailable(targetableAbility.effect, card.card, targetableAbility.target))
                    {
                        var targetingArrow = Instantiate(spellTargetingArrowPrefab).GetComponent<SpellTargetingArrow>();
                        boardSpell.targetingArrow = targetingArrow;
                        targetingArrow.effectTarget = targetableAbility.target;
                        targetingArrow.targetType = targetableAbility.target.GetTarget();
                        targetingArrow.onTargetSelected += () =>
                        {
                            PlaySpellCard(card.card, targetingArrow.targetInfo);
                            effectSolver.MoveCard(netId, card.card, "Hand", "Board", targetingArrow.targetInfo);
                            currentSpellCard = null;
                            gameUI.endTurnButton.SetEnabled(true);
                        };
                        targetingArrow.Begin(boardSpell.transform.localPosition);
                    }
                    else
                    //そうでなければそのまま処理
                    {
                        PlaySpellCard(card.card);
                        effectSolver.MoveCard(netId, card.card, "Hand", "Board");
                        currentSpellCard = null;
                        gameUI.endTurnButton.SetEnabled(true);
                    }
                });
            }
        }
        else
        {
            card.GetComponent<HandCard>().ResetToInitialPosition();
        }
    }


上記メソッドの引数となっているCarViewクラスは、GUIでマウス左クリック時にぶつかったobjectを判定することによって値を取得してきているため、GUI描画のない、デッキやハンドの外からトークンBを選択することは出来ません。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

    //ミニオンをボード上にプレハブ化
    var boardCreature = Instantiate(boardCreaturePrefab);

    var board = GameObject.Find("PlayerBoard");
    boardCreature.tag = "PlayerOwned";
    boardCreature.transform.parent = board.transform;
    boardCreature.transform.position = new Vector2(1.9f * playerBoardCards.Count, 0);
    boardCreature.GetComponent<BoardCreature>().ownerPlayer = this;
    boardCreature.GetComponent<BoardCreature>().PopulateWithInfo(card);

    currentCreature = boardCreature.GetComponent<BoardCreature>();

ここの部分をPopulateToken(Card card)のようなメソッドとしてくくり出して、カードAプレイ時に呼び出してやれば良いような気がします。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/05/01 08:47

    回答頂きありがとうございます。
    回答頂いたコードの7行目で引数として与えている変数cardはCradViewクラスです。
    参考としたコードでは、GUIでマウス左クリック時にぶつかったobjectを判定することによって値を取得してきているため、GUI描画のない、デッキやハンドの外からトークンBを選択することは出来ません。
    これを上記JSONファイルから読み取った情報のみを利用して、トークンBのCradViewクラスを作成するにはどのようなコードを組めば実現できますでしょうか。

    キャンセル

  • 2018/05/01 09:48

    `PlayCard(CardView card)`のなかでCardViewに依存している処理をしているのは`playerHandCards.Remove(card);`の部分や`Destroy(card.gameObject);`の部分だけだと思うので、CardViewではなくCardを渡してほぼ同じことをする処理は書けると思うんですよ。
    PlayCardをコピペして別名を付けて、引数をCardにしてみて、文法エラーになったところを消すなり妥当な処理に書き換えるなりすればよいのでは。

    キャンセル

  • 2018/05/01 09:51

    なにげにCardで“すべての参照を検索”をしてみると、CCGKitに既にCardからぽんとミニオンを置くコードが既に存在しているかもしれませんが、それは無い、んですよね?

    キャンセル

  • 2018/05/01 10:14

    >なにげにCardで“すべての参照を検索”をしてみると
    こちら、確認しましたがCardのみを引数に取ってミニオンをボード上に置く処理はありませんでした。
    確認が取れたのはRuntimeCardか、あるいはCardViewクラスを引数にしてミニオンを召喚するメソッドのみです。
    念のため、ソースコードにCardクラスとPopulateWithInfoメソッドをそれぞれ追記しました。
    「JSONファイルから値を取得して、トリガーとなるカードAの召喚と同時にトークンBを召喚」を実現するため、今一度アドバイス頂けると幸いです。

    キャンセル

  • 2018/05/01 10:17

    ではCardからRuntimeCardを生成できればいいと思うんですが、それは無いんですか?

    キャンセル

  • 2018/05/01 10:32

    いや、ちがう、PopulateWithInfo(RuntimeCard)は、CardViewのメンバで、これはCardViewをInstantiateした後初期化するためのもの、ですよね?

    となると、やはりPlayCardを改造してPopulateToken(Card)を作れということではないでしょうか。
    PlayCardは何というクラスのメンバメソッドなのでしょう?

    キャンセル

0

追記です。
CardクラスとPopulateWithInfoメソッドそれぞれを下記に記します。
以下、カードクラス。

using System.Collections.Generic;

using UnityEngine.Assertions;

namespace CCGKit
{
    /// <summary>
    /// This class represents a single card in the game.
    /// このクラスは、ゲーム内の1枚のカードを表します。
    /// </summary>
    public class Card : Resource
    {
        /// <summary>
        /// カードの所属陣営(追加)
        /// </summary>
        public static int groupId { get; set; }

        /// <summary>
        /// The current resource identifier.
        /// 現在のリソース識別子(カードのユニークID)
        /// </summary>
        public static int currentId { get; set; }

        /// <summary>
        /// The type of this card.
        /// このカードのタイプ。
        /// </summary>
        public int cardTypeId { get; set; }

        /// <summary>
        /// The name of this card.
        /// このカードの名前。
        /// </summary>
        public string name { get; set; }

        /// <summary>
        /// The costs of this card.
        /// このカードのコスト。
        /// </summary>
        public List<Cost> costs = new List<Cost>();

        /// <summary>
        /// The properties of this card.
        /// このカードの特性。
        /// </summary>
        public List<Property> properties = new List<Property>();

        /// <summary>
        /// The stats of this card.
        /// このカードのスタッツ情報。
        /// </summary>
        public List<Stat> stats = new List<Stat>();

        /// <summary>
        /// The keywords of this card.
        /// このカードのキーワード。
        /// </summary>
        public List<RuntimeKeyword> keywords = new List<RuntimeKeyword>();

        /// <summary>
        /// The abilities of this card.
        /// このカードの能力。
        /// </summary>
        public List<Ability> abilities = new List<Ability>();

        /// <summary>
        /// Constructor.
        /// </summary>
        public Card() : base(currentId++)
        {
        }

        /// <summary>
        /// Returns the value of the integer property with the specified name.
        /// 指定された名前を持つ整数プロパティの値を返します。
        /// </summary>
        /// <param name="name">The name of the property.</param>
        /// <returns>The value of the property.</returns>
        public int GetIntProperty(string name)
        {
            var property = properties.Find(x => x.name == name && x is IntProperty);
            Assert.IsNotNull(property);
            return (property as IntProperty).value;
        }

        /// <summary>
        /// Returns the value of the string property with the specified name.
        /// 指定した名前の文字列プロパティの値を返します。
        /// </summary>
        /// <param name="name">The name of the property.</param>
        /// <returns>The value of the property.</returns>
        public string GetStringProperty(string name)
        {
            var property = properties.Find(x => x.name == name && x is StringProperty);
            Assert.IsNotNull(property);
            return (property as StringProperty).value;
        }
    }
}

続いてPopulateWithInfoメソッド

    public virtual void PopulateWithInfo(RuntimeCard card)
    {
        this.card = card;

        //ゲームの基本設定
        var gameConfig = GameManager.Instance.config;
        //カードのID一覧
        var libraryCard = gameConfig.GetCard(card.cardId);
        Assert.IsNotNull(libraryCard);
        //カードの名前
        nameText.text = libraryCard.name;

        attackStat = card.namedStats["Attack"];
        healthStat = card.namedStats["Life"];
        attackText.text = attackStat.effectiveValue.ToString();
        healthText.text = healthStat.effectiveValue.ToString();

        pictureSprite.sprite = Resources.Load<Sprite>(string.Format("Images/{0}", libraryCard.GetStringProperty("Picture")));
        var material = libraryCard.GetStringProperty("Material");
        if (!string.IsNullOrEmpty(material))
        {
            pictureSprite.material = Resources.Load<Material>(string.Format("Materials/{0}", material));
        }

        onAttackStatChangedDelegate = (oldValue, newValue) =>
        {
            UpdateStatText(attackText, attackStat);
        };
        attackStat.onValueChanged += onAttackStatChangedDelegate;

        onHealthStatChangedDelegate = (oldValue, newValue) =>
        {
            UpdateStatText(healthText, healthStat);
        };
        healthStat.onValueChanged += onHealthStatChangedDelegate;

        //キーワードについての挙動
        //属性追加時にいじるとこ(後日要編集)
        var subtypes = gameConfig.keywords.Find(x => x.name == "Subtypes");
        var impetus = subtypes.values.FindIndex(x => x.value == "Impetus");
        var provoke = subtypes.values.FindIndex(x => x.value == "Provoke");
        foreach (var keyword in libraryCard.keywords)
        {
            if (keyword.keywordId == subtypes.id)
            {
                if (keyword.valueId == impetus)
                {
                    hasImpetus = true;
                }
                else if (keyword.valueId == provoke)
                {
                    hasProvoke = true;
                }
            }
        }

        if (hasProvoke)
        {
            glowSprite.gameObject.SetActive(false);
            shadowSprite.gameObject.SetActive(false);
            shieldGlowSprite.gameObject.SetActive(true);
            shieldShadowSprite.gameObject.SetActive(true);
            shieldSprite.gameObject.SetActive(true);
        }
        SetHighlightingEnabled(false);
        if (hasImpetus)
        {
            StopSleepingParticles();
            if (ownerPlayer != null)
            {
                SetHighlightingEnabled(true);
                isPlayable = true;
            }
        }
    }

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

  • 解決済

    Laravel view関数について

    view関数って、イメージですが下記のようになっているのでしょうか? <?php constant("viewPath","../resources/views/")

  • 解決済

    Texture2Dをななめに切り出す方法

    Texture2Dをななめに切り出す方法を探しています。 4点を基準に画像を切り取る関数などはないでしょうか? GetPixelsの引数も一つの座標と幅、高さしかないためどう斜めに

  • 解決済

    Unity2Dでクリックしたオブジェクトの座標を取得したい

    前提・実現したいこと Unity2Dでドラッグ&ドロップではめていくパズルゲームを作成中です。 現在、パズルが出てくるスポーンが一つだけなのですが、三つに増やしたいと考えてお

  • 解決済

    WPF 複数の動画を順番に再生したい

    お世話になっております。 行いたいこと 動画を順番に再生したいと思っています。 仕様 ・再生したい動画を指定(動画1,動画2,動画3,…,動画N)→ボタンを押す→新しいウィ

  • 解決済

    ListView ヘッダ部の背景色の指定

    C#(visual studio 2010)にて、ListViewをつかった表を作成しております。 ヘッダ部およびデータ部へ情報の表示はできたのですが、 ListViewヘッダ部の

  • 解決済

    RigidbodyをアタッチしたらRigidbody.rotationを使う?

    こちらのサイトを見て http://www.f-sp.com/entry/2017/09/06/181854 >Rigidbodyをアタッチしたゲームオブジェクトの姿勢を変更し

  • 解決済

    C#+SeleniumでStaleElementReferenceError

    C#でSeleniumを使用して自動化処理を書いています。 (ブラウザはChromeです。) OS: Windows10 IDE: Visual Studio 2015 Sel

  • 解決済

    モーダルダイアログ表示・破棄時のメッセージ取得

    スキャナーを利用・管理する、ベースフォームを作りたいと思っています。 ベースフォームを継承したフォームを作成して、 継承フォームからモーダルダイアログを呼び出している間、 スキャナ

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

  • C#

    6581questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Unity

    3607questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

  • トップ
  • C#に関する質問
  • [Unity][C#]カードゲームにおいて、デッキ外から召喚するクリーチャーのPrefab描画をしたい