前回の続きです。
視点移動について色々試してみます。
まずは上を向いたら見上げる、下を向いたら見下ろせるようなスクリプトを書く。
加速度センサーを使って基本姿勢(カメラをとるときのスマホの向き)のInput.acceleration.zが「0」で上向きが「1」、下向きが「-1」なのを利用してカメラを動かします。
また、ユニティちゃんの位置は足元を指しているので若干調整。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CamCTRL : MonoBehaviour { public Transform camL,camR,unitychan; Vector3 il,ir,upos; void Start () { il = camL.position; ir = camR.position; upos = unitychan.position + 0.75f*Vector3.up; } void Update(){ Vector3 _v = new Vector3(0,-Input.acceleration.z,0); camL.position = il+_v; camR.position = ir+_v; camL.LookAt(upos); camR.LookAt(upos); } } |
これで上下を見るとユニティちゃんを見上げてたり見下ろすことができました。
でもなんか違う。
本当は左右を向いたら周りが見えてしゃがんだら視点が下がるようなことがしたい。
視点の回転はジャイロが使えれば簡単です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
void Start () { Input.gyro.enabled = true; ql = camL.rotation; qr = camR.rotation; } void Update(){ if(isFirstGyro && Input.gyro.attitude.x!=0){ isFirstGyro = false; qi = Input.gyro.attitude;//スマホの初期回転 } Quaternion _gyroq = Quaternion.Inverse(Quaternion.Inverse(qi)*Input.gyro.attitude); camL.rotation = ql*_gyroq; camR.rotation = qr*_gyroq; } |
最初の回転を覚えておいて、そこからどれくらい回転したか反映させます。
クォータニオンの計算は久々なので無駄がありそう。
問題は視点の平行移動です。
本来は外部のセンサーがユーザの位置を把握するわけですがそんなことができるのものは高い。
複数のスマホを使ってそれっぽいことはできそうだけど再現性がないしなんか嫌。
スマホ単体でどうにかできないか考えてみる。
スマホには加速度センサーがついている。
これは静止状態だと単位ベクトルだけど力が加わると増減する。
上手いこと使えばスマホの動きを検知できそう?
加速度の変化を保存・比較してカメラを動かしてみる。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
nv = Input.acceleration; if(nv.magnitude>0.5f&&pv.magnitude>0.5f){ //異常値ではない if(Vector3.Angle(nv,pv)<10){ //スマホが回転してない if(Mathf.Abs(nv.magnitude-pv.magnitude)>0.1f){ //加速度ベクトルの大きさ変化 tv = (nv-pv)*0.1f; camL.position += tv; camR.position += tv; f1 = pv.magnitude/nv.magnitude; nv *= 1f/nv.magnitude;//反動を抑える } } } pv=nv; |
回転によらないベクトル変化でベクトル長が変化したときに動いたことにします。
慣性の法則で止まるときに逆方向に力がかかるので元に戻らないようにしてます。
・・・。
それっぽい動きはするけど安定しない。
まあそもそも精度の高いものでもないし用途も違うし仕方ない。
次はちょっと方向性を変えて遊んでみよう。