前回の続き。
ボールを浮かしたい
コースは固定されてて重力が変化する空間の中でボールだけ浮かしたい…とか書くだけでややこしいですね。
この考えでは進みそうにないのでちょっと考え切り替えました。
めんどくさいから物理エンジンに任せようって。
コースが上下に動けば勝手にボールは跳ねるだろうと。
どうやろうか
なんとかしてスマホの上下移動をコースの高さに反映すればいいんだよね。Input.accelerationは常に重力加速度を受けてるから
スマホが固定されていれば1G(単位ベクトル)がかかった状態。
ここでスマホを上下に動かすとベクトルサイズが変わるはず。
やってみた
てきとーにInput.accelerationのベクトルサイズを計算して表示float g = Input.acceleration.magnitude; print(string.Format("DEBUG {0}", g));
動かさないとおおむね1前後
スマホ机に置いた状態 |
上下に動かした状態 |
でもこれだと左右に動かすだけでも1G以上がかかるよね。
まぁ傾けて遊ぶゲームだし急に左右に振るのは考えなくていいか。
無視しよ。
とりあえず使えそう!
ちょっと修正
Floorタグを持つオブジェクトのZ座標を動かすように書いてみた。
どんどんずれてどっか行っちゃうので自然と0近くに収束するようにした。
こんな感じ。
どんどんずれてどっか行っちゃうので自然と0近くに収束するようにした。
こんな感じ。
using UnityEngine; using System.Collections; public class Sensor : MonoBehaviour { /// <summary> /// スマホの移動に連動させるオブジェクト /// </summary> GameObject floor; /// <summary> /// 前フレームでのZ座標 /// </summary> float lastZ; // Use this for initialization void Start() { this.floor = GameObject.FindGameObjectWithTag("Floor"); this.lastZ = 0; } // Update is called once per frame void Update() { //端末が上下に動いた量 +↑、-↓ float g = Input.acceleration.magnitude - 1.0f; this.lastZ = (this.lastZ + g) * 0.9f; Vector3 lastPos = floor.transform.position; Vector3 newPos = new Vector3(lastPos.x, lastPos.y, this.lastZ); floor.transform.position = newPos; } }
追記
黄本読んでたら気になる記述見ちゃった。- プログラム制御するオブジェクトはRigidbodyコンポーネントを付ける
- そのうえでIsKinematicプロパティをONにする
- Update関数ではなくFixedUpdate関数内で更新する
- transformを直接操作せず、RigidbodyクラスのMoveRotation、MovePositionを使う
だそうな。
急きょ書き換え
- floorオブジェクトにrigidbodyを付加、isKinematicをON
- スクリプトも変更
using UnityEngine; using System.Collections; public class Sensor : MonoBehaviour { /// <summary> /// スマホの移動に連動させるオブジェクト /// </summary> GameObject floor; /// <summary> /// 前フレームでのZ座標 /// </summary> float lastZ; // Use this for initialization void Start() { this.floor = GameObject.FindGameObjectWithTag("Floor"); this.lastZ = 0; } // Update is called once per frame void FixedUpdate() { //端末が上下に動いた量 +↑、-↓ float g = Input.acceleration.magnitude - 1.0f; this.lastZ = (this.lastZ + g) * 0.9f; Vector3 lastPos = floor.transform.position; Vector3 newPos = new Vector3(lastPos.x, lastPos.y, this.lastZ); floor.rigidbody.MovePosition(newPos); } }
FixedUpdateだと更新間隔を指定できるみたいね。
指定方法はまた調べよう。
transporm.positionとrigidbody.MovePositionの違いはまだ分かんない。
ていうかボールの跳ねあがり方まったく別物になったんだけどw
→Unity系記事まとめ