norablog-techのブログ

このブログは、自分の忘備録的にアウトプットするためのブログとなっております。

【Unity】「VRoidをUnityで動かす」#2(マテリアルの変更)【Mixamo】

youtu.be

今回はVRoideのキャラクターにVRMファイル(真っ白なモデル)のマテリアルを強引に適用します。

私もまだ勉強を始めたばかりなので、勘違いや間違いがあるかもしれませんが、ご容赦ください。

 

【Unity】「VRoidをUnityで動かす」#1(Mixamo編)【Mixamo】


www.youtube.com


前回の動画が説明を入れられなかったので、分割して少しずつ解説してみたいと思います。
今回はVRoideのキャラクターにMixamoのアニメーションを適用します。

 

私もまだ勉強を始めたばかりなので、勘違いや間違いがあるかもしれませんが、ご容赦ください。

【Unity】「VRoidをUnityで動かす」(Mixamo編)(無音・解説なし)


www.youtube.com

ソースコード(これだけです):

AnimationStateController.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AnimationStateController : MonoBehaviour
{
    Animator animator;
    int isRunningHash;
    int isFastRunningHash;
    int isJumpingHash;

    // Start is called before the first frame update
    void Start()
    {
        animator = GetComponent<Animator>();
        isRunningHash = Animator.StringToHash("isRunning");
        isFastRunningHash = Animator.StringToHash("isFastRunning");
        isJumpingHash = Animator.StringToHash("isJumping"); 
    }

    // Update is called once per frame
    void Update()
    {
        bool isRunning = animator.GetBool(isRunningHash);
        bool isFastRunning = animator.GetBool(isFastRunningHash);
        bool isJumping = animator.GetBool(isJumpingHash);
        bool runPressed = Input.GetKey("w");                // 走る
        bool fastRunPressed = Input.GetKey("left shift");   // 早く走る
        bool jumpPressed = Input.GetKey("space");           // Jumpする

        // プレイヤーが走っていない状態、かつ、"w"キーが押された場合
        if (!isRunning && runPressed)
        {
            // "isRunning"ブール値を"true"に設定(走る)
            animator.SetBool(isRunningHash, true);
        }

        // プレイヤーが走っている状態、かつ、"w"キーが押されていない場合
        if (isRunning && !runPressed)
        {
            // "isRunning"ブール値を"false"に設定(止まる)
            animator.SetBool(isRunningHash, false);
        }

        // プレーヤーが速く走っていない状態、かつ、"w"キーと"左Shift"キー両方を押した場合
        if (!isFastRunning && (runPressed && fastRunPressed))
        {
            // "isFastRunning"ブール値を"true"に設定(早く走る)
            animator.SetBool(isFastRunningHash, true);
        }

        // プレーヤーが速く走っていない状態、かつ、"w"キー、または、"左Shift"キー、どちらかが"押されていない"場合
        if (isFastRunning && (!runPressed || !fastRunPressed))
        {
            // "isFastRunning"ブール値を"false"に設定(早く走るのをやめる。走るか、止まるかは押されているキー次第)
            animator.SetBool(isFastRunningHash, false);
        }

        // プレーヤーがJumpしていない状態、かつ、スペースキーが押された場合
        if (!isJumping && jumpPressed)
        {
            // "isRunning"ブール値を"true"に設定(Jumpする)
            animator.SetBool(isJumpingHash, true);
        }

        // プレーヤーがJumpしている状態、かつ、スペースキーが押されていない場合
        if (isJumping && !jumpPressed)
        {
            // "isRunning"ブール値を"false"に設定(Jumpをやめる)
            animator.SetBool(isJumpingHash, false);
        }
        
    }
}

 

 

【Unity】「VRoidをUnityで動かす」(Mixamo編)(作りかけ)


www.youtube.com

 

※ごめんなさい。作りかけです。この夏体調を崩して、しばらく作業ができませんでした。
 まだしばらく作業が出来そうにないので、とりあえず出来ているところまで公開しておきたいと思います。
 肝心のUnityとMixamoのAnimetionの組み込み部分の動画が、編集できていないません。
 Unityのアニメーターというウィンドウで、組み込みます。
 UnityとMixamoのキーワードで探せば、もっとわかりやすい動画が、YouTubeで見つかるかと思います。

【Unity】得点表示と終了処理

このブログは、自分が学んだこと、調べたことをアウトプットするために忘備録的に残しているブログとなっております。
間違った情報や私の勘違いなどをお伝えしてしまうこともあるかと思います。
そこのところをご理解いただき、ご覧ください。
また、間違いや勘違いについて、ご指摘ご鞭撻いただければ幸いです。

 

今回は、得点の表示とゲームオーバーの表示、およびそれらの処理を行います。


www.youtube.com

 

得点とゲームオーバー時の表示を設定する。
1.UI(TextMeshPro)の追加
ヒエラルキー上を右クリックし、
・Score
・GameOver
・Select
 の3つの"テキスト-TextMeshPro"を作成・追加します。

f:id:NoraBlog:20220210042233p:plain

TextMeshProの追加

2.表示位置、フォントサイズ、その他の調整

インスペクターで調整します。

・Score

f:id:NoraBlog:20220210044711p:plain

Scoreの設定

- アンカー:画面左上

- 位置:X 10 Y -10 (少し画面端から離す)

- 幅:200 高さ:30 (表示内容に合わせるとよい)

- Text Input:Score:0000 (スクリプトで初期化します)

- Font Size:24 (画面の大きさに合わせる感じで)

- Alignment:左詰め 上詰め

- Wrapping:Disabled

- Overflow:Overflow

 

f:id:NoraBlog:20220210045044p:plain

アンカープリセット

※Shift + Altを押しながらクリックします。

 

・GameOver

f:id:NoraBlog:20220210053020p:plain

GameOverの設定

- アンカー:画面中央

- 位置:X 0 Y 0

- 幅:300 高さ:40 (表示内容に合わせるとよい)

- Text Input:Game Over (スクリプトで初期化します)

- Font Style:B(Bold)

- Font Size:36 (画面の大きさに合わせる感じで)

- Alignment:中央揃え 中央揃え

- Wrapping:Disabled

- Overflow:Overflow

 

・Select

f:id:NoraBlog:20220210053801p:plain

Selectの設定

- アンカー:画面中央

- 位置:X 0 Y -50

- 幅:300 高さ:30 (表示内容に合わせるとよい)

- Text Input:Q->QUIT Space->Replay  (スクリプトで初期化します)

- Font Size:24 (画面の大きさに合わせる感じで)

- Alignment:中央揃え 中央揃え

- Wrapping:Disabled

- Overflow:Overflow

 

2.スクリプト

GameController.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;    //TextMeshProを使うのに必要
using UnityEngine.SceneManagement;  //Scene01を再読み込みするのに必要

//UnityEditorで作成中の場合有効にする
#if UNITY_EDITOR
using UnityEditor;
#endif

public class GameController : MonoBehaviour
{
    //敵機をGameObjectとして宣言する
    public GameObject CirclePreFab;
    //得点、表示する文言、ゲームの状態を表す変数を定義
    private int score;
    public TextMeshProUGUI scoreText;
    public TextMeshProUGUI gameOverText;
    public TextMeshProUGUI selectText;
    private bool isGameOver;

    // Start is called before the first frame update
    void Start()
    {
        //GenerateCircle()を開始する
        StartCoroutine("GenerateCircle");
        //変数の初期化、表示のクリア
        score = 0;
        UpdateScoreText();
        gameOverText.text = "";
        selectText.text = "";
        isGameOver = false;
    }

    // Update is called once per frame
    void Update()
    {
        //ゲームオーバー状態になれば、
        if (!isGameOver)
        {
            return;
        }
        //以下を実行する。
        if (Input.GetKey(KeyCode.Space))
        {
            SceneManager.LoadScene("Scene01");  //Scene01を再読み込み、初めからプレイ
        }
       //
        if (Input.GetKey(KeyCode.Q))
        {
#if UNITY_EDITOR
            EditorApplication.isPlaying = false;    //下記メソッドを作成中に実行させるための条件設定。
#else
            Application.Quit();     //アプリケーションの終了。本来作成中は、このメソッドは実行されない。
#endif
        }
    }

    //敵機(Circle)を生成する
    IEnumerator GenerateCircle()
    {
        while (true)
        {
            Instantiate(
                CirclePreFab,
                //X軸方向はランダム、Y軸方向6.0f、Z軸方向0.0fに敵機を生成
                new Vector3(Random.Range(-8.5f, 8.5f), 6.0f, 0.0f),
                transform.rotation
            );
            //1秒ごとに実行する。
            //yield return new WaitForSeconds(1.0f);
            //変更
            yield return new WaitForSeconds(Random.value * 2.0f);
        }
    }

    //得点の加算
    public void AddScore(int addScore)
    {
        score += addScore;
        UpdateScoreText();
    }
    //得点の表示更新
    public void UpdateScoreText()
    {
        scoreText.text = "Score:" + score;
    }
    //ゲームオーバー時の処理
    public void GameOver()
    {
        isGameOver = true;
        gameOverText.text = "GameOver";
        selectText.text = "Q->QUIT Space->Replay";
    }
}

 

 

CirclePreFabController.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CirclePreFabController : MonoBehaviour
{
    //GameObjectの宣言
    public GameObject circleexplosion;
    public GameController gameController;   //GameControllerのゲームオブジェクト

    // Start is called before the first frame update
    void Start()
    {
        //あらかじめGameControllerのゲームオブジェクトを取得しておく
        gameController = GameObject.FindWithTag("GameController").GetComponent<GameController>();
    }

    // Update is called once per frame
    void Update()
    {
        transform.position += new Vector3(
                0f,
                -0.5f * Time.deltaTime,
                0f
            );
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.CompareTag("Bullet"))  //Tagが"Bullet"だったら
        {
            Instantiate(circleexplosion, transform.position, transform.rotation);  //追記 爆発エフェクト
            Destroy(collision.gameObject);  //ぶつかったもの(Bullet)
            Destroy(gameObject);            //gameObject:自分(Circle)自身
            gameController.AddScore(10);    //gameController.AddScore()の呼び出し。10点加算する

        }

        if (collision.gameObject.CompareTag("Diamond"))  //Tagが"Diamond"だったら
        {
            gameController.GameOver();  //gameController.GameOver()の呼び出し
            Instantiate(circleexplosion, transform.position, transform.rotation);
            Destroy(gameObject);            //gameObject:自分(Circle)自身
        }

    }

}

 

 

はなはだ簡単ではありますが、今回で終了です。

 

【Unity】自機に消滅のエフェクトをつける。

このブログは、自分が学んだこと、調べたことをアウトプットするために忘備録的に残しているブログとなっております。
間違った情報や私の勘違いなどをお伝えしてしまうこともあるかと思います。
そこのところをご理解いただき、ご覧ください。
また、間違いや勘違いについて、ご指摘ご鞭撻いただければ幸いです。

 

今回は、自機の消滅・爆発のエフェクトをつけます。


www.youtube.com

 

まず、"衝突判定"に必要な設定を自機(Diamond)にを加えます。
1.「ヒエラルキー」の"Diamond"をクリックし、"インスペクター"の"コンポーネントを追加"より、"Rigidbody 2D"を追加します。
 物理演算は使わないので、"ボディタイプ"を"キネマティック"に変更します。

 

2."Circle Collider 2D"を追加します。
 "コライダーの編集"をダブルクリックすると、"Collider"の範囲が表示されます。
 今回は"半径"を"0.2"、"オフセット"を"Y -0.1"に設定しました。

f:id:NoraBlog:20220127082321p:plain

Diamondのインスペクター

次に、前回と同じように"爆発のエフェクト"を作成し、自機に設定します。

3.爆発用画像をプロジェクトにドラッグアンドドロップします。

f:id:NoraBlog:20220127082656p:plain

Sprites

4.アニメーション化したいスプライトをまとめて、「ヒエラルキー」に登録。
 この時、元画像の"Daiamond"はアニメーションに含めないほうが良いです。
 名称がごちゃごちゃになってしまい、分かりにくくなります。

 名称は"DaiamondExplosion.anim"、"DaiamondExplosion.controller"としました。
 両方とも「Animations」ホルダーに移動して置きます。

f:id:NoraBlog:20220127082755p:plain

Animations

5."DaiamondExplosion.anim"はループさせる必要はないので、「インスペクター」内の"時間をループ"のチェックは外します。

f:id:NoraBlog:20220127082919p:plain

インスペクター

6.「ヒエラルキー」上の名前を"DaiamondExplosion"に変更します。
 「PreFabs」フォルダーにドラッグアンドドロップしてPreFab化します。
 「ヒエラルキー」上の"DaiamondExplosion"は削除します。

f:id:NoraBlog:20220127083208p:plain

Prefabs

7.「PreFabs」フォルダー内の"DaiamondExplosion.prefab"をクリック、「インスペクター」内の"タグ"に"DaiamondExplosion"を作成して登録します。
 必ずしも必要はないようですが、Tagを必ず付けるようにしました。
 さらに"コンポーネントを追加"から、"New Script"->"DaiamondExplosionController.cs"を作成します。

※2.参照

 

8."DaiamondExplosionController.cs"に以下を追加します。

DaiamondExplosionController.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DiamondExplosion : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {

   //追加
        Destroy(gameObject, 1.0f); //gameObject:自分(DiamondExplosion)自身 1.0secディレイ(待って)で自身を破壊
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

 

9.「Spritsフォルダー」内の"DiamondController.cs"をクリックして編集します。

DiamondController.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DiamondController : MonoBehaviour
{
    //GameObjectの宣言
    public GameObject bulletprefab; 
    public GameObject diamondexplosion; //追加

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    //"Input.GetAxis":Horizontal と Vertical: w、a、s、d と矢印キー
    //"Time.deltaTime":現在のフレームと前のフレームの間の時間を提供。
    //GameObjectを1秒あたりの単位でその方向に移動します。
    //"Mathf.Clamp":与えられた最小 float 値と最大 float 値の範囲に値を制限します。
    //"transform.position":3D world space.(ワールド座標:画面内の絶対的位置)
    void Update()
    {
        float dx = Input.GetAxis("Horizontal") * Time.deltaTime * 4f;
        float dy = Input.GetAxis("Vertical") * Time.deltaTime * 4f;

        transform.position = new Vector3(
                Mathf.Clamp(transform.position.x + dx, -8.5f, 8.5f),
                Mathf.Clamp(transform.position.y + dy, -4.5f, 4.5f),
                0f
            );

        //Spaceキーを叩くたびに呼び出す。
        if (Input.GetKeyDown(KeyCode.Space))  
        {
            Shoot();
        }
    }

    //弾を撃つ関数
    private void Shoot() 
    {
        //Diamond(Player機)の中心位置から撃つ
        Instantiate(bulletprefab, transform.position, transform.rotation);
    }

    //追記
    //自機(プレイヤー機)の爆発
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.CompareTag("Circle"))  //Tagが"Circle"だったら
        {
            Instantiate(diamondexplosion, transform.position, transform.rotation); //自機の爆発エフェクト表示
            Destroy(gameObject);            //gameObject:自分(Diamond)自身
        }
    }
}

10.「ヒエラルキー」の"Daiamond"をクリックして"インスペクター"を表示すると、"DiamondController(スクリプト)"に"DaiamondExplosion"の項目が増えています。
 そこに「PreFabs」フォルダー内の"DaiamondExplosion.prefab"をドラッグアンドドロップします。

※2.参照

 

11.さらに、敵機(Circle)もぶつかると同時に爆発させたいので、"CirclePreFabController.cs"にも変更を加えます。

CirclePreFabController.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CirclePreFabController : MonoBehaviour
{
    //GameObjectの宣言
    public GameObject circleexplosion; 

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        transform.position += new Vector3(
                0f,
                -0.5f * Time.deltaTime,
                0f
            );
    }

    //追記
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.CompareTag("Bullet"))  //Tagが"Bullet"だったら
        {
            Instantiate(circleexplosion, transform.position, transform.rotation);  //爆発エフェクト
            Destroy(collision.gameObject);  //ぶつかったもの(Bullet)
            Destroy(gameObject);            //gameObject:自分(Circle)自身
        }

        //追加
        if (collision.gameObject.CompareTag("Diamond"))  //Tagが"Diamond"だったら
        {
            Instantiate(circleexplosion, transform.position, transform.rotation);
            Destroy(gameObject);            //gameObject:自分(Circle)自身
        }

    }

}

12.ここまでの作業をセーブして、ゲームを起動して確認します。
 ・Unityのコンソールにエラーが出てないこと。
 ・Daiamondに弾が当たると爆発のエフェクトが表示され、消滅すること

 

自機が爆発したままで、中途半端になりますが、ゲームの終了処理は次回以降で。

今回はここまで。

 

【Unity】敵機に消滅のエフェクトをつける。

前書き:
このブログは、自分が学んだこと、調べたことをアウトプットするために忘備録的に残しているブログとなっております。
間違った情報や私の勘違いなどをお伝えしてしまうこともあるかと思います。
そこのところをご理解いただき、ご覧ください。
また、間違いや勘違いについて、ご指摘ご鞭撻いただければ幸いです。

 

今回は、敵機の消滅のエフェクトをつけます。


www.youtube.com

 

1.前回作成の爆発用画像をプロジェクトの「Sprites」にドラッグアンドドロップします。

f:id:NoraBlog:20220126085633p:plain

Sprites

2.アニメーション化したいスプライトをまとめて、「ヒエラルキー」に登録。
 この時、元画像の"Circle"はアニメーションに含めないほうが良いです。
 名称がごちゃごちゃになってしまい、分かりにくくなります。

 名称は"CircleExplosion.anim"、"CircleExplosion.controller"としました。
 両方とも「Animations」ホルダーに移動して置きます。

f:id:NoraBlog:20220126085815p:plain

Animations

3."CircleExplosion.anim"はループさせる必要はないので、「インスペクター」内の"時間をループ"のチェックは外します。

f:id:NoraBlog:20220126085924p:plain

インスペクター

4.「ヒエラルキー」上の名前を"CircleExplosion"に変更します。
 「PreFabs」フォルダーにドラッグアンドドロップしてPreFab化します。
 「ヒエラルキー」上の"CircleExplosion"は削除します。

f:id:NoraBlog:20220126090036p:plain

PreFabs

5.「PreFabs」フォルダー内の"CircleExplosion.prefab"をクリック、「インスペクター」内の"タグ"に"CircleExplosion"を作成して登録します。
 必ずしも必要はないようですが、Tagを必ず付けるようにしました。
 さらに"コンポーネントを追加"から、"New Script"->"CircleExplosion.cs"を作成します。

f:id:NoraBlog:20220126090251p:plain

インスペクター

6. Scriptに以下のように追加します。

CircleExplosion.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CircleExplosion : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Destroy(gameObject, 0.5f);  //gameObject:自分(CircleExplosion)自身 0.5secディレイ(待って)で自身を破壊
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

 

CirclePreFabController.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CirclePreFabController : MonoBehaviour
{
    //GameObjectの宣言
    public GameObject circleexplosion; //追加

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        transform.position += new Vector3(
                0f,
                -0.5f * Time.deltaTime,
                0f
            );
    }

    //追記
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.CompareTag("Bullet"))  //Tagが"Bullet"だったら
        {
            Instantiate(circleexplosion, transform.position, transform.rotation);  //追記 爆発エフェクト
            Destroy(collision.gameObject);  //ぶつかったもの(Bullet)
            Destroy(gameObject);            //gameObject:自分(Circle)自身
        }
    }

}

 

7."CirclePreFab"の「インスペクター」内の"CirclePreFabController(スクリプト)"の"CircleExplosion"の項目に「PreFabs」フォルダー内の"CircleExplosion.prefab"をドラッグアンドドロップします。

f:id:NoraBlog:20220126090622p:plain

インスペクター

8.ここまでの作業をセーブして、ゲームを起動して確認します。
 ・Unityのコンソールにエラーが出てないこと。(7.を忘れがちです)
 ・Circleに弾が当たると爆発のエフェクトが表示され、消滅すること。

 

今回はここまで。