多脚戦車と戯れてみる

 守られない次回予告

コントローラ操作の習得がメインやねんから別にユニティちゃんじゃなくてもええやろ!(キレ芸)

というわけで、どうせ当面のゴールはメカものゲーム制作なんだから、今からメカで色々するのも悪くはなかろうということで、今回からこれで遊ぶことにした。

assetstore.unity.com

フチコマだったりタチコマだったりウチコマだったり。

余談だけど、オリジナルであるフチコマの由来が、日本書紀に出てくる天斑駒に由来するとか、さすがは博識な士郎正宗氏である。

尚、ナメクジの交尾について知ったのも攻殻機動隊(コミック)が初めてである。

能書きはいいからさっさと動かそう

モノを用意

今回必要なものは(デフォルト以外では)以下の通り。
ちなみに今回から新規プロジェクトで作業を始める。
使用するUnityは2018.2.10f1である。

  • InControl(神アセット)
  • Plane(母なる大地)
  • Player(空のGameObject)
  • Rigidbody("Player"のComponent)
  • Box Collider("Player"のComponent)
  • Mech Control("Player"のScript Component)
  • ACS17(”Assets/ACS-17/Prefab/ACS17"の実体、"Player"の子に配置)

InControl必須であるので、入れ忘れの無いように。セットアップも忘れるなヨ!

assetstore.unity.com

各種パラメータは適当で。デフォルトで一向に構わんということだ。

ただ、Colliderを"ACS17"を納めるサイズにしたり、実行時に"ACS17"が"Plane"上に乗るぐらいの配慮は期待したいゾ。

ソースの中身

いい加減GitHab立ち上げて貼ったほうが良いような気もするが、とりあえず今回も直接貼ります。

MechControl.cs

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

namespace InControl
{
    public class MechControl : MonoBehaviour {

        private enum Direction{ Idle, Forward, Backward, Left, Right, TurnLeft, TurnRight};
        private Direction prevDirection = Direction.Idle;

        // Use this for initialization
        void Start() {

        }

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

        }

        private void FixedUpdate()
        {
            Rigidbody rigidBody = GetComponent<Rigidbody>();
            GameObject gameObject = transform.Find("ACS17").gameObject;
            Actions script = gameObject.GetComponent<Actions>();
            InputControl[] controls = new InputControl[16];
            float horizontal = 0.0f;
            float vertical = 0.0f;
            float turn = 0.0f;
            Direction currentDirection;
            Direction[] directions = { Direction.Idle, Direction.Idle, Direction.Idle };
            Vector3 velocity;

            controls[0] = InputManager.ActiveDevice.GetControl(InputControlType.LeftStickX);
            controls[1] = InputManager.ActiveDevice.GetControl(InputControlType.LeftStickY);
            controls[2] = InputManager.ActiveDevice.GetControl(InputControlType.RightStickX);
            controls[3] = InputManager.ActiveDevice.GetControl(InputControlType.RightStickY);
            controls[4] = InputManager.ActiveDevice.GetControl(InputControlType.LeftStickButton);
            controls[5] = InputManager.ActiveDevice.GetControl(InputControlType.Action1);

            /* Horizontal move */
            if (controls[0].Value <= -0.1f)
            {
                horizontal = controls[0].Value * 10.0f;
                directions[0] = Direction.Left;
            }
            else if (controls[0].Value >= 0.1f)
            {
                horizontal = controls[0].Value * 10.0f;
                directions[0] = Direction.Right;
            }
            /* Vertical move */
            if (controls[1].Value <= -0.1f)
            {
                vertical = controls[1].Value * 10.0f;
                directions[1] = Direction.Backward;
            }
            else if (controls[1].Value >= 0.1f)
            {
                vertical = controls[1].Value * 15.0f;
                directions[1] = Direction.Forward;
            }
            /* Turn */
            if (controls[2].Value <= -0.1f)
            {
                turn = controls[2].Value * 3.0f;
                directions[2] = Direction.TurnLeft;
            }
            else if (controls[2].Value >= 0.1f)
            {
                turn = controls[2].Value * 3.0f;
                directions[2] = Direction.TurnRight;
            }
            velocity = new Vector3(horizontal, 0.0f, vertical);
            transform.localPosition += transform.TransformDirection(velocity) * Time.fixedDeltaTime;
            transform.Rotate(0.0f, turn, 0.0f);

            if ((Mathf.Abs(vertical) >= 1.0f) &&
                Mathf.Abs(vertical) >= Mathf.Abs(horizontal))
            {
                currentDirection = directions[1];
            }
            else if (Mathf.Abs(horizontal) >= 1.0f)
            {
                currentDirection = directions[0];
            }
            else
            {
                currentDirection = directions[2];
            }

            if(prevDirection != currentDirection)
            {
                switch (currentDirection)
                {
                    case Direction.Idle:
                        script.Idle();
                        break;
                    case Direction.Forward:
                        script.WalkForwad2();
                        break;
                    case Direction.Backward:
                        script.WalkBack();
                        break;
                    case Direction.Left:
                        script.StrafeLeft();
                        break;
                    case Direction.Right:
                        script.StrafeRight();
                        break;
                    case Direction.TurnLeft:
                        script.TurnLeft();
                        break;
                    case Direction.TurnRight:
                        script.TurnRight();
                        break;
                }
                prevDirection = currentDirection;
            }

            if (controls[5].WasPressed)
            {
                script.Dead4();
            }

        }
    }
}

InControl影響下に置くClass(今回は"MechControl" class)を"InControl" namespaceに置かねばならんというところが注意点ではあるが、それ以外はユニティちゃんを動かしていた時と大差ない。

入力用のエントリが16個あるのは、将来拡張用なので気にしないで欲しい。

簡単に仕様を説明すると、左スティック入力に応じて進行ベクトルを、右スティック水平入力に応じて旋回量をそれぞれ算出し、"Rigidbody"に反映している。

入力にはそれぞれ、ゼロ点付近の入力誤差を考慮して0.1f程度の遊びを設けている。
操作感によって各自調整すればいいだろう。

尚、移動させるだけでは面白くないので、モーションも付けてみた。

Z軸方向ベクトル>=X軸方向ベクトルで前進/後退モーションに、Z軸方向ベクトル<X軸方向ベクトルで左右移動モーションに、右スティックのみ入力で左右旋回モーションに、未入力状態ではアイドルモーションに、それぞれ切り替えている。

死にたいときはアクションボタンを押せ(CV:青野武

アニメーション切り替えは、”ACS17”の"Action" Scriptの各種メソッドを使用しているが、"Action" Scriptの中身も”ACS17”下の"Animator"のフラグを叩いてるだけなので直接叩いてもいいと思う。

動かしてみた

f:id:himatsubushi-industry:20180930080508g:plain

移動量と歩幅が合ってないとか色々とアラはあるが、それなりに見えるので良しとしよう。

次回予告

戦車なので弾を出してみたいと思う。
また、このモデル、ローラーダッシュが出来るので、ローラー移動も組み込みたい。

あと、いい加減カメラを定点から外したい。

尚、来週が予告通りになるかは保証しない。