UnityチュートリアルSpaceShooterその2「機体の動き」

標準

http://unity3d.com/jp/learn/tutorials/projects/space-shooter-tutorial

#1-5. Player機体を動かす

1.Playerオブジェクトに、C#スクリプトを追加する。名前は、PlayerControllerにする。

2.Assetsフォルダの下に、フォルダー _Scriptsなどを作成し、スクリプトはまとめておく。

3.矢印キーが押されたのを Input.GetAxisを通して反応させる

※Input.GetAxis について
http://unity3d.com/jp/learn/tutorials/modules/beginner/scripting/get-axis

Edit→Project設定→Inputをインスペクタで開くと、Axes についての詳細が設定してある
(AxesはAxis(軸)の複数形)
これをみると、
Axes → Horizontal には、左/右キーか、a/dキーが割り当てられているのがわかる。
また、その反応速度は、3に設定されているのもわかる(数値は-1.0から1.0の範囲をスライド。
Gravityは数値が0に戻る速度。Sensitivity は両端1.0か-1.0に移動する速度)
通常は気にせずに初期値のまま使って問題ない。

 また、キーの利用は、通常のUpdate()関数ではなく、FixedUpdate()関数(定期的に更新がかかる)のところに記述する。

using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour {
 void FixedUpdate(){
   float moveHorizontal = Input.GetAxis("Horizontal");
   float moveVertical   = Input.GetAxis("Vertical");
   Vector3 movement = new Vector3 (moveHorizontal,0.0f,moveVertical);
   GetComponent<Rigidbody>().velocity = movement ;
 }
}

4.スピードが遅いのを解消するために、speedという項目を追加する。void FixedUpdate()の上に

public class PlayerController : MonoBehaviour {
   public float speed;
   void FixedUpdate(){
   float moveHorizontal = Input.GetAxis("Horizontal");
   float moveVertical   = Input.GetAxis("Vertical");
   Vector3 movement = new Vector3 (moveHorizontal,0.0f,moveVertical);
   GetComponent<Rigidbody>().velocity = movement*speed ;
  }

ちなみに、上記表現は、rbというRigidbodyの変数を導入して、

  public class PlayerController : MonoBehaviour {
   private Rigidbody rb;
   public float speed;
   void Start(){
     rb=GetComponent<Rigidbody>();
   }
   void FixedUpdate(){
   float moveHorizontal = Input.GetAxis("Horizontal");
   float moveVertical   = Input.GetAxis("Vertical");
   Vector3 movement = new Vector3 (moveHorizontal,0.0f,moveVertical);
   rb.velocity = movement*speed ;
  }
 }

と表記しても同じ。

5.これで、ゲーム実行前に、speedに10などを設定して動かしてみるとよく動いていいのだが、
画面から機体が飛び出していってしまう。
これをclampを使って解消する。

  public class PlayerController : MonoBehaviour {
   private Rigidbody rb;
   public float speed;
   public float minX,maxX,minZ,maxZ;
   void Start(){
     rb=GetComponent<Rigidbody>();
   }
   void FixedUpdate(){
   float moveHorizontal = Input.GetAxis("Horizontal");
   float moveVertical   = Input.GetAxis("Vertical");
   Vector3 movement = new Vector3 (moveHorizontal,0.0f,moveVertical);
   rb.velocity = movement*speed ;
   rb.position = new Vector3
   (
    Mathf.Clamp(rb.position.x, minX, maxX),
    0.0f,
    Mathf.Clamp(rb.position.z, minZ, maxZ)
   );
  }
}

6.これでもいいのだが、インスペクタに一度しか使われない、minX,maxX,minZ,maxZが縦に表示されて煩わしいので、これを一つの関数にまとめてしまう。

 public class Boundary{
    public float minX,maxX,minZ,maxZ;
 }
 public class PlayerController : MonoBehaviour {
   private Rigidbody rb;
   public float speed;
   public Boundary boundary;
   void Start(){
     rb=GetComponent<Rigidbody>();
   }
   void FixedUpdate(){
   float moveHorizontal = Input.GetAxis("Horizontal");
   float moveVertical   = Input.GetAxis("Vertical");
   Vector3 movement = new Vector3 (moveHorizontal,0.0f,moveVertical);
   rb.velocity = movement*speed ;
   rb.position = new Vector3
   (
    Mathf.Clamp(rb.position.x, boundary.minX,boundary.maxX), 
    0.0f, 
    Mathf.Clamp(rb.position.z,boundary.minZ,boundary.maxZ) 
   ); 
   }
 }

Unityに戻って確認してみると、Boundaryの各変数を設定する場所が表示されない。
これは、シリアライゼーションといって、Unityに関数を知らせる作業をしていないからである。
Class PlayerControllerは、MonoBehaviourがシリアライゼーションしているので、問題ない。
そこで、[System.Seriarizable] をクラスBoundaryの前につける。

[System.Serializable]
 public class Boundary{
    public float minX,maxX,minZ,maxZ;
 }

7.このままでもいいが、左右に機体が動く速度にあわせて、機体を左右に振ることにする。(チルトの追加)

 public class PlayerController : MonoBehaviour {
   private Rigidbody rb;
   public float speed;
   public Boundary boundary;
   public float tilt;
   void Start(){
     rb=GetComponent<Rigidbody>();
   }
   void FixedUpdate(){
   float moveHorizontal = Input.GetAxis("Horizontal");
   float moveVertical   = Input.GetAxis("Vertical");
   Vector3 movement = new Vector3 (moveHorizontal,0.0f,moveVertical);
   rb.velocity = movement*speed ;
   rb.position = new Vector3
   (
    Mathf.Clamp(rb.position.x, boundary.minX,boundary.maxX), 
    0.0f, 
    Mathf.Clamp(rb.position.z,boundary.minZ,boundary.maxZ) 
   ); 
   rb.rotation = Quaternion.Euler (0.0f,0.0f,rb.velocity.x*-tilt);
   }
 }

以上。機体の動きまで。次回は、弾を撃つ設定。

コメントは受け付けていません。