月別アーカイブ: 11月 2015

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が縦に表示されて煩わしいので、これを一つの関数にまとめてしまう。

実際にゲームスタートし、4つの変数の最適値を求める。ここでは、minX -6,maxX 6,minZ -4, maxZ 8ぐらいに設定した。

 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);
   }
 }

tiltの数値は、publicなので、ゲーム実行して設定する。ここでは、4.0ぐらいがちょうどいいかと思う。

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

広告

UnityチュートリアルSpaceShooterその1「環境設定」

標準

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

#1-1.プロジェクトの設定

1.新規プロジェクトを作成(追加パッケージは入れずに、クリーン状態で作成)

2.チュートリアルに関わるアセットをAsset Storeからダウンロード→プロジェクトにインポート

3.現在のシーンを_Scenesという名前のフォルダを作って、Mainシーンとして保存する(名前は何でもよい)
_(アンダースコア)をつけると、フォルダの一番上に来るのでわかりやすい

4.File→ビルド設定で、プラットフォームをWebPlayer(新しいバージョンでは、WebGL)にスイッチする。画面解像度は、(このゲーム用に)幅600ピクセル、高さ900ピクセルにセット。

5.レイアウトの変更:通常は、レイアウト一覧(右上)から「2 by 3」レイアウトを使うが、ここでは、ゲームウィンドウをドラッグして、シーンビューウィンドウの隣にもってきて、大きさを確認しやすくする。そのレイアウトに名前をつけて(例えば、SpaceShooter)保存しておく。

#1-2.プレイヤー機を設定

1.スペースシップをヒエラルキーにドラッグ。名前を「Player」に変更。インスペクターTransform右上の設定ボタンから、「リセット」をクリックし、位置、回転、スケールを初期値に戻す。

2.リジッドボディコンポーネントを追加。「重力を使用する」スイッチをオフにする。

3.衝突境界線(コライダー)コンポーネントを追加する。今回は、メッシュコライダーを使うが、カプセルコライダーで実施する場合のいくつかの注意をすると、まず、この機体の方向は、Z方向が正面になるので、カプセルコライダーの方向を「Z軸」に変更する必要がある。その上で、上から見て(Y軸)カプセルの大きさを機体にあわせる。

4.上記、カプセルコライダーのかわりに、ここでは、メッシュコライダーを使う。Unity5では、メッシュコライダーの「Convex」スイッチをオンにしないとうまくいかないので注意。Meshの形に、簡易化した、「player_ship_collider」を選択する。その上で、「Is Trigger」スイッチをオンにする。

5.アセットのプレファブフォルダに、ジェットエンジンのパーティクルを用意してあるので、Prefabs→VFX→Engines→engines_playerフォルダをヒエラルキーの機体(Player)の中に配置する。

パーティクルは、カメラの方向を常に向くので、Y軸以外から見ると、変に見えるかもしれない。
3Dアイコンが大きすぎると感じたら、ギズモ設定の3Dアイコンの数値を下げる。

#1-3. カメラと照明

1.カメラを選択し、一度場所のリセットをする。真下を向かせたいので、X回転を90にセット。

2.カメラのプロジェクション(投影)タイプはパースではなく、直交のほうを選ぶ(Orthographic)

3.直交なので、カメラ高さはどこでもいいが、Y位置(高さ)を10にしておく。

4.カメラサイズを調整し、だいたい10ぐらいが、ちょうど機体の大きさがよさそうなので、サイズ10にする。

5.機体の位置を上からみて、下方に置きたいのだが、機体は原点にそのまま配置しておき、カメラの位置で調整する。カメラのZ軸位置を5にするとちょうどよさそうである。

6.照明を設定するので、まず最初にあった、「Directional Light」を一度削除する。

7.メインカメラのクリアフラッグズ(Clear Flags)設定が、通常は、「Sky box」になっているが、背景は黒一色にしたいので、「Solid Color」にし、Backgroundの色を黒に設定する。

Unity5以降では、WindowメニューのLighting設定→Sceneのところに、環境光の設定場所が出るので、環境光「Skybox」の右横の小さな丸印をクリックし、必ず「None」(使わない)にしておくこと。

8.これでもまだ機体が見えるのは、環境光のアンビエントカラーが黒以外になっているからである。上記、環境光(Ambient Color)を黒にする。(ゲームシーンで見ると、機体のジェットエンジンパーティクルだけが見える状態)

9.ここから3点照明(メイン(キー)ライト、フィルライト、リムライト)を設置する。

1)Directional Lightを一つ追加し、「Main Light」と名前を変える。
Tranformをリセットして、位置回転を初期化した後、X方向回転で機体に光が当たる位置をさぐる。右側が照らされる位置ということで、X回転が「20」ぐらいがちょうどよさそうである。また、機体正面からも光が当たるように、Y方向回転を調整し、「-115」あたりに設定した。

2)色は「白(初期設定)」

3)強さ(Intensity)は、(チュートリアルムービーでは、0.75ぐらいと言っているが、照明方法がV5では変わったため、2倍程度と考えてよい)1.5から2に設定する。

10.フィルライト:

1)Main Lightを複製し、Fill Lightと名前を変える。

2)回転をリセットしてから、あらためて回転方向を探り、Y回転方向「125」、X回転方向「5」に設定する。

3)色は少しだけ青みがかった色にしたいので、R,G,B128,192,192にする。

4)強さは、(ビデオでは0.5と言っているが、その倍の)1.0に設定する。

11.リムライト:

1)Fill Lightを複製し、Rim Lightと名前を変える。色は白に戻す。

2)回転をリセットしてから、Y回転「65」、X回転「-15」ぐらい。

3)強さは、0.5にする。

12.ライトをまとめるために、空のゲームオブジェクトを作成し、Lightingと名前をつける。

Transformをリセットし、3つのライトをその下にまとめる。このLightingは、じゃまにならないよう、Y100の位置まで持ち上げておく。

#1-4. 背景をイメージ画像にする

1.3Dオブジェクト→Quadを選択し、作成。Backgroundと名前を変更する。

2.Transformをリセットしたのち、X回転90にする。

3.Assets→Texturesフォルダから、tile_nebula_green_diff画像を見つける。1024×2048とサイズが大きいことなどがわかる。

4.画像の1:2の縦横比を維持し、大きさ(スケール)を調整して、Backgroundスケールは、X15、Y30に設定する。

5.初期設定のシェーダーだと暗いので、シェーダーを、Unilit/Textureに変更する。

6.Player機体が背景に埋まらないよう、Y方向に-10ずらす。