【Unity】オンライン3Dアクションゲームの作り方をまとめる! (前編)

スポンサーリンク
PC創作
マイケル
マイケル
どうもこんばんは!マイケルです!
エレキベア
エレキベア
クマ〜〜〜〜〜〜
マイケル
マイケル
最近は3Dエレキベアを動かすのを目標に3Dモデル作成をがんばっていましたが、
今日はゲーム作成側の勉強ということで、こちらの本を使って進めていきます!
スクリーンショット 2020 04 08 0 36 18

Unityゲーム開発 オンライン3Dアクションゲームの作り方

エレキベア
エレキベア
アクションゲームクマ!!
マイケル
マイケル
こちらの画面が作成するゲームの画面になります!
スクリーンショット 2020 04 08 0 59 58
エレキベア
エレキベア
かっこいいクマ〜〜〜!!
マイケル
マイケル
移動して攻撃したりとそれなりのクオリティのゲームが作れるので、
Unityの基本操作を一通り覚えて、次のステップに進みたい人には持ってこいですね!
マイケル
マイケル
ただ、いろいろと情報が古いので調べながら直さないといけない部分も多々あるので注意です。。。
エレキベア
エレキベア
昔の本なのクマね
マイケル
マイケル
そうなんだよね!
調べたくない人はなるべく最新の参考書をみたほうがいいかもしれません…
マイケル
マイケル
とりあえずこの本を前半部分、ゲームの基本操作の部分を作り終わったので、自分の中の整理もかねて紹介しようと思います!
スポンサーリンク

作成の流れについて

マイケル
マイケル
この本では主に、

・移動操作の設定
・ステータスの追加
・アニメーションの設定
・攻撃処理の設定
・敵のAI設定

という流れで作成していきます!
マイケル
マイケル
まずはスクリプトの全体図を僕の解釈でまとめてみました!
スクリーンショット 2020 04 08 0 19 58
エレキベア
エレキベア
ごちゃごちゃしてて分からないクマ
マイケル
マイケル
これから少し分割して説明するよ
マイケル
マイケル
最初は少ししっかりしたゲームを作り始めようとした時、
どういう単位でプログラムを組んだらいいかわからないと思うけど
マイケル
マイケル
この本で作るゲームは役割ごとにスクリプトを分けて作っているので、
全体設計の参考にも役立つと思うし、いろんなゲームに流用できるところがあると思うよ!
エレキベア
エレキベア
それはやりがいがあるクマね

移動操作について

スクリーンショット 2020 04 08 22 43 33
マイケル
マイケル
最初に移動させる操作を作ります!
マイケル
マイケル
まずキャラクターを移動させる共通のスクリプト「CharacterMove.cs」を作って、受け取った移動位置に移動するスクリプトを書きます
・・・・・(略)・・・・・
            // 水平面での移動のためYは固定
            Vector3 destinationXZ = destination;
            destinationXZ.y = transform.position.y;

            // 目的地までの距離と方角を求める
            Vector3 direction = (destinationXZ - transform.position).normalized; // ベクトル
            float distance = Vector3.Distance(transform.position, destinationXZ); // 距離

            // 現在の速度を退避
            Vector3 currentVelocity = velocity;
            // 目的地に近づいたら到着
            if (arrived || distance < StoppingDistance)
                arrived = true;

            // 移動速度を求める
            if (arrived)
                velocity = Vector3.zero;
            else
                // 方向ベクトル * 歩行速度
                velocity = direction * walkSpeed;

・・・・・(略)・・・・・

        // 重力を加える
        // 下方向ベクトル * 重力加速度 * フレーム間の時間
        velocity += Vector3.down * GravityPower * Time.deltaTime;

        // 設置していたら思い切り地面に押し付ける
        Vector3 snapGround = Vector3.zero;
        if (characterController.isGrounded)
            snapGround = Vector3.down;
        // 新しい位置 = 移動速度ベクトル * 1フレームの時間 + 地面に押し付ける力
        characterController.Move(velocity * Time.deltaTime + snapGround);
マイケル
マイケル
そしてクリックやドラッグ操作を判定する「InputManager.cs」、
クリックした時に移動地点を渡す「CharacterCtrl.cs」の二つを作ってあげることで
InputManage -> PlayerCtrl -> CharacterMove
の順番でクリックした位置の情報が渡っていき、移動することができます!
・・・・・(略)・・・・・ 
   // クリックの状態を返す
    public bool Clicked()
    {
        if (!moved && Input.GetButtonUp(MOUSE_LEFT_CLICK))
            return true;
        else
            return false;
    }
・・・・・(略)・・・・・
・・・・・(略)・・・・・
    // 歩行Update
    void Walking()
    {
        if (inputManager.Clicked())
        {
            // クリックした箇所にRayを飛ばす
            Ray ray = Camera.main.ScreenPointToRay(inputManager.GetCursorPosition());
            // Rayを飛ばして地面と交差した位置を求める
            if (Physics.Raycast(ray,
                out RaycastHit hitInfo, // 衝突したオブジェクト
                RayCastMaxDistance,
                (1 << LayerMask.NameToLayer("Ground")) | (1 << LayerMask.NameToLayer("EnemyHit")))) // Ground, またはEnemyHitのビットフィールド
            {
                // 地面をクリックした時
                if (hitInfo.collider.gameObject.layer == LayerMask.NameToLayer("Ground"))
                {
                    SendMessage("SetDestination", hitInfo.point);
                }
・・・・・(略)・・・・・
            }
        }
エレキベア
エレキベア
他のキャラクターにも使いまわせるよう
役割ごとに分けてるクマね
マイケル
マイケル
そのとおりクマ

ステータスの追加について

スクリーンショット 2020 04 08 22 54 55
マイケル
マイケル
これは簡単で、キャラクターのHPや名前を管理する
「CharacterStatus.cs」を作ります!
・・・・・(略)・・・・・
    // 体力
    public int HP = 100;
    public int MaxHP = 100;

    // 攻撃力
    public int Power = 10;

    // 最後に攻撃した対象
    public GameObject lastAttackTarget = null;

    // ----- GUI, ネットワーク設定で使用 -----
    // プレイヤー
    public string characterName = "Player";
・・・・・(略)・・・・・
エレキベア
エレキベア
これもあとで他のキャラクターにも設定できるようにするクマね
マイケル
マイケル
賢いねエレキベア

アニメーションの設定について

スクリーンショット 2020 04 08 22 55 24
マイケル
マイケル
次にアニメーションの設定です!
スクリーンショット 2020 04 08 23 55 50
マイケル
マイケル
アニメーションは上記画像のようなAnimationClipの設定画面から遷移条件を指定できます!
マイケル
マイケル
遷移条件を設定したら、パラメータを設定する「CharaAnimation.cs」を作ります!
    void Update()
    {
        // runアニメーション設定
        Vector3 delta_position = transform.position - prePosition;
        animator.SetFloat("Speed", delta_position.magnitude / Time.deltaTime);
        // Attackアニメーション設定
        if(attacked && !status.attacking)
        {
            attacked = false;
        }
        animator.SetBool("Attacking", (!attacked && status.attacking));
        // Downアニメーション設定
        if(!isDown && status.died)
        {
            isDown = true;
            animator.SetTrigger("Down");
        }
        // 現在位置を設定
        prePosition = transform.position;
    }
マイケル
マイケル
以上の設定で、特定条件を満たした時にアニメーションが変化するようになります!
合わせて、「PlayerCtrl.cs」にもステータスを追加しておきましょう!
・・・・・(略)・・・・・
    // Update is called once per frame
    void Update()
    {
        // ステートに応じた処理
        switch (state)
        {
            case State.Walking:
                Walking();
                break;
            case State.Attacking:
                Attacking();
                break;
        }
        // ステート遷移処理
        if(state != nextState)
        {
            state = nextState;
            switch (state)
            {
                case State.Walking:
                    WalkStart();
                    break;
                case State.Attacking:
                    AttackStart();
                    break;
                case State.Died:
                    Died();
                    break;
            }
        }
    }
・・・・・(略)・・・・・

攻撃処理について

スクリーンショット 2020 04 08 0 19 58のコピー
マイケル
マイケル
移動、アニメーション設定までしたら次は攻撃処理の設定です!
マイケル
マイケル
攻撃する武器の範囲に「AttackArea.cs」、
攻撃を受ける範囲に「HitArea.cs」を作成しましょう!
マイケル
マイケル
そして「AttackArea.cs」を設定した武器が当たった対象の
「HitArea.cs」に攻撃情報を送り、「PlayerCtrl.cs」内でHPを減らす処理を実装します!
・・・・・(略)・・・・・
    void OnTriggerEnter(Collider other)
    {
        // 攻撃が当たった相手のDamageメッセージをおくる
        other.SendMessage("Damage", GetAttackInfo());
        // 攻撃した対象を保存
        status.lastAttackTarget = other.transform.root.gameObject;
    }
・・・・・(略)・・・・・
・・・・・(略)・・・・・
    void Damage(AttackArea.AttackInfo attackInfo)
    {
        transform.root.SendMessage("Damage", attackInfo);
    }
・・・・・(略)・・・・・
・・・・・(略)・・・・・
    // ダメージ受けた時の処理
    // (HitArea.csからSendMessageで呼び出される)
    void Damage(AttackArea.AttackInfo attackInfo)
    {
        status.HP -= attackInfo.attackPower;
        // 死亡判定
        if (status.HP <= 0)
        {
            status.HP = 0;
            ChangeState(State.Died);
        }
    }
・・・・・(略)・・・・・
エレキベア
エレキベア
これで相手のHPを減らせるようになるクマね

敵のAI設定について

スクリーンショット 2020 04 08 22 50 30
マイケル
マイケル
以上でプレイヤーの動きは大体設定できたので、
最後に敵の動きを設定していきます!
マイケル
マイケル
敵に設定するスクリプトも基本的にプレイヤーと一緒ですが、「SearchArea.cs」を追加し、「PlayerCtrl.cs」から「EnemyCtrl.cs」に変えています
エレキベア
エレキベア
具体的にどう違うクマ?
マイケル
マイケル
自分で動かすプレイヤーと違って敵は自身で動いてもらわないといけないので
AI設定をしているというわけです!
エレキベア
エレキベア
敵が勝手に動くようにするクマね
マイケル
マイケル
「SearchArea.cs」で探索範囲の中にプレイヤーがいたらターゲットに設定して、「EnemyCtrl.cs」の中でプレイヤーを追跡するステータスを追加するよ!
・・・・・(略)・・・・・
    private void OnTriggerStay(Collider other)
    {
        // Playerタグをターゲットにする
        if (other.tag == "Player")
        {
            enemyCtrl.SetAttackTarget(other.transform);
        }
    }
・・・・・(略)・・・・・
・・・・・(略)・・・・・
    // 追跡中
    void Chasing()
    {
        // 移動先をプレイヤーに設定
        SendMessage("SetDestination", attackTarget.position);
        // 2m以内に近づいたら攻撃
        if (Vector3.Distance(attackTarget.position, transform.position) <= 2.0f)
        {
            ChangeState(State.Attacking);
        }
    }
・・・・・(略)・・・・・
スポンサーリンク

まとめ

マイケル
マイケル
ざっくりと話しましたが、これまでの設定で敵が自分で動いて、
攻撃したら倒せるようになります!
マイケル
マイケル
ここにゲームルールや敵を生成するジェネレータを追加するだけでも割と遊べますね
エレキベア
エレキベア
3Dキャラを動かすのは楽しいクマね
マイケル
マイケル
夢が広がるね!
今回で基本操作までは作れたから、次はUIやネットワーク設定をしていくぞ!
エレキベア
エレキベア
楽しみクマ〜〜〜〜〜〜〜
マイケル
マイケル
さて、ブログも書いたし遊ぶか〜〜〜〜
スクリーンショット 2020 04 05 17 40 53
エレキベア
エレキベア
どんだけドラゴンおんねん
マイケル
マイケル
バグらせるのも楽しいね

【Unity】オンライン3Dアクションゲームの作り方をまとめる! (前編) 〜完〜

コメント