クマテクブログ

日々のメモ

iOS11のARKitをUnityから使用してみる

iOS11が発表されiOSにARKitという新しいARサポートが入りました。
こちらはUnityやUnreal EngineからPluginを通して使用する事できるそうなのでUnityを使ってオブジェクトを表示してみました。

必要なもの

  • iOS11にUpdateしたiPhone 6s以上の端末(ARは実機じゃないと確認できません)
  • XCode 9(現在β)
  • Unity 5.6.1p1以上
  • Unity ARKit Plugin

STEP

#1. Unity ARKit Pluginをプロジェクトにインポート
#2. Player SettingsのCamera Usage Descriptionを設定(これを設定しないとアプリがクラッシュします。)
#3. Main CameraにUnityARVideoコンポーネントを追加し、UnityARVideoのClear MaterialにYUVMaterialを設定
#4. UnityARGeneratePlane Componentをシーンのオブジェクトに追加(これを追加すると平面を検知してくれるようになります。)

これで準備は整いました。
あとは下記のようなソースを追加してみます。
平面の検知後、画面をタップした所に平面があればオブジェクトを生成するというスクリプトになります。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.iOS;

public class Spawner : MonoBehaviour
{
	public GameObject catPrefab;
	public float createHeight;
	private MaterialPropertyBlock _props;

	void Start()
	{
		_props = new MaterialPropertyBlock();
	}

	void CreateCat(Vector3 position)
	{
		Instantiate(catPrefab, position, Quaternion.identity);
	}

	void Update()
	{
		if (Input.touchCount > 0 )
		{
			var touch = Input.GetTouch(0);
			if (touch.phase == TouchPhase.Began)
			{
				var screenPosition = Camera.main.ScreenToViewportPoint(touch.position);

				ARPoint point = new ARPoint {
					x = screenPosition.x,
					y = screenPosition.y
				};

				List<ARHitTestResult> hitResults = UnityARSessionNativeInterface.GetARSessionNativeInterface().HitTest (point, 
				ARHitTestResultType.ARHitTestResultTypeExistingPlaneUsingExtent);
                
				if (hitResults.Count > 0)
				{
					foreach (var hitResult in hitResults)
					{
						Vector3 position = UnityARMatrixOps.GetPosition (hitResult.worldTransform);
						CreateCat (new Vector3 (position.x, position.y + createHeight, position.z));
						break;
					}
				}
			}
		}
	}
}

無事カメラ空間の中にオブジェクトが生成されました。

https://raw.githubusercontent.com/wiki/cyario/ARKitSample/images/cats.gif

RigitBodyで生成したオブジェクトに重力をつけ検知した平面と衝突判定をつけてあげればこのようにテーブルから転げ落ちる表現も簡単に実装できます。

またStencil Shaderを使ったりして平面検知したPlaneの後ろに回ったオブジェクトは表示させないようにしたりすると綺麗に見えると思います。