環境メモ
⭐️Mac OS Mojave バージョン10.14
⭐️Unity 2019.1.9f1
⭐️Xcode11.2
⭐️iPhone7(IOS 12.2)
UnityとARKitで、ねずみちゃんAR(ねずみちゃんTapでカウントアップ)を作る。
↓↓実際に動かした動画
😍Unity AR🤩
— non (@nonnonkapibara) January 2, 2020
🌅あけおめですぅ🌅
🐭ねずみちゃん🐭AR📲作ってみたよぉ。
(ねずみちゃんTapでパーティクル表示して、カウントアップする)😊
チーズ🧀から、ねずみちゃんが出てくるよぉ😘#unity3d #ARhttps://t.co/bbXMZjJcXu pic.twitter.com/w8GaP2KR77
準備
まず、ねずみちゃんを表示する「チーズ」モデルをBlenderで作成。
cheese.fbxで出力する。
mouse.fbxで出力する
ここからUnity
Unityを起動する。
Unity AR Kitを取り込む。
【Unity】Unity ARKit Pluginが無いのでUnity-Technologies-unity-arkit-plugin-b3de628acfac.zipを使う
https://qiita.com/nonkapibara/items/3800d4ff3c56912073df
UnityARKitPlugin - Examples - UnityARKitScene
を選ぶ
RandomCube
HitCubeParent
GeneratePlanes
ARKitControl
PointCloudExample
AR3DOFCameraManager
は不要なので削除する

準備で用意した、「チーズ」モデルと、ねずみちゃんモデルをUnityに取り込む
「チーズ」モデルをPrefabにして、タグを「cheese」 にする
たくさんのチーズを1つにまとめる。
Create Emptyを作成し、その中に、たくさん作ったチーズを入れる

タグを「mouse」にする。
ねずみちゃんに、Colliderを設定する



次に、チーズの床を作る。(ねずみちゃんをDownした時に、隠れるようにする)
3D ObjectーPlanを選択する

チーズの床を「occlusionPlaneMaterial.mat」にする
UnityARKitPlugin - Examples - Common - Materials
「occlusionPlaneMaterial.mat」を選択する

ねずみちゃんTapでカウントアップ


ねずみちゃんTapでパーティクルを表示する





ソースコード
Create Emptyで、Game Objectを作り、
「floorScript」と「mouseHitScript」を配置する
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.iOS;
public class floorScript : MonoBehaviour
{
bool cheeseViewed = false; // チーズモデル描画
public GameObject cheeaseObj; // チーズ
public GameObject mouseObj; // ネズミ
public void CreateMouse(GameObject mouse)
{
foreach(Transform trans in mouse.transform)
{
GameObject lastLayer = trans.gameObject;
if (lastLayer.tag == "cheese") {
Vector3 position = lastLayer.transform.position;
Instantiate(mouseObj, position, mouseObj.transform.rotation);
}
}
}
void HitTest(ARPoint point)
{
List<ARHitTestResult> hitResults = UnityARSessionNativeInterface.GetARSessionNativeInterface().HitTest(point, ARHitTestResultType.ARHitTestResultTypeExistingPlaneUsingExtent);
if (hitResults.Count > 0)
{
GameObject cheese = Instantiate(cheeaseObj);
cheese.transform.position = UnityARMatrixOps.GetPosition(hitResults[0].worldTransform);
cheese.transform.rotation = UnityARMatrixOps.GetRotation(hitResults[0].worldTransform);
// ネズミを生成する
CreateMouse(cheese);
this.cheeseViewed = true; // チーズモデル描画済み
}
}
void Update()
{
if ((!cheeseViewed && Input.touchCount > 0)
&& (Input.GetTouch(0).phase == TouchPhase.Began))
{
var touchPosition = Camera.main.ScreenToViewportPoint(Input.GetTouch(0).position);
ARPoint arPoint = new ARPoint
{
x = touchPosition.x, y = touchPosition.y
};
HitTest(arPoint);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class mouseHitScript : MonoBehaviour
{
int hitCount = 0;
void Update()
{
// ねずみちゃんTapする
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit = new RaycastHit();
if (Physics.Raycast(ray, out hit))
{
pointMode(hit);
}
}
}
void pointMode(RaycastHit hit)
{
// ねずみちゃんをTapしたらポイントをカウントアップする
if (hit.transform.gameObject.CompareTag("mouse"))
{
hit.transform.gameObject.GetComponent<mouseScript>().HitProcess();
hitCount++;
GameObject.Find("Point").GetComponent<Text>().text = "Point: " + hitCount.ToString();
}
}
}
ねずみちゃんPrefabに、「mouseScript」を配置し、パーティクルをDrag&Dropして配置する
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class mouseScript : MonoBehaviour
{
Vector3 mouseViewPosition; // ねずみちゃん表示位置
Vector3 mouseViewDownPosition; // ねずみちゃん下がった時の位置
bool mouseUppedFlag = true; // ねずみちゃんUP
float timeCount = 0;
public GameObject effect;
void Start()
{
Vector3 pos = transform.position;
pos.y += 0.05f;
this.mouseViewPosition = pos;
this.mouseViewDownPosition = this.mouseViewPosition - new Vector3(0, 0.1f, 0);
// ねずみちゃんDown
DownUnder();
}
void UpAbove()
{
transform.position = this.mouseViewPosition;
mouseUppedFlag = true; // ねずみちゃんUP
}
void DownUnder()
{
transform.position = this.mouseViewDownPosition;
mouseUppedFlag = false; // ねずみちゃんDown
}
private void Update()
{
this.timeCount += Time.deltaTime;
if (this.timeCount > 3.0f)
{
this.timeCount = 0;
if (this.mouseUppedFlag) {
DownUnder();
} else {
UpAbove();
}
}
}
public void HitProcess()
{
GameObject particleObj = Instantiate(effect, transform.position + new Vector3(0, 0.04f, 0), effect.transform.rotation);
Destroy(particleObj, 1.0f);
this.timeCount = 0;
// ねずみちゃんを下に下げる
DownUnder();
}
}