Unityでキャラクターを動かす方法

Unityでキャラクターアニメーションの表示を行い、キーボード操作でアニメーションを変化させるスクリプトを組み込んでみます。
今回使用する環境は以下の通りです。

目次

作成手順

アニメーションデータ準備

今回使用するキャラクターアニメーションテンプレートを下記ページより ダウンロードします。

「ダウンロード」を押すと、OPTPiX_SpriteStudio_Animation_Template_20180220.zip というファイルがダウンロードされるので展開します。

今回は、展開したファイルを
E:¥SpriteStudioData¥OPTPiX_SpriteStudio_Animation_Template
に保存して説明を行います。

新しくプロジェクトを作成

Unityを開き、Fileメニューから「New Project」を選択し、新しくプロジェクトを作成します。SS6Player for Unity をセッティング
SS6Player for Unity をプロジェクトに加えます。
詳しい方法は「Unityにアニメーションを表示する」を参照してください。

フォルダを準備

1.キャラクターコントロールに使用するデータ、スクリプトを入れるフォルダを設けます。
Projectウィンドウを右クリックし、コンテキストメニューの「Create」→「Folder」でフォルダを作成します。

今回は Assets フォルダの下に Sample という名称でフォルダを作成しました。

2.このフォルダに、スクリプトを納めるフォルダと、リソースを納めるフォルダを作成します。
今回は以下の名前のフォルダを作成しています。

  • Resources
    リソースを納めます
  • Script
    スクリプトを納めます

リソースを納めるフォルダの綴りに気を付けましょう。「Resources」に格納されているデータを参照する仕様になっているためです。
フォルダ名に誤りがあるとインポートしたアニメーションを参照できず、NULLエラーが発生します。

sspjインポート

再生したいsspjをインポートします。
インポートの詳しい手順は「Unityにアニメーションを表示する」の下記項目を参照してください

1.インポート先は、先程準備した
Assets/Sample/Resources
を指定します。
2.Tools > SpriteStudio6 > Importer を選択して
Import Mode 「SpriteStudio6 Player」を選択します。

3.「Import」を押して、指定するファイルは前項でダウンロードしたサンプル内

E:SpriteStudioDataOPTPiX_SpriteStudio_Animation_Templatecharacter_sample1

フォルダーにある character_sample1.sspj を指定します。

インポートに成功すると
character_sample1
が登録されます。

スクリプト作成

次にキャラクターを制御するスクリプトを準備します。

1.Projectウィンドウを右クリックし、コンテキストメニューの「Create」→「C# Script」でスクリプトを作成します。
2.今回は「CharacterControl」という名称のスクリプトを作成しました。

準備したスクリプトにキャラクター制御について記載します。
今回使用したスクリプトは「スクリプト解説」の項に掲載しています。
スクリプトについては、コピーして貼り付けていただくだけで各種設定可能になります、準備してから次の項目へ進むようお願いします。

キャラクター制御の準備

1.GameObject作成
Hierarchy ウィンドウのコンテキストメニューを開いて、Create Emptyを選択、空のGameObjectを作成します。
2.名称変更
今回は名前を分かりやすくするため、クリックして名称を「CharacterControlObject 」に変えます。
3.スクリプトセット
Assets/Sample/Scriptを開き、先ほど作成した CharacterControl スクリプトをドラッグして、Hierarchy ウィンドウ の CharacterControlObject へドロップします。

設定方法は、ドラッグ&ドロップ以外に下記の方法もあります

  1. Hierarchy ウィンドウ の CharacterControlObject をクリック
  2. Inspectorへ表示された Add Component をクリック
  3. 開いたプルダウンメニューから Scripts を選択
  4. CharacterControl を選択
4.アニメーション数の設定
スクリプトが設定されると Inspector に「Size」を設定する項目が追加されます。
これはスクリプトで使用するssaeデータを設定する枠数を示します。
今回は 1つ使用しますので、「1」と入力してください。
5.Select Object ウィンドウを開く
「Element 0」の欄に使用するアニメーションの prefab を設定します。
Element 0 欄の端にある を押して Select Object ウィンドウを開いてください。
6.アニメーションのprefabを設定
使用する character_template_3head を選択してウィンドウを閉じます。
を設定してください。
7.設定確認
下記のように選択した prefab が設定されていたら完了です。
prefab の設定は PrefabAnimation にある prefab を直接 ドラッグ&ドロップすることで設定も可能です。

これでキャラクター制御の準備が完了しました。

カメラの確認

SS6Player for Unity をセッティングする際に、アニメーションが表示されるカメラ調整済の場合は、本項目の手順はスキップしてください。

1.Main Camera を選択
Hierarchy ウィンドウにて Main Camera を選択してください。
2.Inspector を確認
初期状態は下記のようになっていると思います。
このままではアニメーションが見えない状態のため調整します。
3.Transform の Position 変更
Position の Z を今回は -600 に設定しました。
これでアニメーション再生時に表示されるようになります。

キャラクターを動かす

インポートしたssaeとスクリプトが動作するか確認します。

1.作成したものを動かします。
▶を押して動作させます。

2.スクリーン中央に「PRESS SPACE」と表示されます。
スペースキーを押してください。
3.中央にキャラクターが表示されます。
4.矢印キーで左右に走って移動。
Zキーでアタックのアニメーションが再生されます。
5.動作を確認して完了です。
スクリプトを変更して、他のアニメーションを再生することも可能です。
下記のスクリプト解説を参考に試してみてください。

スクリプト解説

今回組み込んだスクリプトについて解説します。
スクリプトについては、できるだけシンプルに記述しています。
SpriteStudio のデータを組み込み、制御する際の参考にしていただけると幸いです。

CharacterControl.cs

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

public class CharacterControl : MonoBehaviour {

    // 再生アニメーションのResourcesフォルダ内のサブパス
    [SerializeField]
    public Object[] AnimationList;

    // 再生アニメーション指定用 
    private enum AnimationPattern : int
    {
        Wait = 33,      // 待機
        Attack = 1,     // 攻撃 
        Run = 24,       // 走り 
        Count
    }

    // キャラクター管理用 
    private GameObject m_goCharacter = null;
    private GameObject m_goCharPos = null;
    private Vector3 m_vecCharacterPos;      // キャラクター位置 
    private Vector3 m_vecCharacterScale;    // キャラクタースケール 

    // 処理ステップ用 
    private enum Step : int
    {
        Init = 0,   // 初期化 
        Title,      // タイトル 
        Wait,       // 待機 
        Move,       // 移動 
        Attack,     // 攻撃
        End
    }

    // 処理ステップ管理用 
    private Step m_Step = Step.Init;

    // 汎用
    // いろいろ使いまわす用変数
    private int m_Count = 0;
    private bool m_SW = true;

    // Use this for initialization
    void Start () {

        // キャラクターパラメータ関連を設定 

        // 座標設定 
        m_vecCharacterPos.x = 0.0f;
        m_vecCharacterPos.y = -240.0f;
        m_vecCharacterPos.z = 0.0f;

        // スケール設定 
        m_vecCharacterScale.x = 0.5f;
        m_vecCharacterScale.y = 0.5f;
        m_vecCharacterScale.z = 1.0f;
    }

    // Update is called once per frame
    void Update () {
        switch(m_Step)
        {
            // 初期化
            case Step.Init:
                m_Count = 0;
                m_SW = true;
                m_Step = Step.Title;
                break;
            // タイトル
            case Step.Title:
                if (++m_Count > 15) {
                    m_SW = !m_SW;
                    m_Count = 0;
                }
                if( Input.GetKeyDown(KeyCode.Space) == true ) {
                    AnimationStart();   // アニメーション開始処理(設定)
                    m_Step = Step.Wait;
                }
                break;
            // 待機
            case Step.Wait:
                if (Input.GetKeyDown(KeyCode.Z) == true)        // 攻撃 
                {
                    // 攻撃に変更 
                    AnimationChange(AnimationPattern.Attack);
                    m_Step = Step.Attack;
                }
                else if (Input.GetKeyDown(KeyCode.LeftArrow) == true)   // 左移動 
                {
                    if (m_vecCharacterScale.x < 0)
                        m_vecCharacterScale.x *= -1;    // 左向きにします
                    m_goCharPos.transform.localScale = m_vecCharacterScale; // 向き設定 
                    // 走りに変更 
                    AnimationChange(AnimationPattern.Run);
                    m_Step = Step.Move;
                }
                else if (Input.GetKeyDown(KeyCode.RightArrow) == true)  // 右移動 
                {
                    if (m_vecCharacterScale.x > 0)
                        m_vecCharacterScale.x *= -1;    // 右向きにします
                    m_goCharPos.transform.localScale = m_vecCharacterScale; // 向き設定 
                    // 走りに変更 
                    AnimationChange(AnimationPattern.Run);
                    m_Step = Step.Move;
                }
                break;
            // 移動 
            case Step.Move:
                if (Input.GetKey(KeyCode.LeftArrow) == true)   // 左移動 
                {
                    if(m_vecCharacterPos.x > -560.0f)
                        m_vecCharacterPos.x -= 10.0f;
                }
                else if (Input.GetKey(KeyCode.RightArrow) == true)  // 右移動 
                {
                    if (m_vecCharacterPos.x < 560.0f)
                        m_vecCharacterPos.x += 10.0f;
                }
                else
                {
                    // 待機に変更 
                    AnimationChange(AnimationPattern.Wait);
                    m_Step = Step.Wait;
                }
                m_goCharPos.transform.localPosition = m_vecCharacterPos;    // 座標反映 
                break;
            // 攻撃中 
            case Step.Attack:
                if(IsAnimationPlay() == false)
                {
                    // 待機に変更 
                    AnimationChange(AnimationPattern.Wait);
                    m_Step = Step.Wait;
                }
                break;
            default:
                break;
        }
	}

    private void OnGUI()
    {
        // GUI変更
        GUIStyle guiStyle = new GUIStyle();
        GUIStyleState styleState = new GUIStyleState();

        switch (m_Step)
        {
            // タイトル
            case Step.Title:
                if (m_SW == true)
                {
                    styleState.textColor = Color.black; // 文字色 黒 
                    guiStyle.normal = styleState;       // スタイルの設定。
                    GUI.Label(new Rect(420, 180, 100, 50), "PRESS SPACE", guiStyle);
                }
                break;
            default:
                break;
        }
    }

    // アニメーション開始 
    private void AnimationStart()
    {
        Script_SpriteStudio6_Root scriptRoot = null;    // SpriteStudio Anime を操作するためのクラス
        int listLength = AnimationList.Length;

        // すでにアニメーション生成済 or リソース設定無い場合はreturn
        if (m_goCharacter != null || listLength<1)
            return;

        // 再生するリソース名をリストから取得して再生する
        Object resourceObject = AnimationList[0];
        if (resourceObject != null)
        {
            // アニメーションを実体化
            m_goCharacter = Instantiate(resourceObject, Vector3.zero, Quaternion.identity) as GameObject;
            if (m_goCharacter != null)
            {
                scriptRoot = Script_SpriteStudio6_Root.Parts.RootGet(m_goCharacter);
                if (scriptRoot != null)
                {
                    // 座標設定するためのGameObject作成
                    m_goCharPos = new GameObject();
                    if (m_goCharPos == null)
                    {
                        // 作成できないケース対応 
                        Destroy(m_goCharacter);
                        m_goCharacter = null;
                    }
                    else
                    {
                        // Object名変更 
                        m_goCharPos.name = "Comipo";

                        // 座標設定 
                        m_goCharacter.transform.parent = m_goCharPos.transform;

                        // 自分の子に移動して座標を設定
                        m_goCharPos.transform.parent = this.transform;
                        m_goCharPos.transform.localPosition = m_vecCharacterPos;
                        m_goCharPos.transform.localRotation = Quaternion.identity;
                        m_goCharPos.transform.localScale = m_vecCharacterScale;

                        //アニメーション再生
                        AnimationChange(AnimationPattern.Wait);
                    }
                }
            }
        }
    }

    // アニメーション 再生/変更 
    private void AnimationChange(AnimationPattern pattern)
    {
        Script_SpriteStudio6_Root scriptRoot = null;    // SpriteStudio Anime を操作するためのクラス
        int iTimesPlaey = 0;

        if (m_goCharacter == null)
            return;

        scriptRoot = Script_SpriteStudio6_Root.Parts.RootGet(m_goCharacter);
        if (scriptRoot != null)
        {
            switch (pattern)
            {
                case AnimationPattern.Wait:
                    iTimesPlaey = 0;    // ループ再生 
                    break;
                case AnimationPattern.Attack:
                    iTimesPlaey = 1;    // 1回だけ再生 
                    break;
                case AnimationPattern.Run:
                    iTimesPlaey = 0;    // ループ再生 
                    break;
                default:
                    break;
            }
            scriptRoot.AnimationPlay(-1, (int)pattern, iTimesPlaey);
        }
    }

    // アニメーションが再生中か停止中(エラー含)か取得します
    private bool IsAnimationPlay()
    {
        bool ret = false;

        Script_SpriteStudio6_Root scriptRoot = null;    // SpriteStudio Anime を操作するためのクラス

        if (m_goCharacter != null)
        {
            scriptRoot = Script_SpriteStudio6_Root.Parts.RootGet(m_goCharacter);
            if (scriptRoot != null)
            {
                // 再生回数を取得して、プレイ終了かを判断します
                int Remain = scriptRoot.PlayTimesGetRemain(0);
                if (Remain >= 0)
                    ret = true;
            }
        }

        return ret;
    }

}

関数解説

  • void Start ()
    キャラクターに関連するパラメータの初期化を行っています。
  • void Update ()
    毎フレーム行われる処理を m_Step の指定で処理が変化するように組んでいます。
  • void OnGUI()
    文字表示を行うために使用しています。
  • void AnimationStart()
    アニメーションを開始する処理をまとめています。
    プログラム上から、アニメーションのprefab を読み込んで、GameObjectを生成、座標指定しての表示を行っています。
  • void AnimationChange(AnimationPattern pattern)
    アニメーションパターンの切り替えを行っています。
  • bool IsAnimationPlay()
    アニメーションが再生中かどうか取得します。
    特定のアニメーションで終了を取得するために設けました。

関連ページ

SS6Player For Unity
 最新版、質問・要望は GitHubへ