Unity

【Unity】RobotKyleでいろいろ~ その2~ キーボードで操作する

投稿日:2020年9月30日 更新日:

概要

前回はUnityの新規プロジェクトの作成からUnity AssetのRobot Kyleを配置するところまでを紹介しました。

今回はこの続きとしてキーボードでRobot Kyleを動かすまでを紹介していきます。


環境

Windows10
Unity 2020.1.f1


やりたいこと

キーボードでの操作の実現を目指します。具体的には以下を行えるようにしたいと思います。

  • キーボードの↑↓ボタンで前後に進む
  • キーボードの←→ボタンで方向転換する
  • スペースキーでジャンプする
  • Shift + ↑↓ボタンで早いスピードで前後に進む

ただし今回はアニメーションまでは付けずに動けばいいというところまでを目指します。

Step1 : コンポーネントの追加

Robot Kyleを動かすにあたり物理計算を行うためのRigidbodyと、衝突を管理するためのColliderのコンポーネントを設定していきます。

Rigidbodyの追加

まずはRigidbodyを追加します。
HierachyからRobot Kyleを選択し、InspectorタブからAdd Componentを選択します。

検索ボックスが現れますので”rigid”などと打ってRigidbodyが出てきたら選択します。

Rigidbodyのパラメータはデフォルトのままで問題ありません。


Colliderの追加

同様にColliderも追加していきます。Add Componentから”collider”と入力し、Capsule Colliderを選択します。

Capsule Colliderの設定値はうまいくRobot Kyleの体が収まるくらいに調整するのが良いです。ここでは以下のように設定しています。

Y : 0.9
Radius : 0.3
Height : 1.8


Step2 : Main Cameraの設定

次にMain Cameraの設定を行います.
HierarchyのMain Cameraをドラッグ&ドロップでRobot Kyleの配下に配置します。

次に、Main CameraのInspectorでTransformを調整します。

ここは好みになりますが、私の場合はRobot Kyleのなるべく全身を映るようにしたかったため、以下のように設定してあります。

X : 0
Y : 1.5
Z : -2.5


Step3: 操作するスクリプトの作成

ProjectタブのAsset上で右クリックし、Create > C# Scriptからscriptファイルを新規作成し、PlayerConという名前を付けます。

scriptファイルを開き以下のようなスクリプトを記述します。

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

public class PlayerCon : MonoBehaviour
{
    // Start is called before the first frame update

    //Status
    [SerializeField] public bool onGround = true;
    [SerializeField] public bool inJumping = false;

    //rb Variable
    Rigidbody rb;

    //Run speed
    float speed = 6f;

    //Sprint speed
    float sprintspeed = 9f;


    //Angle change speed
    float angleSpeed = 200;

    //variable
    float v;
    float h;

    void Start()
    {

        //Getting rb component
        rb = this.GetComponent<Rigidbody>();

        //To Avoid Rotating body.
        rb.constraints = RigidbodyConstraints.FreezeRotation;

    }

    // Update is called once per frame

    void Update()
    {

        //Left Shift key can make character sprint run.
        if (Input.GetKey(KeyCode.LeftShift))
            v = Input.GetAxisRaw("Vertical") * Time.deltaTime * sprintspeed;
        else
            v = Input.GetAxisRaw("Vertical") * Time.deltaTime * speed;


        //It can't be moved in Attacking or Jumping
        if (!inJumping)
        {
            if (v > 0)
            {
                transform.position += transform.forward * v;
            }
            else
            {
                transform.position += transform.forward * v / 3;
            }
        }

        //Horizontal Movement
        h = Input.GetAxisRaw("Horizontal") * Time.deltaTime * angleSpeed;
        transform.Rotate(Vector3.up * h);

        //Jumping Movement
        if (Input.GetButton("Jump") &amp;&amp; onGround)
        {
            //Initialize velocity
            rb.velocity = new Vector3(0, 0, 0);

            //Adding Force upfoward to Jump
            rb.AddForce(transform.up * 300);

            //When character is in Spinrt, the force is stronger than normal to up&amp;foward 
            if (Input.GetKey(KeyCode.UpArrow) &amp;&amp; Input.GetKey(KeyCode.LeftShift))
                rb.AddForce(transform.forward * 250);

            //When character is in run, the force is to up&amp;foward
            else if (Input.GetKey(KeyCode.UpArrow))
                rb.AddForce(transform.forward * 180);
 
            //When character is running back, the force is to backward
            else if (Input.GetKey(KeyCode.DownArrow))
                rb.AddForce(transform.forward * -100);
            
            //when jumping, the onGround flag is false.
            onGround = false;
        }


    }
    void OnCollisionEnter(Collision col)
    {
        onGround = true;
        inJumping = false;
    }
}

スクリプトの中身について順を追って紹介します。

void Startの中身

rb = this.GetComponent<Rigidbody>();
rb.constraints = RigidbodyConstraints.FreezeRotation;

今回、Playerの操作にRigidbodyを使用します。そのためPlayerのRigidbody関連のオブジェクトを取得しておきます。

void Updateの中身

前後方向の移動速度

if (Input.GetKey(KeyCode.LeftShift))
    v = Input.GetAxisRaw("Vertical") * Time.deltaTime * sprintspeed;
else
    v = Input.GetAxisRaw("Vertical") * Time.deltaTime * speed;
  • 左Shiftを押したときはsprintspeedで定義されている速度を使用
  • それ以外はspeedで定義されている速度を使用

移動

if (!inJumping)
        {
            if (v > 0)
            {
                transform.position += transform.forward * v;
            }
            else
            {
                transform.position += transform.forward * v/2;
            }
        }
  • ジャンプしている際には移動できないように制限
  • 後退するときは速度を半分に制限
  • transform.positionを使用して位置を移動


方向転換

h = Input.GetAxisRaw("Horizontal") * Time.deltaTime * angleSpeed;
transform.Rotate(Vector3.up * h);
  • 方向転換のベクトル定義
  • transform.Rotateで回転


ジャンプ

if (Input.GetKey(KeyCode.Space) &amp;&amp; onGround)
{
    rb.velocity = new Vector3(0, 0, 0);
    rb.AddForce(transform.up * 300);

    if (Input.GetKey(KeyCode.UpArrow) &amp;&amp; Input.GetKey(KeyCode.LeftShift))
        rb.AddForce(transform.forward * 250);

    else if (Input.GetKey(KeyCode.UpArrow))
        rb.AddForce(transform.forward * 180);

    else if (Input.GetKey(KeyCode.DownArrow))
        rb.AddForce(transform.forward * -100);

    onGround = false;
    }
  • Spaceキーが押されてかつ地面に接地しているとき(空中ジャンプは禁止)
  • 速度を0にリセット(連続ジャンプで速度が増えていかないように)
  • 上方向に力発生(これで垂直ジャンプ)
  • ↑キーと左Shiftの同時押しで前方向に強めのrb.AddForceを発生(斜めジャンプ)
  • ↑キーで標準のrb.AddForce発生(斜めジャンプ)
  • ↓キーで後ろジャンプのrb.AddForce発生
  • ジャンプ後に地面接地フラグをFalseにする


OnCollisionEnter

if (col.gameObject.tag == "Ground")
{
    onGround = true;
    inJumping = false;
}
  • Groundと接触したらonGroundをtrueにする
  • Groundと接触したらinJumpingをfalseにする
 注意事項:TerrianにGroundタグが付いていること、Robot KyleのCapsule Colliderのis Trigerにチェックが入っていないこと 

Gameモードで確認

無事に動くことを確認する。

まとめ

今回はキーボードでRobot Kyleを動かすところまでを実践しました。ただ、この状態だとまだアニメーションがついていないので、味気ないです。次回はさらにこのスクリプトを改良し、アニメーションをつけていきたいと思います。

-Unity

執筆者:


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

UnityでSerializedObjectNotCreatableException:Object at index 0 is nullが出た時の対処法

Contents1 発生状況1.1 実行環境2 対処その13 対処その24 まとめ 発生状況 UnityでFreeのAnimationクリップをeditから編集し、その後Gameをスタートしたところ、 …

【Unity】error CS0619:’GUIText’ is obsolete:’GUIText has been removed. Use UI.Text instead.’が出た時の対処法

Contents1 目的1.0.1 2020/9 追記2 環境3 発生現象4 対処方法 目的 UnityでC#スクリプトを記述してゲームオブジェクトにAttachしようとしたときにerror CS06 …

【Unity】衝突時にパーティクルを発生させる

Contents1 目的2 環境3 事前準備4 Step1 : 衝突させるオブジェクトの設置5 Step2 : Sphereへのパーティクル設定6 Step3 : 衝突時にParticleを再生するス …

UnityでPostProcessManager.cs(425,66): error CS0117: ‘EditorSceneManager’ does not contain a definition for ‘IsGameObjectInMainScenes’が出た時の対処法

Contents1 概要2 環境3 発生状況4 対処方法5 まとめ 概要 UnityのAsset StoreからParticle Packageをダウンロードしてimportしたところ、以下のエラーが …

UnityでAnimationEvent ‘Hit’ on animation ‘Attack1’ has no receiver! が出た時の対処

Contents1 概要2 環境3 発生事象4 対処法4.1 Animationのコピー4.2 Hitイベントの削除4.3 再度Gameで確認 概要 Unity Asset StoreでFreeのAn …

言語切り替え

カテゴリー