LoginSignup
2
1

More than 5 years have passed since last update.

【Unity】ARKit床面認識した後でスマホTapした位置にUnity Chanをランダムに配置する

Posted at

環境メモ
⭐️Mac OS Mojave バージョン10.14
⭐️Xcode version 10.0(10A255)
⭐️Unity 2018.2.14f1
⭐️iPhone7 IOS11.4.1

実際に動かした動画はこちら↓↓
https://twitter.com/nonnonkapibara/status/1061432598822453248

IMG_0104.png
IMG_0105.png

1.AssetsストアからUnity Chanのキャラクターをダウンロードする

「Optimize, SD Kohaku-Chanz!」を入力して、Downloadする

001.png

2.GameObjectを作り「UnityChanCollection」という名前にする
3.「Optimize SDKohaku-Chanz」のAssetsから「Prefab」を選択して
UnityChanCollectionの中に、それぞれのPrefabをDrag&Dropして入れる。
4.「UnityChanCollection」を選択し、Inspectorを開く。
5.「Unity AR Hit TestExample」の「Hit Transform」で「HitCubeParent」を選択する
002.png

6.全てのキャラクターを選択した状態で、「Update Mode」を「Animate Physics」にする
003.png

Animator Componentリファレンス
https://docs.unity3d.com/ja/current/Manual/class-Animator.html
004.png

7.Assetsを選択し、「UnityChanCollection」の中にあるキャラクターを全てAssets内にDrag&Dropして入れ込む
(Prefab化にする)
005.png

8.「UnityChanCollection」の中にあるキャラクターを全て削除する
(ソースコードの中で、キャラクターを生成する為)008.png

9.「Unity AR Hit TestExample」のソースコードを開く

UnityARHitTestExample
using System;
using System.Collections.Generic;

namespace UnityEngine.XR.iOS
{
    public class UnityARHitTestExample : MonoBehaviour
    {
        public Transform m_HitTransform;
        public float maxRayDistance = 30.0f;
        public LayerMask collisionLayer = 1 << 10;  //ARKitPlane layer
        // unity chanのGame Objectを宣言する
        public GameObject[] unityChanGameObject;
        // ランダム数
        private int unityChanNumber;

        // コメントアウト ここからStart
        /*
        bool HitTestWithResultType (ARPoint point, ARHitTestResultType resultTypes)
        {
            List<ARHitTestResult> hitResults = UnityARSessionNativeInterface.GetARSessionNativeInterface ().HitTest (point, resultTypes);
            if (hitResults.Count > 0) {
                foreach (var hitResult in hitResults) {
                    Debug.Log ("Got hit!");
                    m_HitTransform.position = UnityARMatrixOps.GetPosition (hitResult.worldTransform);
                    m_HitTransform.rotation = UnityARMatrixOps.GetRotation (hitResult.worldTransform);
                    Debug.Log (string.Format ("x:{0:0.######} y:{1:0.######} z:{2:0.######}", m_HitTransform.position.x, m_HitTransform.position.y, m_HitTransform.position.z));
                    return true;
                }
            }
            return false;
        }
        */
        // コメントアウト ここまで End

        /*
         * Unity Chanを生成する
         */
        void CreateUnityChan(Vector3 position) {
            unityChanNumber = Random.Range(0, unityChanGameObject.Length);
            // Instantiateは「ランタイムにUnityChanを生成する」
            GameObject character = Instantiate(unityChanGameObject[unityChanNumber], position, Quaternion.identity);
            // LookAtは「対象の Transform を設定し、その方向へと向かせます」
            character.transform.LookAt(unityChanGameObject[unityChanNumber].transform);
            // transform.rotationは、回転
            character.transform.rotation = Quaternion.Euler(0.0f, character.transform.rotation.eulerAngles.y, character.transform.rotation.z);
        }

        // Update is called once per frame
        void Update () {
            // コメントアウト Start
            /*
            #if UNITY_EDITOR   //we will only use this script on the editor side, though there is nothing that would prevent it from working on device
            if (Input.GetMouseButtonDown (0)) {
                Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
                RaycastHit hit;

                //we'll try to hit one of the plane collider gameobjects that were generated by the plugin
                //effectively similar to calling HitTest with ARHitTestResultType.ARHitTestResultTypeExistingPlaneUsingExtent
                if (Physics.Raycast (ray, out hit, maxRayDistance, collisionLayer)) {
                    //we're going to get the position from the contact point
                    m_HitTransform.position = hit.point;
                    Debug.Log (string.Format ("x:{0:0.######} y:{1:0.######} z:{2:0.######}", m_HitTransform.position.x, m_HitTransform.position.y, m_HitTransform.position.z));

                    //and the rotation from the transform of the plane collider
                    m_HitTransform.rotation = hit.transform.rotation;
                }
            }
            #else
            */
            //コメントアウト End

            if (Input.touchCount > 0 && m_HitTransform != null)
            {
                var touch = Input.GetTouch(0);
                if (touch.phase == TouchPhase.Began || touch.phase == TouchPhase.Moved)
                {
                    var screenPosition = Camera.main.ScreenToViewportPoint(touch.position);
                    ARPoint point = new ARPoint {
                        x = screenPosition.x,
                        y = screenPosition.y
                    };

                    List<ARHitTestResult> hitTestResultList = UnityARSessionNativeInterface.GetARSessionNativeInterface().HitTest(point, ARHitTestResultType.ARHitTestResultTypeFeaturePoint);
                    if (hitTestResultList.Count > 0) {
                        foreach(var entity in hitTestResultList) {
                            Vector3 position = UnityARMatrixOps.GetPosition(entity.worldTransform);
                            // Unity Chanを生成する
                            CreateUnityChan(new Vector3(position.x, position.y, position.z));
                        }
                    }

                    // コメントアウト Start
                    /*
                    // prioritize reults types
                    ARHitTestResultType[] resultTypes = {
                        //ARHitTestResultType.ARHitTestResultTypeExistingPlaneUsingGeometry,
                        ARHitTestResultType.ARHitTestResultTypeExistingPlaneUsingExtent, 
                        // if you want to use infinite planes use this:
                        //ARHitTestResultType.ARHitTestResultTypeExistingPlane,
                        //ARHitTestResultType.ARHitTestResultTypeEstimatedHorizontalPlane, 
                        //ARHitTestResultType.ARHitTestResultTypeEstimatedVerticalPlane, 
                        //ARHitTestResultType.ARHitTestResultTypeFeaturePoint
                    }; 

                    foreach (ARHitTestResultType resultType in resultTypes)
                    {
                        if (HitTestWithResultType (point, resultType))
                        {
                            return;
                        }
                    }
                    */
                    // コメントアウト End
                }
            }
            // コメントアウト
            //#endif
        }
    }
}

10.「UnityChanCollection」を選択し、「Unity Chan Game Object」を0から7に変更する
(キャラクターが7つあるので。)
008.png

①UTC_Default
スクリーンショット 2018-11-11 10.59.44.png

②UTC_SchoolUniform_summer
スクリーンショット 2018-11-11 11.00.13.png

③UTC_SchoolUniform_Winter
スクリーンショット 2018-11-11 11.00.42.png

④Misaki_SchoolUniform_Winter
スクリーンショット 2018-11-11 11.01.38.png

⑤Misaki_SchoolUniform_summer
スクリーンショット 2018-11-11 11.01.09.png

⑥Yuko_SchoolUniform_summer
スクリーンショット 2018-11-11 11.02.17.png

⑦Yuko_SchoolUniform_Winter
スクリーンショット 2018-11-11 11.02.24.png

11.Assetsの中の7つのキャラクターを順番に、Untiy Chan Objectの ElementにDrag&Dropしていく。
009.png
010.png

完成!!

12.最終的に、7つのキャラクターの「Rotaiton」を90にし、サイズも0.1にして小さくしました。
011.png

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1