Unity2Dにおいてカードゲームの制作をしているのですが、自分のターン中に相手の手札のカード領域に対してドラッグできないように、また逆に相手のターン中に自分の手札のカード領域に対してドラッグできないようなスクリプトを書きたいのですがどうにも上手くいきません。
最終的に想定しているカードゲームの簡単な説明ですが、
プレイヤーが一つのフィールドにカードを出していくタイプのものです。
プレイヤーのターン開始
コストを支払ってカードをフィールドに出す
フィールドに出したカードの効果が処理される
処理されたカードは廃棄される(ここはまだ未実装)
ターンエンドで相手のターンに
以降HPが0になるまでこれの繰り返し
該当箇所のcsはほぼ下の3つになります
CardController.cs
C#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class CardController : MonoBehaviour 6{ 7 public CardModel model; //カードの情報 8 public CardMovement movement; //CardMovement.cs扱えるように 9 10 private void Awake() 11 { 12 movement = GetComponent<CardMovement>(); //CardMovementクラスの取得 13 } 14}
CardMovement.cs///カードのドラッグに関する処理のスクリプト
C#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.EventSystems; 5 6public class CardMovement : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler 7{ 8 public Transform defaultParent; 9 public bool isDraggable; //ドラッグ可能かどうか。これを使ってどうにか実装できないか考えていた 10 11 public void OnBeginDrag(PointerEventData eventData) 12 { 13 defaultParent = transform.parent; 14 transform.SetParent(defaultParent.parent, false); 15 GetComponent<CanvasGroup>().blocksRaycasts = false; 16 } 17 18 public void OnDrag(PointerEventData eventData) 19 { 20 Vector3 cardPos = Camera.main.ScreenToWorldPoint(eventData.position); 21 cardPos.z = 0; 22 transform.position = cardPos; 23 } 24 25 public void OnEndDrag(PointerEventData eventData) 26 { 27 transform.SetParent(defaultParent, false); 28 GetComponent<CanvasGroup>().blocksRaycasts = true; 29 } 30 } 31
DropPlace.cs///カードのドロップに関する処理のスクリプト
C#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.EventSystems; 5 6public class DropPlace : MonoBehaviour, IDropHandler 7{ 8 public enum TYPE //手札のカードかフィールドか ここにEHAND(敵の手札)を追加して実装できないかどうかも考えた 9 { 10 HAND, 11 FIELD, 12 } 13 public TYPE tips; 14 public void OnDrop(PointerEventData eventData) 15 { 16 if (tips == TYPE.HAND) //手札の範囲内でドラッグした時にカードのコスト(soul)を消費しないようにしている 17 { 18 return; 19 } 20 CardController card = eventData.pointerDrag.GetComponent<CardController>(); //ドラッグされてきたカードのデータ 21 if (card != null) //もしカードが重なっているなら 22 { 23 if (card.model.soul > GameManager.instance.playerSoul && GameManager.instance.isPlayerTurn == true) 24 { 25 return; 26 //GameManager.csにあるbool関数のisPlayerTurnで自分のターンであるかを判定している 27 //自分のターンに受け取ったカードのコスト(soul)が、自分の所持しているコストよりも大きいなら 28 //コストが不足しているためカードのドロップが出来ないようにしている。 29 } 30 else if (card.model.soul > GameManager.instance.enemySoul && GameManager.instance.isPlayerTurn == false ) 31 { 32 return; 33 //上と逆で相手ターンにコスト不足ならドロップ出来ないようにしている 34 } 35 card.movement.defaultParent = this.transform; //ドロップされたときにdefaultParentをドロップした箇所に設定している 36 card.model.isFieldCard = true; //ドロップされる場所はFieldなので、ドロップされたCardModel.csにあるbool関数のisFieldCardをtrueにすることでFieldに置かれているフィールド上のカードですよという状態にする 37 } 38 } 39} 40
かなり長文になるので必要部分だけを切り取ってCardModel.csとGameManager.csの方も掲載します
CardModel.cs
C#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class CardModel 6{ 7 public string name; 8 public int soul; 9 ... 10 ... 11 public bool isFieldCard; //ここでisFieldCardを付けています 12}
C#
1using System; 2using System.Collections; 3using System.Collections.Generic; 4using UnityEngine; 5using UnityEngine.UI; 6 7public class GameManager : MonoBehaviour 8{ 9 public bool isPlayerTurn; //プレイヤーのターンかどうかの確認するため 10 ... 11 ... 12 void Start() 13 { 14 StartGame(); 15 } 16 void StartGame() 17 { 18 ... 19 ... 20 isPlayerTurn = true; //最初はプレイヤーのターンなのでtrueにしておく 21 TurnCalc(); 22 } 23 void TurnCalc() //ターンを切り替える処理 24 { 25 if (isPlayerTurn == true) 26 { 27 PlayerTurn(); //プレイヤーのターン処理をする 28 } 29 else 30 { 31 EnemyTurn(); //エネミーのターン処理をする 32 } 33 } 34 public void ChangeTurn() //ターンチェンジ処理、ボタンにアタッチしてクリックで切り替えしている 35 { 36 isPlayerTurn = !isPlayerTurn; //もしプレイヤーのターンなら否定になるのでエネミーターンに、逆の場合も 37 if(isPlayerTurn == true) 38 { 39 playerSoul = playerMaxSoul; //コスト回復処理みたいなものなので今回の質問には関係ないです(多分) 40 ShowSoul(); //そもそも書いてある内容がここにはこれだけなので一応載せました 41 } 42 else 43 { 44 enemySoul = enemyMaxSoul; //上に同じく 45 ShowSoul(); 46 } 47 TurnCalc(); //ターンが移ったらターン開始の処理が行われる 48 } 49 void PlayerTurn() //上下ともTurnCalc()で切り替わる時のターン処理 50 { 51 Debug.Log("Playerのターン"); //現在は特に何も書くことがないので切り替わってるかだけ確認しています 52 } 53 void EnemyTurn() 54 { 55 Debug.Log("敵のターン"); //上に同じく 56 } 57... 58... 59} 60
これでおそらく必要部分のスクリプトは掲載出来ているかと思います。
またカードの手札領域やフィールドですが、UIとしてそれぞれの領域にパネルを配置しています。
ゲーム画面は流石に載せられないのですが、ドロー関連のスクリプトを置いておきます
これは殆ど質問内容には関係ありませんが[SerializeField]でplayerHandTransformにはプレイヤーの手札となるパネルの領域をヒエラルキーからインスペクターにドロップして設定して~といった形で作っています
Draw.cs
c#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Draw : MonoBehaviour 6{ 7 [SerializeField] Transform playerHandTransform = default; 8 [SerializeField] Transform enemyHandTransform = default; 9 [SerializeField] CardController cardPrefab = default; 10 11 List<int> playerDeck = new List<int>() { 1, 3, 2, 2, 1 }; 12 List<int> enemyDeck = new List<int>() { 2, 2, 1, 1, 2 }; 13 14 public void PlayerDrow() 15 { 16 GiveCardToHand(playerDeck, playerHandTransform); 17 } 18 public void EnemyDrow() 19 { 20 GiveCardToHand(enemyDeck, enemyHandTransform); 21 } 22 23 public void GiveCardToHand(List<int> deck, Transform hand) 24 { 25 if (deck.Count == 0) 26 return; 27 } 28 int cardID = deck[0]; 29 deck.RemoveAt(0); 30 CreateCard(cardID, hand); 31 } 32 void CreateCard(int cardID, Transform hand) 33 { 34 CardController card = Instantiate(cardPrefab, hand, false); 35 card.Init(cardID); 36 } 37 38} 39
現在コメントアウトで説明している機能に関しては全て実装できていて、ドラッグの制限をかける機能だけがどうやっても実装できません。
長くなりましたのでもう一度実装したい内容なのですが
**
・自分のターン中(isPlayerTurn==true)の場合は相手の手札をドラッグできないように
・相手のターン中はその逆に
・フィールドもドロップできるだけにしておかないと相手のターン中にフィールドに出したカードを自分がドラッグ出来てしまうバグが起きるかもしれないのでその可能性?についてもお願いしたいです。(↑で相手の手札に加えてフィールドもドラッグできないようにすれば解決するかも?)
**
試したこと
DropPlace.cs内のenumのTYPEにEHAND(敵の手札)を追加
CardController.csに public DropPlace drop;
Awake()内に
drop = GetComponent<DropPlace>();で movementのようにクラスを取得させ
CardMovement.csのOnBeginDrop()内で
CardController card = GetComponent<CardController>();
if (GameManager.instance.isPlayerTurn == true) //もしプレイヤーのターンなら
{
if (card.drop.tips == DropPlace.TYPE.EHAND) //動かそうとするカードのdrop.tipsのTYPEがEHAND(敵の手札の場合)
{
isDraggable = false; //ドラッグを不可能にする
}
}
や、そもそも別のドラッグに関連するスクリプトを書いて、その中でenumでHANDの区別をつけるようにしてアタッチしてみたりもしたのですが上手くいかず、どうすればいいのか混乱している状態です。
宜しくお願いします。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/10/29 04:00