こんにちは、Keita_Nakamori(´・ω・`)です。
今日は、オブジェクトの重力落下、衝突、最実体化、破壊までをやってみましたのでメモっておきます。
モデルの作成
まずはモデルの作成ですが、滑り台とシュートを作っていきました。
それぞれ、Create Emptyし、その中に部品を配置し一つの塊にしました。
その際、今回のモデルは斜面なので、なるべく簡単に調整できるよう、一旦、水平に作成したものをプレハブ化してPrefabsフォルダに保存し、ヒエラルキーへ呼び出したあとに、Rotationで斜面にするというやり方を採用しました。
さらに、後ほど再実体化(Instantiate)するときの出現位置を設定するために、予めプレハブ構成の中に、出現位置としてオブジェクトをひとつ配置しておくことで、指定が簡単になるメリットがありました。(結構重要)
重力落下と衝突面の定義
重力の定義は、オブジェクトに対してAdd Component>rigid body でUse GravityをONにすれば重力1Gが定義されます。
- 質量Mass=0.01kg
- 進行方向抵抗Drag=0
- 回転抵抗Angler Drag=0
としました。
衝突面の定義は、オブジェクトに対してAdd Component>Mesh Collider で定義できます。注意ですがここでIs Triggerにチャックを入れてはダメです。これは接触を検知したら別のスクリプトを走らせるためのものなので、逆に接触しなくなります。(非常にわかりにくい。)
MeterialへはPysicalMaterialとして予め作成したPM010を定義しました。
再実体化(Instatiate)
オブジェクトを再出現させるところをやっていきます。
Crate EmptyでGameControllerという名前にして、そこにAdd Componentで再出現スクリプト(Summon.cs)をアタッチする作戦で行きます。
スクリプト(Summon.cs)
DayDreamコントローラーのメインボタンを押すと発動するように作成しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Summon : MonoBehaviour { //当該スクリプトは、任意の3Dオブジェクトを任意の座標に召喚します。 //当該スクリプトは、予め作っておいたEmptyObjectであるゲームコントローラーに入れます。 //インスペクタ上で代入:召喚するオブジェクトをアタッチする(Assetsからドラッグすること) [SerializeField] GameObject summonObject; //インスペクタ上で代入:召喚する座標をもつオブジェクトをアタッチする。かEmptyObjectでも良い。 [SerializeField] Transform summonPosition; void Update() { //Daydreamコントローラーをクリックダウンすると下記関数Summon()が発動する。 if (GvrControllerInput.ClickButtonDown) { SummonFunc(); } } void SummonFunc() { //summonObjectをsummonPosition.positionの位置、summonPosition.rotationの向きで召喚する Instantiate(summonObject, summonPosition.position, summonPosition.rotation); } } |
GameControllerのインスペクター
スクリプトのおかげで、Summon ObjectとSummon Positionをインスペクターから定義できるようになっているはずです。
Summon Objectには出現位置として使用し、InstatiateするオブジェクトをAssetsのPrefabからドラッグします。ヒエラルキーから持ってくるとうまく再実体化できませんでした。
Summon Psition にはプレハブモデルの中にひとつだけ搬送ワークを設置していますので、それをヒエラルキーからアタッチして座標を取得します。
やってみましょう
ここで問題発生です。オブジェクトが増えるとFPSが極端に下がってしまいます。
オブジェクトの破壊
出現から一定時間後に自動的に破壊されるようにスクリプトを追加します。
スクリプト(TimeLimitObj.cs)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
using UnityEngine; using System.Collections; public class TimeLimitObj : MonoBehaviour { //オブジェクトのライフタイムのデフォルト値を定義 //およびインスペクターから変更可能にする public float life_time = 1.5f; //タイムカウンターの変数定義 float time = 0f; // Use this for initialization void Start() { //タイムカウンターの変数定義 time = 0; } // Update is called once per frame void Update() { //処理ステップ毎の時間を積算する time += Time.deltaTime; print(time); //積算時間がライフタイムを超えたら //そのオブジェクトを破壊する if (time > life_time) { Destroy(gameObject); } } } |
オブジェクト自身にインスペクターからAdd Component>TimeLimitObj をアタッチして、Life_timeに例として60(秒)などと入力します。
結果、60秒後には全てのオブジェクトが消滅します。
次回の課題
VR(Mirage Solo)の視界を他者も共有できるようにしたい。
まともな人間のアセットを配置したい・・・