前回の解説で手札やフィールドにカード生成することが出来るようになりましたね!
見てない人はこちら参照↓
今回はカードを持って動かせるようにしていくよ!!
完成形としてはこんな感じ!
動かせるようになるとカードゲームらしくなって楽しいよね!!
そんなわけで早速いくぞ!!
Contents
カードを動かす為のコードの実装
ではまず、カードを持って動かしたり、フィールドに出せるようにするのに必要な実装の流れを説明していくよ!
流れはザッとこんな感じ↓
①.カードを動かすコードを書く
②.フィールドに置く為のコードを書く
③.カードにコードを貼り付ける(アタッチする)
④.フィールドにコードを貼り付ける(アタッチする)
コードの内容と貼り付け方は後で詳しく説明するから、
とりあえずの流れを頭に入れといて、やりながら「あー今はここをやってるのね」って思いながらやるといいよ!
そんな訳で実際にやっていくぞ!!
①②2つのコード記入
ここではまず
カードを動かすためのコードと、
フィールドに置くためのコードを書いていくよ!
1.スクリプトの作成
では新しいスクリプトを2つ作るよ。
名前は、
“CardMovement”
“DropPlace”
という名前で作ってね。
クラス作成方法が分からないひとは以下を参考にして!!
“CardMovement”と”DropPlace”という名前のクラスが出来たらOK!!↓
それぞれ
カードを動かすためのコード(”CardMovement”)
フィールドに置くためのコード(”DropPlace”)
になってるよ。
2.プログラムの記入
そしたら中身を開いて、中身を丸ごと全部コピぺしよう。
”CardMovement”はこっち↓
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public class CardMovement : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler { public Transform cardParent; public void OnBeginDrag(PointerEventData eventData) // ドラッグを始めるときに行う処理 { cardParent = transform.parent; transform.SetParent(cardParent.parent, false); GetComponent<CanvasGroup>().blocksRaycasts = false; // blocksRaycastsをオフにする } public void OnDrag(PointerEventData eventData) // ドラッグした時に起こす処理 { transform.position = eventData.position; } public void OnEndDrag(PointerEventData eventData) // カードを離したときに行う処理 { transform.SetParent(cardParent, false); GetComponent<CanvasGroup>().blocksRaycasts = true; // blocksRaycastsをオンにする } } |
”DropPlace”はこっち↓
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; // フィールドにアタッチするクラス public class DropPlace : MonoBehaviour, IDropHandler { public void OnDrop(PointerEventData eventData) // ドロップされた時に行う処理 { CardMovement card = eventData.pointerDrag.GetComponent<CardMovement>(); // ドラッグしてきた情報からCardMovementを取得 if (card != null) // もしカードがあれば、 { card.cardParent = this.transform; // カードの親要素を自分(アタッチされてるオブジェクト)にする } } } |
③④コードの貼り付け(アタッチ)
無事コードが書けたら、今度はUnity側の設定をしていくよ!
まずはCardPrefabに”CardMovement”を張り付けよう。
①.Cardプレハブをクリック
②.右下の「Add Component」をクリック
③.CardMovementと入力して、選択する
④.右のInspecterビューに、CardMovementが表示されればOK!!
≪2020/07/13 追記≫
コメントでご指摘いただいた所についての追記になります。
⑤.上記に加えて「Canvas Group」の追加。(パラメータは上の画像に合わせて下さい)
他にも疑問点、抜けてる点などコメントしていただけるとめちゃくちゃありがたいです!
コメント頂きありがとうございました!!
同じように、PlayerFieldにも”DropPlace”を張り付けよう。↓
そしたら実行ボタンを押す!!
動かせるし、フィールドに出せる!!!
と、そんな感じでカードを自由に動かして出せるようになったかな??
そしたらコードの解説をしていくよー!
コードの解説
ではカードを動かしてる、
それぞれのコードについて説明していくよ!!
①CardMovement(カードを動かすためのコード)と、
②DropPlace(カードを置くためのコード)の順に説明していくよ。
①CardMovementについて
まずはカードに貼り付けた”CardMovement”のコードについて。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public class CardMovement : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler { public Transform cardParent; public void OnBeginDrag(PointerEventData eventData) // ドラッグを始めるときに行う処理 { cardParent = transform.parent; transform.SetParent(cardParent.parent, false); GetComponent<CanvasGroup>().blocksRaycasts = false; // blocksRaycastsをオフにする } public void OnDrag(PointerEventData eventData) // ドラッグした時に起こす処理 { transform.position = eventData.position; } public void OnEndDrag(PointerEventData eventData) // カードを離したときに行う処理 { transform.SetParent(cardParent, false); GetComponent<CanvasGroup>().blocksRaycasts = true; // blocksRaycastsをオンにする } } |
ざっくりまとめるとこんな感じ↓
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とかについての説明。
ここね↓
1 2 3 4 |
public class CardMovement : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler { (省略) } |
ここの部分にいくつか書いてあるけど、
さっき説明した“OnDrag”メソッドを使う時は”IDragHandler“書かないと使えないよ。
って認識でOK。
それぞれ以下に対応してるよ↓
【クラス名】 | 【メソッド名】 |
---|---|
IDragHandler | “OnDrag”メソッド |
IBeginDragHandler | “OnBeginDrag”メソッド |
IEndDragHandler | “OnEndDrag”メソッド |
表の右のメソッドを使うには、対応したクラスを書く必要があるってことね。
継承部分についてもう少し詳しく知りたい人はコメント下さいな。
unityengine.eventsystemsについて
最後にこれ↓
1 2 3 4 5 6 7 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public class CardMovement : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler {(省略)} |
これもすごくザックリ言うと、
さっき説明した、IDragHandlerとかを使う為に書く必要があるもの。
って認識でOK
これを書かないと使えないので書きましょう。ってだけ。
ここも詳しく知りたい人がいたらコメントくださいな。
②DropPlaceについて
次にフィールドに貼り付けたコードについての解説!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; // フィールドにアタッチするクラス public class DropPlace : MonoBehaviour, IDropHandler { public void OnDrop(PointerEventData eventData) // ドロップされた時に行う処理 { CardMovement card = eventData.pointerDrag.GetComponent<CardMovement>(); // ドラッグしてきた情報からCardMovementを取得 if (card != null) // もしカードがあれば、 { card.cardParent = this.transform; // カードの親要素を自分(アタッチされてるオブジェクト)にする } } } |
ざっくり、やってる処理としては、
《ドロップされた時の処理》→カードの親要素をアタッチしてるオブジェクトに変える
ってだけ。
なので、この”DropPlace”クラスの親要素を変更する処理をコメントアウトすると、、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; // フィールドにアタッチするクラス public class DropPlace : MonoBehaviour, IDropHandler { public void OnDrop(PointerEventData eventData) // ドロップされた時に行う処理 { CardMovement card = eventData.pointerDrag.GetComponent<CardMovement>(); // ドラッグしてきた情報からCardMovementを取得 if (card != null) // もしカードがあれば、 { // card.cardParent = this.transform; // カードの親要素を自分(アタッチされてるオブジェクト)にする } } } |
置けなくなる!!(実際にやってみてね)
と言うわけで、この処理を行う“DropPlace”クラスをアタッチしたから、カードが置けてる。ってことですな。
演習
今回は割と簡単な演習だからみんなやってみて!
【演習】
現在は自分の手札から、自分のフィールドにカードを置くことは出来るけど、
逆にフィールドから手札に戻すことは出来ない。自分のフィールドから相手のフィールドに置くことも出来ない。
ではフィールドのカードを手札に戻す、あるいは相手のフィールドに出せるようにするにはどうすれば良いか。
ヒントとしては、
コードが貼ってあるから置けるんだよ。
って話。
まあカードゲームとしては有り得ない仕様だけど、練習だと思ってやってみよう!
答え合わせ
出来たかな??
ただ単にコピペしてるだけだと全く身に付かないから、やり方を覚えながら進もうね。
んで、答えはこう↓
このふたつにDropPlaceをアタッチするだけ!!
変な仕様になっちゃうから終わったらアタッチしたのは消しといてね!!
【最後に】お詫びとか、今後について
更新がめちゃくちゃ遅くなってしまってごめんなさい!!
コメントしてくれた方々ほんとにありがとうございました!
これでもめちゃくちゃ原動力になってます。
記事を書いてる側としては、ほんとにたった一言のコメントでも力になるし嬉しいんです!
なのでほんの1mmでも応援して頂けたり、参考になったという方はぜひコメントをお願いします。
(もちろん「ここがちょっと分かりずらいよ!」などのコメントでも大丈夫です!参考にしますので!!)
その代わりと言ってはなんですが、
7月中にカードゲームの基本動作までの
解説記事を全て書いて投稿します。
(現時点で全く記事のストックとか無いけど。。笑)
具体的には下の動画で言うと、
マナコスト通りにカードを出して、
相手のカードとバトルする所までね。
(スペルカードとか、モンスター効果とかはその後に実装するよ)
ペースとしては週に2回の投稿を予定しています。
なので全10回程度の解説記事になると思います。
そして最終的には「初心者がカードゲームを作りたいなら”みじんこのブログ”を見ればいいよね」って言ってもらえるようなサイトにしたいと思ってます!
その為にはあなたのコメント一つがめちゃくちゃ力になるので、一言でもいいのでコメントの方よろしくお願いいたします!!
あと質問などあれば、お気軽にどうぞ!!!
新しい記事を投稿したタイミングとか、
ゲームについての役立ち(そうなこと)など
知りたい方はフォローして下さいな→→mijinko_game000
↑ごめん、今はTwitterは全然使ってないからいいです。笑
次の記事↓
前の記事↓
では今回は終わりっ!!
参考にさせて頂いた動画
[Unityゲーム開発講座] シャドバ風!?カードゲームの作り方 #1 UIの実装
こんにちは。
記事参考になりました。続き楽しみです。
CanvasGroupを使われてますが、AddComponentで「CanvasGroup」も追加しないといけないのではないでしょうか?
>yukiさん
コメントありがとうございます!
あ、、完全に抜けてました。
これだとエラーめちゃくちゃ出ますね。。笑
すみません、CanvasGroupの追加は必要です!!
記事に追記したのでよろしくお願いします。
また何かあったらコメントお願いしますね!
次の記事は今日か明日に出せると思うので、また見て下さい!
凄く参考になりました
Unity初なので大変助かっています
DropPlaceをPlayerHandに入れて実行したら
入れたものがなくなっている現象に見舞われて困っていましたが
実行中に入れても戻るんですね(初心者杉;
>もっけさん
コメントありがとうございます^^
確かに実行中にアタッチしたものは、実行を停止すると消えますね(笑)
困ることも多いですが、特に初心者のうちはミスすればするほど色々知れるので、
解説に無いことでも気になることはガンガン試しながら作ってみてください!(バックアップは取っておいた方が良いかも。。)
大変参考になりました.
質問がありコメントいたしました.
カードの配置に関しての質問です.すでに解説されている内容でしたら申し訳ございません.
カードをきれいに配置する方法は,記事に書いてあり,わかったのですが,
カードをもって,任意の位置に配置することは可能でしょうか?
よろしくお願い致します.
>まさきさまさん
コメントありがとうございます!
カードを固定の位置に配置する方法ですかね??(遊戯王みたいな?遊戯王やってなかったらごめんなさい。。)
恐らく色々方法はあるとは思いますが、あくまで僕が実装するんだとしたら、
今ある「PlayerField」の幅を縮めたものを5つ分作って、1枚づつカードを置けるようにしますかね~(フィールドに5体まで出せるようにする場合の話)
って説明で分かりますかね、、??
いまいち分からなかったらまたコメント下さい!
(出来た時もコメントくれたら嬉しい。笑)
お返事、感謝いたします。
わかりやすい解説ありがとうございました。
今後もよろしくお願いいたします。
いつも参考にさせて頂いてます
CardMovementのスクリプトを作成して、プログラムを記入したのに、
Add Componentをクリックして
CardMovementで検索してもCardMovementが表示されません
どういった原因が考えられますでしょうか?
>ピーロさん
コメントありがとうございます!
んー、一番多いのは、コードに書かれているクラス名が間違っていることですかね。
なので一旦、コードのクラス名と検索した時のクラス名にスペルミスが無いかを確認してみて下さい!
特に間違ってなければ、、、(´・ω・`)ナンダロウ
コードに関しての質問です。コードを映しても書くやつで参照なしとなってしまい、動きません。
どうしたらいいのでしょうか?
Logを出そうとしてもOnBeginDrag・OnDrag・OnEndDrag・OnDrop
が動きませんでした。
>ラいさん
コメントありがとうございます!
返信遅れてすみません、届いてますよ!
んー、CardMovementとDropPlaceクラスの話ですかね?
4行目の
using UnityEngine.EventSystems;
は書いてありますか?
これが書いてないと、動かないので一旦確認してみて下さい!
ちなみにコードにエラーは出てないってことでいいですよね??
アタッチは出来てない状況なんですかね、、??
>コードを映しても書くやつで参照なしとなってしまい、動きません。
あとこの”書くやつ”って言うのが分からなくてなんとも、、、
どこのことでしょうか、、(´・ω・`)ゴメンヨ
using UnityEngine.EventSystems;は書いてありますね。エラーは出てません。public void OnBeginDrag(PointerEventData eventData)などの上に普通ならUnity メッセージ□個の参照と表示されるはずなのですが、0個の参照となって動きません。ということです。わかりにくくてすみません。
>ラいさん
あー、なるほど!分かりました!
OnBeginDragメソッドなどは、メソッドを別のところから呼び出してる訳ではないので0個の参照と表示されていて問題ないです。
コードにエラーが出てないのなら、プログラムにミスはないと思います。
“動かない”とありますが、実行ボタンを押した後に、カードをドラッグしても動かないってことですかね?
Cardプレハブにアタッチはされましたか??
解説通りにアタッチしてて、動かないなら、、(-ω-)ナンダロウ、、
あと、カードがPlayerFieldの下になってしまうのはどうしたらいいでしょうか?
>ラいさん
えーと、まずカードは動くようになったってことですかね??
私としても初心者の方に分かりやすいサイトを作ろうと思ってるので、質問していただくのはむしろウェルカムなのですが、流石に「今は~という状況で、…が出来ない」「これが原因だと思って、~と~を試したけど…になってしまう」など、今の状況を詳細に説明して頂かないと答えようがないです。。
解説してる通りの動きをしてない時点で、もうどんな状況になってるのか分からないので、、
質問内容を整理してると、案外自分で解決出来たりしますし、色々分からないながらも直すのはめちゃくちゃ勉強になると思います。
(あと僕がコメントを見て答えるより、自分で頑張った方が早い場合もあると思うので。笑)
一旦、「原因は何かな??」って色々悩みながら試して、それでも解決しなかったらまたコメント下さい。
詳細を説明していただければ、力になれるかも知れないので!!
わかりました!ありがとうございます。頑張ってみます!(でもできることもうなさそう…)
すいません、今「ドラッグしたけど攻撃しなかったカードをもとの位置に戻す」というようにコードを書き換えようとしています(今だと一度クリックしたカードは必ず一番右に動いてしまうので)
考え方として、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/
できました!Imageを使わないでやってたようでした。ありがとうございます!
できました‼
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かな。笑
でもぶっちゃけコードなんて動けばいいと思ってるので気にすることなしです!笑 完璧です!!)
こちらこそいつもコメントくれるので僕も助かってますよ!
今後ともよろしくお願いしますね~
いつもありがとうございます!!3日前にUnityダウンロードしたばかりでさっそく挫けかけてましたが、こちらの記事を見ながらだと楽しく出来てます!!
カードが動くことに感動してお礼の連絡でした!!
頑張って最後まで続けたいと思います!!
>アツシさん
始めたばかりだと分からないことばっかりですよね。笑
感動してもらえて嬉しいです(*´ω`)笑
まだ完結してないですが、頑張ってください!!
初めまして!
私は高校時代にHTMLを齧っただけのスキルしかないですが、
みじんこさんの分かりやすい記事のおかけで新しい趣味が広がりそうです!
応援してます!
>りんごさん
わー、ありがとうございます、嬉しいです(*´ω`)
僕はHTMLも書けないんで、りんごさんはもっとガンガン作っていけると思います!笑
ゲーム作成はめちゃめちゃ楽しい趣味になるので、一緒にやっていきましょう!!
すみません。早速詰みました。
コードの記載(フルコピペ)、カードプレファブへのアタッチ、グループ全て記載通りで問題ないかと思いますが、プレビュー(再生ボタン)を押してからドラッグしてもカードが移動しません。手札が5枚とフィールドに5枚の計10枚ですが、どのカードも動かないです。
ここまで順調にできてたので全く原因がつかめないです。。
>りんごさん
んー、なんでしょう。。
カードの移動処理を実装してるのは、
該当記事の「③④コードの貼り付け(アタッチ)」の章の部分なので、そこはもう一度よく確認いただけますか?
特に⑤で解説してる「Canvas Group」の「Blocks Raycasts」をオンにしているかどうかを確認してみて下さい!
みじんこさん
初日の作業から1から作り直ししてみましたがやはり動かず。。お手上げです><;
何度もすみません。
解決しました!
Hierarchyタブにeventsystemフォルダがなかった(おそらく自分で消した)ことが原因だったみたいです!
これでようやく次のステップへ行けます!
お騒がせしました><;
>みじんこさん
問題なくアタッチもできていて、Blocks Raycastsもチェックされているように見えます。
私のの何かのミスかと思いますので復習かねて1からやり直してみます!
(お礼のみ)
みじんこさん、とても楽しく読ませていただいています。間違って戻っての繰り返しですが1ヶ月でようやくここまで終わりました。自作のカードゲームをリリースするために頑張っています。みじんこさんの記事はどのページよりもわかりやすくて、飽き性の私でもモチベーションを維持したまま学習できていて、本当にありがたいです。
>ネコヤナギさん
(なんかいい名前ですね笑)
コメントありがとうございます!
自作のカードゲームいいですね〜
どんなの作ってるのか見てみたいですね〜笑
リリースまで大変だと思いますが、ゲーム作るのが好きなら楽しめると思います!頑張って下さいー!
相手のカードも動かせてしまうので、動かせないようにしたいです!
どうしたらできるのでしょうか?
>じゃがすけさん
んー、bool enemyCard など作って、CardMovementに enemyCardがtrueならreturnする。という処理を書けば動かさない様に出来ますね。
もしくは解説記事⑨まで進めてもらえると相手のカードは動かせなくなるので、そこまで進めてみて下さい!
>みじんこ さん
回答ありがとうございます!後先読まずに質問しちゃってすいません(汗
解説最後まで読み進めたいと思います!
>じゃがすけさん
いえいえー!
また何か知りたいことがあったらコメントで教えて下さい(‘ω’)
趣味でUnityをはじめました。大変参考にさせていただいております。
「CardMovement.cs」について質問させてください。
OnBeginDragとOnEndDragの「SetParent」で設定している値が異なりますが、ここがいまいちわかりませんでした。
何がちがうのでしょうか?
>かなもんさん
返信めちゃくちゃ遅くなってすみません!!
これは単にカードをドラッグしている時に、
カードが他の要素の下にならないように親要素をCanvasに変更してるってだけです。笑
どっちも同じように、
OnBeginDragの方でもcardParentを親にしてカードを動かしてみると分かるかと思います!
って回答で大丈夫ですかね、、??
今回もわかりやすかったです。
毎回レッスンのあとにちゃんと自分で考える作りになっていてとてもよい(語彙力0)
コメントあざっす!(語彙力)
フィールドに出せるカードを上限五枚にするにはどうすればいいですか?
>匿名さん
フィールドにカードが5枚より少ない時に、カードを置けるようにすればいいので、
カードを置く処理のところに
if(子要素の数<5)
{カードをフィールドに置く処理}
というような分岐を書いてみると実装出来るかと思います!
調べつつ色々試してみて、それでも分からなければ、
具体的に分からない部分をまた聞いて下さいー!
3Dのタイル状にどうやったらオブジェクトをドラッグアンドドロップできるか悩んでいたので、とても参考になりました。
レイキャストの座標が入った空オブジェクトに入れるとなんとかできそうです。
このサイトの説明順序がとてもわかりやすくて助かります。
解決できました。ありがとうございます。
PlayerHandの中心部がPlayerLeaderの画像の範囲と被ってしまっていて選択できていなかったようです。
質問が送られていなかったようですね、、
変なコメントをしてしまいました。
ちなみに質問は中心部のカードのみドラッグできないというものでした。とてもわかりやすいので今後もこのサイトを参考にさせていただきます!
>うさぎさん
いえいえ、全然大丈夫ですよー!
自力で解決できたみたいで良かったです!!
また不明点あればお気軽に聞いてください( ´ ▽ ` )ノ
相手のカードをドラッグして自分のフィールドに持って来れてしまうのですが、何が原因でしょうか?
現時点ではカードに「相手のカードか自分のカードか判別するデータ」を持たせてない為、その動きで問題ないです。
解説記事を進めていくとそれも解決するので、そのまま進めていってください!
このシリーズとても参考になります!今自分で昔作ったカードゲームをパソコン上でできるようにしてみたいなーと思って頑張ってます!まずはこの記事に書いてある内容をマスターします!
>じゃすてぃそさん
コメントありがとうございます!
参考になったのであればよかったです!!(σ・∀・)σグッ
一通り内容を理解しながら進めていけば、ある程度は自分の作りたいゲームを作れるようになると思うので、楽しみながら進めてみてくださいね!
楽しくunity学ばせてもらってます。カードを動かすプログラムを実行しても、右半分のカードしか動きません。何が悪いのか見当が付きますか?
>ななしさん
んー、右半分ですか、、、正直謎ですね。
もしかしたらUnityのバグかも知れないので、一旦保存してUnityの再起動をしてみてください!
返信ありがとうございます。いろいろ試してみます。
コメント失礼します。ドラッグ、ドロップのスクリプトで記事通り作成しているつもりなのですがPlayerField、PlayerHand以外の位置にもカードを置けてしまうのです。何が間違っているのかわかりますでしょうか。
カード自体を動かすことはできます。PlayerField上にドロップすると親要素はしっかり変更されています。その状態で何もない位置にドロップすると親要素がPlayerFieldのままその位置にドロップできてしまいます。
何が原因なのでしょうか。
>たなかです。さん
んー、、正直謎ですね。。
どこにでもカードを置けてしまうということは、恐らくOnEndDragの中のSetParentが動いてない。ってことだと思います。(SetParentが動けば、何もない位置にドロップしたら絶対元の位置(親要素)に戻るので。)
ただ恐らくその後、そのカードを移動しようとするとカードがどっかに消える。って挙動になるっぽいんですよね。。その辺りの挙動を教えて貰っていいですか??
もしくは何か進捗あったら教えてください!!
気になる挙動といえばドロップするとき少し位置ずれが起こることですかね。
PlayerFieldからPlayerHandに戻そうとするとかなり下方向への位置ずれが起こって画面から消え(るように見え)ます。PlayerHandにドロップするときは画面外に出るほどの位置ずれはなく、多少下にずれるといった感じです。
>たなかです。さん
んー、明らかにちゃんと親要素を取得して、セット出来てない動きっぽいんですけどね。。位置ズレの起きたCardの親要素がHierarchie上でCanvasになってたりしませんか??
とはいえ解説通りに設定出来ていればその挙動にはならないので、分からないですね、、力になれず申し訳ない。。。m(_ _)m
親要素はしっかり変わってるんですよね。
趣味程度としての制作なのでいろいろ模索してみます。
ご迷惑おかけしました。
めちゃくちゃ参考になります!
めちゃくちゃ参考にしちゃってください!笑
質問失礼します
今第5回までの所を見終わったのですが
カードをこんな感じに複製する方法ってありますか?
https://gyazo.com/8eef69ded29fb2c9cb8203602d297a1d
自分でもやってみたのですがなかなか難しいです
単にOnBeginDragメソッドで、CreateCardすれば良いのでは??
って思いましたけど、それだけだと何故かCardIDが取得出来ないっぽいですね。。
しっかり調査すれば出来ないこともなさそうですけど、cpu532さんはもう実装出来ました??
とりあえずドラッグではなくクリックによってカードを召喚する方式にしてみました。
いろいろなサイトをみながら何とかやっていけてます!
なるほど!
ひとまず実装を進められてる様でよかったです!
色々調べてもわからなかったので、聞かせてください。
私は自分のフィールドを二つ作ったのですが、ゲームを再生(?)すると、手前側のフィールドがクリックできて、かつクリックするとエラーメッセージが出るんです。
The dropdown template is not assigned. The template needs to be assigned and must have a child GameObject with a Toggle component serving as the item.
UnityEngine.Debug:LogError (object,UnityEngine.Object)
TMPro.TMP_Dropdown:SetupTemplate () (at Library/PackageCache/com.unity.textmeshpro@3.0.6/Scripts/Runtime/TMP_Dropdown.cs:610)
TMPro.TMP_Dropdown:Show () (at Library/PackageCache/com.unity.textmeshpro@3.0.6/Scripts/Runtime/TMP_Dropdown.cs:771)
>如月ヌイさん
返信遅くなってすみません!(仕事が立て込んでたもんで、、)
とりあえず一つ目のは解決出来たみたいでよかったです!
まだちゃんと調べられてないのであんまりお答えできないですが、本記事にて解説している内容とは別のエラーっぽいですね。(Dropdown?)
まだ解決出来てないのであれば、調べてみますが現状どうですか??
(ちなみにDropdownはあんまり使ったことないんであんまり期待しないでください… orz)
質問です。
現在、手札を5枚得る。
フィールドにカードを置く。
までは出来たのですが、フィールドのカードを動かすことができません。
よろしければ、なぜこのようになっているのかわかりましたら、ご教授願いたいです、、、
すいません! できました! 謎に増えたキャンバスと、無駄に広く作ったLPに判定を吸われてました……
おー、自己解決出来たようで良かったです!
また不明点あれば聞いてくださいー!
何とか、この問題は自己解決できました。
引き続き読ませていただいてます。
質問失礼します
CardMovementのOnEndDragで
transform.SetParent(cardParent, false);
したときだけDropPlaseのOnDropが動くのはなぜでしょうか?
あー、そこは説明が足りなかったかもですね、、
OnDropメソッドは「何かしらがドロップされた時に動く」メソッドです。
※CardMovementのOnDragとかと似たようなもの。
なので、transform.SetParent(cardParent, false);した時に動いているものではないです!
こんにちは。カードの移動が上手くいかず、お助けいただきたいです・・・
演習の通りに作っているのではなく、応用して自分のゲームを作っているので、伝わりづらいところがありましたら申し訳ございません。
まず前提として、960×540の画面サイズです。
カードを手札からフィールドへドラッグした瞬間、カードの位置情報が大きく変わります。
座標480,90あたりにある手札カードを掴むと、
座標800,300あたりまでカード画像がワープするのです。
その状態のまま座標390,270あたりのフィールドへカーソルを持っていきドロップすると、座標940,270あたりにカードが表示されます。
ただ、親要素はちゃんとフィールドに変わっています。
なんとなく、本来表示したいカードの座標に、ポインタの座標分の数値が加算されているような気がします。
伝わりますでしょうか・・・
もし解決策が分かりましたら、ご教授いただけると幸いです。
宜しくお願いします。
追記です。
フィールド側にGridRayoutGroupをアタッチすることで、ドロップしたときに自動でフィールドに整列させることができました。ただ、一時しのぎのようで・・・
カードを掴んだときは変わらず、カーソルより右上の方にワープした状態で表示されます。
ドロップすれば直るという状態です。
とりあえずフィールドへのドロップができればゲームプレイ自体は可能ですので、このまま次のステップへ行こうと思います。
もし画像のワープについて心当たりがあればお助けください・・・
宜しくお願いします。
くるシュウさん
返信遅れてすみません!!
んー、、正直くるシュウさんの画面の状態がわからないのでなんとも言えないのですが、
座標指定でカードの動きを制御していないので、画面サイズの違いでカードの表示がズレることはないかと思ってます。
なんとなくCardMovementクラスの処理(特にOnDragメソッド??)でミスってる気がしますが、解説通りのコードにしたら解説通りの動きをするか確認してもらえますか??
もしくは画面キャプチャを見せて貰えたりすれば分かるかもです!(ここに載せるのはやだな、、って場合はTwitterのDMでも大丈夫です!)
CardMovement、DropPlaceのスクリプトがちゃんとアタッチされていて、CanvasGroupもちゃんとプレハブについてるのですが、実行して手札から場にカードをドラッグさせると消えてしまいます。ちゃんと内部ではデータが移動してヒエラルキーには表示されているのにです。Z軸かなと思っていじってみましたが駄目でした。Gamemanagerで、実行時に配置するとちゃんと表示され、ドラッグして手札に動かすことは問題なくできます。
コードのコピペだけでなく、中身の説明もしていただけるのでとても分かりやすいです!
質の高い記事を無料でご提供いただきありがとうございます!
toshiさん、そう言っていただけると嬉しいです!
ゲーム制作のお力になれたようで良かったです( ´∀`)