基準点に必要な挙動は回転とズームでした。
今回つけた機能は以下の通りです。
- スワイプでθ、φ変位(それぞれスワイプの縦成分、横成分が対応)
- キー操作でr変位(Wで拡大、Qで縮小)
- キーボードEで視点リセット
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PolarCoordinates : MonoBehaviour {
public GameObject origin; // 原点
public Camera camera; // 使用するカメラ
public float swipeMoveSpeedX = 0.01f; // スワイプで移動するスピード
public float swipeMoveSpeedY = 0.01f; // スワイプで移動するスピード
public float theta = 90 * Mathf.Deg2Rad; // 極座標角度パラメータθ
public float phai = 0 * Mathf.Deg2Rad; // 極座標角度パラメータφ
public float r = 5; // 極座標距離r(ReferencePointの座標から算出)
public float diffR = 1; // ズーム単位
private Vector3 baseMousePos; // 基準となるタップの座標
private Vector3 baseCameraPos; // 基準となるカメラの座標
private bool isMouseDown = false; // マウスが押されているかのフラグ
public void UpdatePosition() {
// θ,φの変位を直交座標の変位に変換する
float newX = r * Mathf.Sin(theta) * Mathf.Cos(phai);
float newY = r * Mathf.Cos(theta);
float newZ = r * Mathf.Sin(theta) * Mathf.Sin(phai);
if (theta > 0 && theta < 180 * Mathf.Deg2Rad) {
this.transform.position = new Vector3 (newX, newY, newZ);
}
// 原点にむけてRotationを修正
transform.LookAt(new Vector3 (0, 0, 0));
}
public void ResetPosition() {
// ハードコーディング。イケてない
theta = 90 * Mathf.Deg2Rad;
phai = 0 * Mathf.Deg2Rad;
r = 5;
UpdatePosition();
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
// スワイプの判定
if ((isMouseDown)|| Input.GetMouseButtonDown(0)) {
baseMousePos = Input.mousePosition;
isMouseDown = true;
isAutoRotate = false;
}
// 指離した時の処理
if (Input.GetMouseButtonUp(0)) {
isMouseDown = false;
basePinchZoomDistanceX = 0;
basePinchZoomDistanceY = 0;
}
// 回転
if (isMouseDown) {
// マウスグリグリ動かすことでここが変化する
Vector3 mousePos = Input.mousePosition;
Vector3 distanceMousePos = (mousePos - baseMousePos);
// スワイプの距離が極座標のθ,φに相当する
float swipeX = distanceMousePos.x * swipeMoveSpeedX;
float swipeY = distanceMousePos.y * swipeMoveSpeedY;
theta += swipeY;
phai += swipeX;
UpdatePosition();
baseMousePos = mousePos;
}
// ズーム
if (Input.GetKeyDown(KeyCode.Q)) {
r += diffR;
UpdatePosition();
} else if (Input.GetKeyDown(KeyCode.W)) {
r -= diffR;
UpdatePosition();
}
// リセット
if (Input.GetKeyDown(KeyCode.E)) {
ResetPosition();
}
if (Input.GetKeyDown(KeyCode.JoystickButton0)) {
ResetPosition();
}
}
}PolarCoordinates.cs
カメラに必要な挙動は基準点からの移動です。
今回つけた機能は以下の通りです。
- キーボードの方向キーでxy変位
- キーボードEで位置リセット
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraMove : MonoBehaviour {
public float diffPosition = 0.05f; // 移動単位
public void ResetPosition() {
this.transform.localPosition = new Vector3 (0, 0, 0);
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
// 移動
if (Input.GetKey(KeyCode.UpArrow)) {
this.transform.localPosition += new Vector3 (0, diffPosition, 0);
} else if (Input.GetKey(KeyCode.DownArrow)) {
this.transform.localPosition -= new Vector3 (0, diffPosition, 0);
} else if (Input.GetKey(KeyCode.LeftArrow)) {
this.transform.localPosition -= new Vector3 (diffPosition, 0, 0);
} else if (Input.GetKey(KeyCode.RightArrow)) {
this.transform.localPosition += new Vector3 (diffPosition, 0, 0);
}
// リセット
if (Input.GetKeyDown(KeyCode.E)) {
ResetPosition();
}
}
}CameraMove.cs
VR解剖図 HoloLensアプリ
via www.youtube.com
VRアプリ: ジャイロ機能
VRアプリでは画面操作はできません。
コントローラを用意しない場合は、主に首振りや視線で操作することになります。
今回は複雑なものは実装せず、3Dモデルを首振りで観察することを目指します。
スマホのジャイロ機能を使用します。
加えてVRアプリ化を施す必要があります。
現在、UnityでVRアプリを作ろうと思ったら例として以下の2つの選択肢が取れます。
- Google VR SDK for Unityを使う
- UnityのVR support機能を使う
UnityのVR機能はまだ新しいものですが、今後この組み込み機能を使うのがスタンダードとなるでしょう。
外部ライブラリに依存させたくないので今回はこちらを選択します。
ちなみに今回はAndroid向けに作っていきます。
VR設定
Minimum API Levelを要求通りに上げ、Bundle Identifierを適当に設定します。


山田涼太
回転、移動、ズームを組み合わせることで任意の点を観察することができるようになりました。