Skip to main content
パーティクルで
2Dシューティング


くるくる
自己紹介

くるくる
・@mkd214
・22歳
・大学院1回生
・普段はJavaScriptでARな研究してます

Unity歴は1年半弱
・簡単なプロトタイプ作って遊んでます
・ゲームジャムやハッカソンによく出没
宣伝

おっさんコレクション

・Twitter上におっさんが現れるので捕まえる
・30種のおっさんをコンプリートするゲーム

・Node.js+MongoDB+DropBox

・興味のある人は @yanotasu をフォロー
早速
ゲームを作って行きましょう
どんなゲーム??
Particleがわんさかでてくるゲーム!!
と,いうことでParticleについて学ぼう!!
今日学ぶ、Particleの4つの要素


   Emission       Start系




    Shape     Simulation Space
Emission
Emission --- パーティクルのでる数を決める

・Rate
  連続してパーティクルが出る
  1秒辺りにでる数を設定する
・Burst
  ある時間に一斉にパーティクルが出る
  一斉に出る時間と数を設定する
Shape
Shape --- パーティクルのでる形

・Shape
  でる形を決める
・Radius,Angleなど
  でる形の各部分の大きさを設定する
・RandomDirection
  パーティクルの出る方向をランダムにする
・EmitFromShell
Shape
Shape --- パーティクルのでる形

・EmitFromShell
  Trueだと表面からのみでる
  Falseだと表面を含む領域全てからでる
Start系

Start系 ---1つのパーティクルが生成された時
     に与えられるパラメータ
・StartLifeTime
  出て消えるまでの時間。(寿命)
・StartSpeed
  出た時の速さ(マイナスの値もいれられるよ)
・StartSize
  出た時の大きさ
Simulation Space
SimulationSpace --- でたあとのParticleSystem
                    との位置の依存関係


                                   Local




                                   World
この4つ,なんとなくわかりましたか??


  Emission       Start系




   Shape     Simulation Space
パーティクルを作りましょう!!
必要なパーティクル

自機(Player)
チャージしてる時(Charging)
チャージが完了した時(Charged)
弾(Bullet)
自機が死んだ時(DeadPlayer)

敵(Enemy)
敵が死んだ時(DeadEnemy)
必要なパーティクル

7つのパーティクルを作成して
それぞれ名前をつけよう




次のページから,パーティクルを作っていくよ!!
自機(Player)

StartLifeTime   -> 0.1
StartSpeed      -> 0
SimulationSpace -> World

Rate           -> 1000

Shape          -> チェックを外す
チャージ中(Charging)

StartLifeTime   -> 0.5
StartSpeed      -> -10

Shape         -> Sphere
Radius        -> 5
EmitFromShell ->True
チャージ完了(Charged)

Rotation X      -> 0

StartLifeTime   -> 0.8
StartSpeed      -> 0
StartSize       -> 0.3
SimulationSpace -> World

Rate            -> 100
Shape          -> チェックを外す
弾(Bullet)

StartLifeTime   -> 0.05
StartSpeed      -> 0
StartSize       -> 0.8
SimulationSpace -> World


Rate            -> 100
Shape          -> チェックを外す
自機が死んだ時(DeadPlayer)

Looping          -> false
StartSpeed       -> 15

Rate             -> 0
Time Particles   -> 0.00 100
                  -> 0.50 100
                  -> 1.00 100

Shape            -> Sphere
敵(Enemy)

StartLifeTime    -> 0.1
StartSpeed       -> 0
StartColor       -> Red
Simulation Space -> World

Rate            -> 1000

Shape          -> チェックを外す
敵が死んだ時(DeadEnemy)

Looping          -> false
StartSpeed       -> 15
StartColor       -> Red

Rate             -> 0
Time Particles   -> 0.00 100

Shape            -> Sphere
当たり判定と剛体の準備をしよう
当たり判定と剛体の準備をしよう

当たり判定と剛体が必要なのは

Player(自機)
Bullet(弾)
Enemy(敵)

SphereColliderとRigidbodyをつけておこう!!
Playerに当たり判定と剛体

Use Gravity      -> false
FreezePositionZ -> true
FreezeRotationXYZ -> true

Center           -> 0 0 0
Radius           -> 0.3
Enemyに当たり判定

Use Gravity      -> false
FreezePositionZ -> true
FreezeRotationXYZ -> true

isTrigger        -> true
Center           -> 0 0 0
Radius           -> 0.5
Bulletに当たり判定

Use Gravity      -> false
FreezePositionZ -> true
FreezeRotationXYZ -> true

Center           -> 0 0 0
Radius           -> 0.5
カメラの設定をしておこう
カメラの設定をしておこう

今回は2Dなので
Orthographicカメラを使います

Position XYZ   -> 0 1 -10

Background     -> Black

Projection     -> Orthographic
Size           -> 5
Scriptを書いて動かそう!!
Playerの動きを作ろう

Player
・動く(Move)
・チャージする(Charge)
・弾を発射する(Shoot)
・敵に当たると死亡(Dead)

PlayerController.jsを作成し,
Playerに追加しておいてください
PlayerController.jsを書き換えよう.
function Update () {
   Move();
}
function Move(){
   var mouse = Input.mousePosition;
   var pos = Camera.mainCamera.ScreenToWorldPoint(mouse);
   pos.z = 0;
   transform.position = pos;
}
PlayerController.jsの解説
//スクリーン上のマウスの位置を取得
var mouse = Input.mousePosition;
//マウス座標からカメラ座標に変換
var pos = Camera.mainCamera.ScreenToWorldPoint(mouse);
//Zが-10が入るので0にする
pos.z = 0;
//マウスの位置に動かす
transform.position = pos;
PlayerController.jsの解説
//スクリーン上のマウスの位置を取得
var mouse = Input.mousePosition;
//マウス座標からカメラ座標に変換
var pos = Camera.mainCamera.ScreenToWorldPoint(mouse);
//Zが-10が入るので0にする
pos.z = 0;
//マウスの位置に動かす
transform.position = pos;
**この方法はOrthographicカメラ時のみ使える
親子関係に

ChargingとChargedを
Playerの子へ

子にしたいオブジェクトをドラッグ
親のオブジェクトにドロップ
親子関係に

ChargingとChargedを
Playerの子へ

子にしたいオブジェクトをドラッグ
親のオブジェクトにドロップ

その後,子のPositionを
(0,0,0)にしておく
PlayerController.jsの最後に追加

var chargedObj:GameObject;
var chargingObj:GameObject;
function Charge(){
   if(Input.GetButton("Fire1")){
       chargingObj.SetActive(true);
   }else if(Input.GetButton("Fire1")){
       chargingObj.SetActive(false);
   }
}
Chargeさせる(PlayerController.js内)
function Start () {
  chargingObj.SetActive(false);
  chargedObj.SetActive(false);
}
function Update () {
  Move();
  Charge();
}
Scriptから他Objectを操作
Playerの子のChargedを
Charged Obj横のNoneにドラッグドロップ

Playerの子のChargingを
Charging Obj横のNoneにドラッグドロップ
Chargeの解説

//マウスの左クリックが押されている間はTrue
if(Input.GetButton("Fire1")){
    //chargingObjをアクティブ(動いている状態)にします
    chargingObj.SetActive(true);
//マウスの左クリックが上がった瞬間だけTrue
}else if(Input.GetButton("Fire1")){
    //chargingObjをアクティブじゃないようにする
    chargingObj.SetActive(false);
}
Chargeの追加(PlayerController.js内)
private var time : float = 0.0;
function Charge(){
    time+=Time.deltaTime;
    if(Input.GetButton("Fire1")){
         if(time<2) { chargingObj.SetActive(true);}
         else{
              chargingObj.SetActive(false);
              chargedObj.SetActive(true);
         }
    }else if(Input.GetButtonUp("Fire1")){
         if(time<2) { chargingObj.SetActive(false);}
         else{chargedObj.SetActive(false);time=0;}
    }
}
たまを打つよ
PlayerController.jsの最後に追加
var bulletPrefab:GameObject;
private var root2 = Mathf.Sqrt(2);
private var x = [1,1/root2,0,-1/root2,-1,-1/root2,0,1/root2];
private var y = [0,1/root2,1,1/root2,0,-1/root2,-1,-1/root2];

function Shoot(){
    for(var i=0;i<8;i++){
         var bullet : GameObject = Instantiate(bulletPrefab);
bullet.transform.position = transform.position + Vector3(x[i],y[i],0)*1.0f;
         bullet.rigidbody.velocity = Vector3(x[i],y[i],0) * 15.0f;
         bullet.name = "Bullet";
         Destroy(bullet,2.0f);
    }
}
Shootの追加(PlayerController.js)
function Charge(){
   time+=Time.deltaTime;
   if(Input.GetButton("Fire1")){
        if(time<2) { chargingObj.SetActive(true);}
        else{
             chargingObj.SetActive(false);
             chargedObj.SetActive(true);
        }
   }else if(Input.GetButtonUp("Fire1")){
        if(time<2) { chargingObj.SetActive(false);}
        else{chargedObj.SetActive(false);time=0;Shoot();}
   }
}
Prefabの作り方
HierarchyのBulletを
Projectにドラッグドロップ

ProjectにBulletができていれば成功

HierarchyのBulletは
必要ないの削除しておきましょう

DeadPlayerとDeadEnemyとEnemyも
Prefab化し,Hierarchyのは削除しましょう
関連付けよう!!
BulletPrefabに関連付けるために
ProjectのBulletを
PlayerControllerの
Noneにドラッグドロップ
当たり判定を作るよ!!
PlayerController.jsの最後に追加
var deadPlayerPrefab:GameObject;
function OnTriggerEnter(other:Collider){
   if(other.gameObject.name == "Enemy"){
       var obj=Instantiate(deadPlayerPrefab);
       obj.transform.position = transform.position;
       Destroy(gameObject);
   }
}
OnTriggerEnterの解説
//Triggerにぶつかった時に呼ばれる
function OnTriggerEnter(other:Collider){
     //ぶつかったオブジェクトの名前がEnemyならTrue
     if(other.gameObject.name == "Enemy"){
          //Prefabをゲームシーンに登場させる
          var obj=Instantiate(deadPlayerPrefab);
          //登場したPrefabの位置をPlayerの位置にする
          obj.transform.position = transform.position;
          //Playerを消す
          Destroy(gameObject);
     }
}
Enemyをだすよ!!
Enemyをだすよ!!

空のGameObjectを作成.
名前は Creater.

Create.jsを作成.
空のGameObjectにAdd.

右のようになっていればOK
Create.jsを編集しよう
private var time=0.0f;
var prefab:GameObject;
var timeInterval : float = 2.5f;
function Update () {
    time += Time.deltaTime;
    if(time > timeInterval){
         time=0.0f;
         var obj = Instantiate(prefab);
         obj.transform.position.x = Random.Range(-11.20f,11.20f);
         obj.transform.position.y = 6;
         obj.transform.position.z = 0;
         obj.name = "Enemy";
    }
}
Createrの設定

PrefabがNoneになっているので
ProjectionのEnemyを
ドラッグドロップ
Enemyを動かすよ
Enemyの動きを知ろう

Enemy
・最初に速度を設定(等速直線運動する)
・下に行き過ぎたら勝手に消える
・弾にあたったらやられる


Enemy.jsを作成し,
EnemyのPrefabに追加しておいてください
Enemy.jsを書き換えよう.
function Start () {
     rigidbody.velocity.y = -Random.Range(3.0f,10.0f);
}
function Update () {
     if(transform.position.y < -12.0f){Destroy(gameObject);}
}
var deadEnemyPrefab : GameObject;
function OnTriggerEnter(other:Collider){
     if(other.gameObject.name == "Bullet"){
          var obj:GameObject = Instantiate(deadEnemyPrefab);
          obj.transform.position = transform.position;
          Destroy(obj,3.0f);
          Destroy(gameObject);
     }
}
関連付けるよ
ProjectionのEnemyの
DeadEnemyPrefabが
Noneになっているので
ProjectのDeadEnemyを
Noneにドラッグドロップ
完成!!!