2018年3月15日 星期四

Design cross platform AR framework in unity

其實我覺得這個應該要讓Unity自己來的(它最利害的不就是跨平台嗎?),但可能因為目前Google的ARCore才正式Release不久,而且相關Unity方面的整合也是Google自己寫的,不像IOS就是Unity自己官方提供的,所以就沒處理這部份。

目前的需求還是比較單純的,只要有一個定位的空間plane,然後把整個遊戲場景擺放在這個plane上面即可。架構如下:





















使用上只要先import相關package檔,並把ARSessionProcessor放到場景即可跟ARSessionProcessor這個Component溝通,並開始開發遊戲。做好後可直接在Android及IOS device上進行測試,並且可在PC上進行相關的測試驗證。

這邊是hit AR plane函式接口處理,範例如下:
protected virtual void Update()
{
  if (!_targetSessionProcessor)
            return;
  //取得螢幕點擊資訊
        Vector3 touchPosition;
#if UNITY_EDITOR_WIN
        if (!Input.GetMouseButtonUp(0))
            return;
        touchPosition = Input.mousePosition;
#else
        Touch touch;
        if (Input.touchCount < 1 || (touch = Input.GetTouch(0)).phase != TouchPhase.Began)
            return;
        touchPosition = touch.position;
#endif
  //呼叫RayCast相關函式,取得點擊AR plane相關資訊
        Ray outTestRay;
        bool outHitNewPlane;
        Vector3 outHitPoint;
        Quaternion outDestRotation;
        if (!_targetSessionProcessor.ProcessARRayCast(ref touchPosition, out outHitNewPlane,
   out outTestRay, out outHitPoint, out outDestRotation))
            return;
  //假如點擊到新的AR plane,就處理相關場景功能(場景產生或搬移場景)
        if (outHitNewPlane)
        {
            if ((!_rootTransform) && (_scenePrefab))
            {
                GameObject go = Instantiate(_scenePrefab);
                if (go)
                {
                    _rootTransform = go.transform;
                    _sceneBoxCollider = go.GetComponentInChildren();
                }
            }
            outHitPoint.y += _offestHeight;
            _rootTransform.position = outHitPoint;
            _rootTransform.rotation = outDestRotation;
            return;
        }

        if ((!_rootTransform) || (!_sceneBoxCollider))
            return;
  //如果點到的是同一個plane,就處理物件功能(產生物件或調整物件位置)
        RaycastHit hitInfo;
        if (!_sceneBoxCollider.Raycast(outTestRay, out hitInfo, 100.0f))
            return;

        if (!_objectTransform)
        {
            GameObject go = Instantiate(_objectPrefab, _rootTransform);
            if (go)
                _objectTransform = go.transform;
        }
        _objectTransform.position = hitInfo.point;
}

相關Demo影片:




Dream continues in...

沒有留言:

張貼留言