【Unity】カードを裏返したりめくる動作を実装する

Unity

Unity初心者です。

現在2Dでシャドバースとかハースストーンっぽいカードゲームを作っているのですが、初心者故にかなり苦戦しています。

実装したソースなどを備忘録としてブログに書いていきたいと思います。

裏返されたカードをアニメーション付きでめくる動作

Unityでカードゲームを作成するに当たり、裏返されたカードをめくる動作はかなりの確率で必須になります。

特に相手がいる場合ですと、相手の手札が丸見えというわけにはいかないと思うので、裏側表示にする必要があります。

クリックで単純に裏側の画像から表画像に変更をしてもよいのですが、一瞬で変わると味気ないため、アニメーションを付けてみることにしました。

↓こんな感じでアニメーション付きでカードをオープンさせます。

カードをめくる動作を実装したソース

早速ですが実装したソースは以下になります。とりあえずカードを回転させるところです。

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


public class a : MonoBehaviour
{
    private Image img;
    private Sprite ura;
    private Sprite omote;
    void Start()
    {
        img = GetComponent<Image>();
        // 裏面の画像(Assets/Resource/Sprites/ura.png)
        ura = Resources.Load<Sprite>("Sprites/ura");

        // 表面の画像
        omote = Resources.Load<Sprite>("Sprites/omote");

        // 最初は裏面を表示する
        img.sprite = ura;

        cardOpen(100f);
    }

    void Update()
    {
        
    }

    public async Task cardOpen(float speed)
    {
        float angle = -180f;
        transform.SetAsFirstSibling();

        //回転させる
        while (angle < 0f)
        {
            angle += speed * Time.deltaTime;
            transform.eulerAngles = new Vector3(0, angle, 0);
            await Task.Delay(TimeSpan.FromSeconds(0.01f));
        }

        transform.eulerAngles = new Vector3(0, 0, 0);
    }
}

コルーチンのほうがスマートな気がしましたが、async/awaitで記載をしてみました。

例えば遊戯王の「トラップカードオープン!!」とかの場合だと、カードが実際に見えるまで次の処理にいきたくないので、コルーチンでcallBackするなら、async/awaitで良いかなと。

これでcardopenメソッドを呼べばカードをめくることが出来ます。

参考にしたサイト

【Unity】カードを回転させてめくる動作を実装する - Qiita
カードゲームといえば、裏になってるカードを捲って表にする動きを実装したいですよね。そんな時に使える方法を紹介します。 概要 uGUIでもtransformを回転させればGameObjectを回転させられます。 そこで、カードのG...

カードの表面を変更する

これだとただ回転をさせているだけなので、カードの表面を変更します。

いろいろ調べてみたけど「カードのGameObjectが90度回転した時点で表面を差し替えるべき」という内容しかなかったのでそのとおりに実装します。

ループの中で画像を判定しているのは無駄に思えますが、関数の引数によって裏返すのかめくるのかをスマートに制御したかったのでここに入れました。

(変更がなければ多分処理負荷もないはずなので、まあ良いかなあと思いました。)

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


public class a : MonoBehaviour
{
    private Image img;
    private Sprite ura;
    private Sprite omote;
    void Start()
    {
        img = GetComponent<Image>();
        // 裏面の画像
        ura = Resources.Load<Sprite>("Sprites/back");

        // 表面の画像
        omote = Resources.Load<Sprite>("Sprites/huti2");

        // 最初は裏面を表示する
        transform.eulerAngles = new Vector3(0, 0, 0);

        cardOpen(100f, true);
    }

    public async Task cardOpen(float speed, bool toOmote)
    {
        float angle = -180f;
        transform.SetAsFirstSibling();

        //回転させる
        while (angle < 0f)
        {
            if (angle >= -90f)
            {
                img.sprite = toOmote ? omote : ura;
            }
            else
            {
                img.sprite = toOmote ? ura : omote;
            }
            angle += speed * Time.deltaTime;
            transform.eulerAngles = new Vector3(0, angle, 0);
            await Task.Delay(TimeSpan.FromSeconds(0.01f));
        }

        transform.eulerAngles = new Vector3(0, 0, 0);
    }
}

コメント

タイトルとURLをコピーしました