ゲーム作り

【解説通りに作るだけ】デジタルカードゲームの作り方④ カードの動かし方編

 

前回の解説で手札やフィールドにカード生成することが出来るようになりましたね!

見てない人はこちら参照↓

【解説通りに作るだけ】Unityのデジタルカードゲーム作り方③ 手札の生成編 前回でカードとフィールドの作成が完了しましたね! ※前回の記事はこちら↓ http://yuus01.info/ga...

 

今回はカードを持って動かせるようにしていくよ!!

完成形としてはこんな感じ!

 

動かせるようになるとカードゲームらしくなって楽しいよね!!

そんなわけで早速いくぞ!!

 

カードを動かす為のコードの実装

ではまず、カードを持って動かしたり、フィールドに出せるようにするのに必要な実装の流れを説明していくよ!

 

流れはザッとこんな感じ↓

①.カードを動かすコードを書く
②.フィールドに置く為のコードを書く
③.カードにコードを貼り付ける(アタッチする)
④.フィールドにコードを貼り付ける(アタッチする)

 

コードの内容と貼り付け方は後で詳しく説明するから、

とりあえずの流れを頭に入れといて、やりながら「あー今はここをやってるのね」って思いながらやるといいよ!

そんな訳で実際にやっていくぞ!!

 

①②2つのコード記入

ここではまず
カードを動かすためのコードと、
フィールドに置くためのコードを書いていくよ!

 

1.スクリプトの作成

では新しいスクリプトを2つ作るよ。

名前は、

“CardMovement”

“DropPlace”

という名前で作ってね。

クラス作成方法が分からないひとは以下を参考にして!!

 

“CardMovement”と”DropPlace”という名前のクラスが出来たらOK!!↓

 

それぞれ

カードを動かすためのコード(”CardMovement”)

フィールドに置くためのコード(”DropPlace”)

になってるよ。

 

2.プログラムの記入

そしたら中身を開いて、中身を丸ごと全部コピぺしよう。

 

”CardMovement”はこっち↓

 

”DropPlace”はこっち↓

 

③④コードの貼り付け(アタッチ)

無事コードが書けたら、今度はUnity側の設定をしていくよ!

まずはCardPrefabに”CardMovement”を張り付けよう。

①.Cardプレハブをクリック
②.右下の「Add Component」をクリック
③.CardMovementと入力して、選択する
④.右のInspecterビューに、CardMovementが表示されればOK!!

≪2020/07/13 追記≫

コメントでご指摘いただいた所についての追記になります。

⑤.上記に加えて「Canvas Group」の追加。(パラメータは上の画像に合わせて下さい)

他にも疑問点、抜けてる点などコメントしていただけるとめちゃくちゃありがたいです!

コメント頂きありがとうございました!!

 

同じように、PlayerFieldにも”DropPlace”を張り付けよう。↓

 

 

そしたら実行ボタンを押す!!

 

動かせるし、フィールドに出せる!!!

と、そんな感じでカードを自由に動かして出せるようになったかな??

そしたらコードの解説をしていくよー!

 

コードの解説

ではカードを動かしてる、
それぞれのコードについて説明していくよ!!

①CardMovement(カードを動かすためのコード)と、

②DropPlace(カードを置くためのコード)の順に説明していくよ。

 

①CardMovementについて

まずはカードに貼り付けた”CardMovement”のコードについて。

 

ざっくりまとめるとこんな感じ↓

1.《カードをドラッグし始めた時の処理》→親要素を変更する(10~15行目)
2.《ドラッグ中の処理》→カードの場所をマウスポインターと同じにする(17~20行目)
3.《ドラッグし終わった時の処理》→親要素を変更する(22~26行目)

 

一番重要な”OnDrag”メソッド

今回一番重要なのが、17行目の”OnDrag”メソッド

名前の通りだけど、

OnDragメソッドとは、
ドラッグしてる時にこのメソッドの中に書いてある処理を実行
するというメソッド。

今回で言うと、
transform.position = eventData.position
なので、

ドラッグしてる間は、
transform.position(カードの場所)を
eventData.position(マウスポインターの場所)にするよ。

っていう処理をしてるってこと!!

 

他のメソッドについて

次に大事なのが、“OnBeginDrag”と”OnEndDrag”メソッド

(”OnDrag”メソッドの上と下にあるメソッドのことね。)

 

これらはそれぞれ、

ドラッグし始めた時の処理(OnBeginDragメソッド)

ドラッグし終わった時の処理(OnEndDragメソッド)

が書かれてるよ。

 

それぞれメソッドの中に、

transform.SetParent(~,false)

って書かれてるけど、これの意味は

(この場合で言うと)カードオブジェクトの親要素を変更する。ってこと。

親要素って言うのはこれね。↓

 

今回の動きで説明すると、

ドラッグする前の手札のカード(赤枠で囲ってるカード)の親要素は、PlayerHand。

 

これをドラッグすると親要素がCanvasに変わる↓

※transform.SetParent(cardParent.parent, false)の処理による結果

 

ドロップしたらこうなる↓

という処理をここで行ってるよ!

 

〜Handlerについて

次はクラス名の後ろに書いてあるIDragHandlerとかについての説明。

ここね↓

ここの部分にいくつか書いてあるけど、

さっき説明した“OnDrag”メソッドを使う時は”IDragHandler“書かないと使えないよ。

って認識でOK。

 

それぞれ以下に対応してるよ↓

【クラス名】 【メソッド名】
IDragHandler “OnDrag”メソッド
IBeginDragHandler “OnBeginDrag”メソッド
IEndDragHandler “OnEndDrag”メソッド

表の右のメソッドを使うには、対応したクラスを書く必要があるってことね。

 

継承部分についてもう少し詳しく知りたい人はコメント下さいな。

 

unityengine.eventsystemsについて

最後にこれ↓

 

これもすごくザックリ言うと、

さっき説明した、IDragHandlerとかを使う為に書く必要があるもの。

って認識でOK

これを書かないと使えないので書きましょう。ってだけ。

ここも詳しく知りたい人がいたらコメントくださいな。

 

②DropPlaceについて

次にフィールドに貼り付けたコードについての解説!

ざっくり、やってる処理としては、

《ドロップされた時の処理》→カードの親要素をアタッチしてるオブジェクトに変える

ってだけ。

 

なので、この”DropPlace”クラスの親要素を変更する処理をコメントアウトすると、、

置けなくなる!!(実際にやってみてね)

と言うわけで、この処理を行う“DropPlace”クラスをアタッチしたから、カードが置けてる。ってことですな。

 

演習

今回は割と簡単な演習だからみんなやってみて!

【演習】

現在は自分の手札から、自分のフィールドにカードを置くことは出来るけど、

逆にフィールドから手札に戻すことは出来ない。自分のフィールドから相手のフィールドに置くことも出来ない。

ではフィールドのカードを手札に戻す、あるいは相手のフィールドに出せるようにするにはどうすれば良いか。

 

ヒントとしては、

コードが貼ってあるから置けるんだよ。

って話。

 

まあカードゲームとしては有り得ない仕様だけど、練習だと思ってやってみよう!

 

答え合わせ

出来たかな??

ただ単にコピペしてるだけだと全く身に付かないから、やり方を覚えながら進もうね。

んで、答えはこう↓

このふたつにDropPlaceをアタッチするだけ!!

変な仕様になっちゃうから終わったらアタッチしたのは消しといてね!!

 

【最後に】お詫びとか、今後について

更新がめちゃくちゃ遅くなってしまってごめんなさい!!

コメントしてくれた方々ほんとにありがとうございました!

これでもめちゃくちゃ原動力になってます。

記事を書いてる側としては、ほんとにたった一言のコメントでも力になるし嬉しいんです!

なのでほんの1mmでも応援して頂けたり、参考になったという方はぜひコメントをお願いします。

(もちろん「ここがちょっと分かりずらいよ!」などのコメントでも大丈夫です!参考にしますので!!)

 

その代わりと言ってはなんですが、

7月中にカードゲームの基本動作までの
解説記事を全て書いて投稿します。

(現時点で全く記事のストックとか無いけど。。笑)

具体的には下の動画で言うと、
マナコスト通りにカードを出して、
相手のカードとバトルする所までね。
(スペルカードとか、モンスター効果とかはその後に実装するよ)

 

ペースとしては週に2回の投稿を予定しています。

なので全10回程度の解説記事になると思います。

そして最終的には「初心者がカードゲームを作りたいなら”みじんこのブログ”を見ればいいよね」って言ってもらえるようなサイトにしたいと思ってます!

その為にはあなたのコメント一つがめちゃくちゃ力になるので、一言でもいいのでコメントの方よろしくお願いいたします!!

 

新しい記事を投稿したタイミングとか、
ゲームについての役立ち(そうなこと)など
知りたい方はフォローして下さいな→→mijinko_game000

あと質問などあれば、お気軽にどうぞ!!!

 

次の記事↓

【解説通りに作るだけ】デジタルカードゲームの作り方講座⑤ カードデータの反映編 前回までの記事でカードを持って動かせるようになりましたね!! 見てない人は前回の記事参考↓ http://yuus0...

前の記事↓

【解説通りに作るだけ】Unityのデジタルカードゲーム作り方③ 手札の生成編 前回でカードとフィールドの作成が完了しましたね! ※前回の記事はこちら↓ http://yuus01.info/ga...

では今回は終わりっ!!

 

何も知らない初心者がカードゲームアプリを作ろうとした結果www ワクワクが止まらないんだが、、?!! 子供の頃から作りたかったゲームをとうとう形にする日が来たと思うとワクワクが止...
Unity初心者がいきなりカードゲームを作るのは無理??【答え:余裕です】 初心者だけど、カードゲームを作ってみたい!! って思って、色々調べてみると って気持ちになっちゃうよね。 ...
【超自由になれます】Bluetoothイヤホンを使うべき3つのメリットとデメリット突然だけど Bluetoothイヤホン使ってる?? 元々ぼく自身「Bluetooth??なにそれおいしいの?」状態だったので...

 

ABOUT ME
みじんこ
【名前】みじんこ(ここのブログ書いてるひと) ・大学2年の時に「ゲームが作りたいー!!」って思ったのに、ゲームの作り方を解説してるサイトがことごとく何言ってんのか分かんなくて挫折した。 ・数年な時を経て「だったら俺が完全初心者にも超わかりやすいサイトを作ってやんよ!」って事で、初めてゲームを作ろうとしてる方向けに解説記事を書いてるよ。

POSTED COMMENT

  1. yuki より:

    こんにちは。
    記事参考になりました。続き楽しみです。

    CanvasGroupを使われてますが、AddComponentで「CanvasGroup」も追加しないといけないのではないでしょうか?

    • みじんこ より:

      >yukiさん
      コメントありがとうございます!
      あ、、完全に抜けてました。
      これだとエラーめちゃくちゃ出ますね。。笑
      すみません、CanvasGroupの追加は必要です!!
      記事に追記したのでよろしくお願いします。
      また何かあったらコメントお願いしますね!

      次の記事は今日か明日に出せると思うので、また見て下さい!

  2. もっけ より:

    凄く参考になりました
    Unity初なので大変助かっています
    DropPlaceをPlayerHandに入れて実行したら
    入れたものがなくなっている現象に見舞われて困っていましたが
    実行中に入れても戻るんですね(初心者杉;

    • みじんこ より:

      >もっけさん
      コメントありがとうございます^^
      確かに実行中にアタッチしたものは、実行を停止すると消えますね(笑)

      困ることも多いですが、特に初心者のうちはミスすればするほど色々知れるので、
      解説に無いことでも気になることはガンガン試しながら作ってみてください!(バックアップは取っておいた方が良いかも。。)

  3. まさきさま より:

    大変参考になりました.
    質問がありコメントいたしました.

    カードの配置に関しての質問です.すでに解説されている内容でしたら申し訳ございません.

    カードをきれいに配置する方法は,記事に書いてあり,わかったのですが,
    カードをもって,任意の位置に配置することは可能でしょうか?
    よろしくお願い致します.

    • みじんこ より:

      >まさきさまさん
      コメントありがとうございます!
      カードを固定の位置に配置する方法ですかね??(遊戯王みたいな?遊戯王やってなかったらごめんなさい。。)

      恐らく色々方法はあるとは思いますが、あくまで僕が実装するんだとしたら、
      今ある「PlayerField」の幅を縮めたものを5つ分作って、1枚づつカードを置けるようにしますかね~(フィールドに5体まで出せるようにする場合の話)

      って説明で分かりますかね、、??
      いまいち分からなかったらまたコメント下さい!
      (出来た時もコメントくれたら嬉しい。笑)

      • まさきさま より:

        お返事、感謝いたします。
        わかりやすい解説ありがとうございました。
        今後もよろしくお願いいたします。

  4. ピーロ より:

    いつも参考にさせて頂いてます
    CardMovementのスクリプトを作成して、プログラムを記入したのに、
    Add Componentをクリックして
    CardMovementで検索してもCardMovementが表示されません
    どういった原因が考えられますでしょうか?

    • みじんこ より:

      >ピーロさん
      コメントありがとうございます!

      んー、一番多いのは、コードに書かれているクラス名が間違っていることですかね。
      なので一旦、コードのクラス名と検索した時のクラス名にスペルミスが無いかを確認してみて下さい!

      特に間違ってなければ、、、(´・ω・`)ナンダロウ

  5. ラい より:

    コードに関しての質問です。コードを映しても書くやつで参照なしとなってしまい、動きません。
    どうしたらいいのでしょうか?
    Logを出そうとしてもOnBeginDrag・OnDrag・OnEndDrag・OnDrop
    が動きませんでした。

    • みじんこ より:

      >ラいさん
      コメントありがとうございます!
      返信遅れてすみません、届いてますよ!

      んー、CardMovementとDropPlaceクラスの話ですかね?

      4行目の
      using UnityEngine.EventSystems;
      は書いてありますか?

      これが書いてないと、動かないので一旦確認してみて下さい!
      ちなみにコードにエラーは出てないってことでいいですよね??
      アタッチは出来てない状況なんですかね、、??

      >コードを映しても書くやつで参照なしとなってしまい、動きません。
      あとこの”書くやつ”って言うのが分からなくてなんとも、、、
      どこのことでしょうか、、(´・ω・`)ゴメンヨ

  6. ラい より:

    using UnityEngine.EventSystems;は書いてありますね。エラーは出てません。public void OnBeginDrag(PointerEventData eventData)などの上に普通ならUnity メッセージ□個の参照と表示されるはずなのですが、0個の参照となって動きません。ということです。わかりにくくてすみません。

    • みじんこ より:

      >ラいさん
      あー、なるほど!分かりました!
      OnBeginDragメソッドなどは、メソッドを別のところから呼び出してる訳ではないので0個の参照と表示されていて問題ないです。
      コードにエラーが出てないのなら、プログラムにミスはないと思います。

      “動かない”とありますが、実行ボタンを押した後に、カードをドラッグしても動かないってことですかね?
      Cardプレハブにアタッチはされましたか??

      解説通りにアタッチしてて、動かないなら、、(-ω-)ナンダロウ、、

  7. ラい より:

    あと、カードがPlayerFieldの下になってしまうのはどうしたらいいでしょうか?

    • みじんこ より:

      >ラいさん
      えーと、まずカードは動くようになったってことですかね??

      私としても初心者の方に分かりやすいサイトを作ろうと思ってるので、質問していただくのはむしろウェルカムなのですが、流石に「今は~という状況で、…が出来ない」「これが原因だと思って、~と~を試したけど…になってしまう」など、今の状況を詳細に説明して頂かないと答えようがないです。。
      解説してる通りの動きをしてない時点で、もうどんな状況になってるのか分からないので、、

      質問内容を整理してると、案外自分で解決出来たりしますし、色々分からないながらも直すのはめちゃくちゃ勉強になると思います。
      (あと僕がコメントを見て答えるより、自分で頑張った方が早い場合もあると思うので。笑)

      一旦、「原因は何かな??」って色々悩みながら試して、それでも解決しなかったらまたコメント下さい。
      詳細を説明していただければ、力になれるかも知れないので!!

  8. ラい より:

    わかりました!ありがとうございます。頑張ってみます!(でもできることもうなさそう…)

  9. トキムネ より:

    すいません、今「ドラッグしたけど攻撃しなかったカードをもとの位置に戻す」というようにコードを書き換えようとしています(今だと一度クリックしたカードは必ず一番右に動いてしまうので)

    考え方として、CardMovementのOnBeginDragで動かす前のCardの親OriginalCardPosition、位置OriginalCardParentを保存しておき、OnEndDragで「Drag前と親が変わっていなければ親と位置をOriginalCardPosition、OriginalCardParentにする」という処理がいいかなと思うのですが

    public void OnBeginDrag(PointerEventData eventData) // ドラッグを始めるときに行う処理
    {
    Transform OriginalCardPosition = transform.position;
    Transform OriginalCardParent = transform.parent;

    cardParent = transform.parent;
    transform.SetParent(cardParent.parent, false);
    GetComponent().blocksRaycasts = false; // blocksRaycastsをオフにする
    }

    ではTransform OriginalCardPositionのところでエラーになってしまいました。
    現状あまりtransformの使い方を理解できていないのですが、どうやって元のカード親・位置を取得すればよいでしょうか?

    • みじんこ より:

      >トキムネさん
      あー、確かに気になりますよね。。笑
      あとで「バグ修正」的な記事で解説しようとは思ってたので、細かい解説はそっちで。。。

      で、肝心のやり方ですが、考え方としては完璧です!!(・ω・)スバラシイ!
      ただ使うコード(position)がちょっと違いますね!

      今回、Cardの位置が変わってしまうのは、Hierarchy上でCardの位置が入れ替わってることが原因です。
      試しにゲーム実行中にPlayerFieldのCard(子要素)の順番をHierarchyビュー上で動かしてみて下さい。
      ゲーム上でもカードの順番が変わると思います。

      つまり今回重要なのは「子要素の順番」です!!
      そしてこれを変更するコードは、“SetSiblingIndex”です。
      ※ちなみに元の子要素の順番を取得するコードは、“GetSiblingIndex”です。

      このコードを使って実装できるので、是非色々試してみてください!!(ちょっと難しいかも知れないですけど、演習だと思って頑張って下さい!)
      分からなかったらまた聞いて下さいー!

      参考:https://unity-yuji.xyz/change-hierarchy-order/

  10. ラい より:

    できました!Imageを使わないでやってたようでした。ありがとうございます!

  11. トキムネ より:

    できました‼

    using(略)

    public class CardMovement : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler
    {
    public Transform cardParent;//
    Transform OriginalParent;//元のカードの親を入れる
    int Cnamber;//元のカードの順番を入れる

    public void OnBeginDrag(PointerEventData eventData) // ドラッグを始めるときに行う処理
    {
    OriginalParent =this.transform.parent;
    Cnamber = this.transform.GetSiblingIndex();

    (元のOnBeginDragの処理を書く)
    }

    public void OnDrag(PointerEventData eventData) // ドラッグした時に起こす処理
    {
    (略)
    }

    public void OnEndDrag(PointerEventData eventData) // カードを離したときに行う処理
    {
    if (OriginalParent == cardParent)
    {
    transform.SetParent(OriginalParent, false);
    transform.SetSiblingIndex(Cnamber);
    GetComponent().blocksRaycasts = true; // blocksRaycastsをオンにする
    }
    else
    {
    (元のOnEndDragの処理を書く)
    }
    }
    }

    現状変な挙動していないのでこれで正解だと思います!
    わざわざ参考URLまで教えていただき助かりました!
    いつもコメントに反応していただき本当に助かってます。本当にありがとうございます!

    • みじんこ より:

      >トキムネさん
      おー!!!素晴らしい!!!
      120点です!!完璧です!笑

      ほぼ思っていた通りのコードになっていて、ちゃんと動いているので問題ないと思います!
      (ちょっとだけ言うとnamberじゃなくて、numberかな。笑
       でもぶっちゃけコードなんて動けばいいと思ってるので気にすることなしです!笑 完璧です!!)

      こちらこそいつもコメントくれるので僕も助かってますよ!
      今後ともよろしくお願いしますね~

COMMENT

メールアドレスが公開されることはありません。