/// <summary>
        /// The Unity OnEnable() method.
        /// </summary>
        public void OnEnable()
        {
            _timeSinceStart   = 0.0f;
            _isReturning      = false;
            _isHosting        = false;
            _hitPose          = null;
            _anchorComponent  = null;
            _qualityIndicator = null;
            _cachedComponents.Clear();

            InstructionBar.SetActive(true);
            NamePanel.SetActive(false);
            CopyPanel.SetActive(false);
            InputFieldWarning.SetActive(false);
            ShareButton.gameObject.SetActive(false);
            Controller.PlaneGenerator.SetActive(true);

            switch (Controller.Mode)
            {
            case PersistentCloudAnchorsController.ApplicationMode.Ready:
                ReturnToHomePage("Invalid application mode, returning to home page...");
                break;

            case PersistentCloudAnchorsController.ApplicationMode.Hosting:
            case PersistentCloudAnchorsController.ApplicationMode.Resolving:
                InstructionText.text = "Detecting flat surface...";
                DebugText.text       = "ARCore is preparing for " + Controller.Mode;
                break;
            }
        }
        /// <summary>
        /// The Unity OnDisable() method.
        /// </summary>
        public void OnDisable()
        {
            if (_pendingTask.Count > 0)
            {
                Debug.LogFormat("Cancelling pending tasks for {0} Cloud Anchor(s): {1}",
                                _pendingTask.Count,
                                string.Join(",", new List <string>(_pendingTask).ToArray()));
                foreach (string id in _pendingTask)
                {
                    XPSession.CancelCloudAnchorAsyncTask(id);
                }

                _pendingTask.Clear();
            }

            if (_qualityIndicator != null)
            {
                Destroy(_qualityIndicator.gameObject);
                _qualityIndicator = null;
            }

            if (_anchorComponent != null)
            {
                Destroy(_anchorComponent.gameObject);
                _anchorComponent = null;
            }

            if (_cachedComponents.Count > 0)
            {
                foreach (var anchor in _cachedComponents)
                {
                    Destroy(anchor.gameObject);
                }

                _cachedComponents.Clear();
            }
        }
        private void PerformHitTest(Vector2 touchPos)
        {
            var planeType = DetectedPlaneType.HorizontalUpwardFacing;

            if (Application.platform == RuntimePlatform.IPhonePlayer)
            {
#if ARCORE_IOS_SUPPORT
                var     session       = UnityARSessionNativeInterface.GetARSessionNativeInterface();
                var     viewportPoint = Controller.MainCamera.ScreenToViewportPoint(touchPos);
                ARPoint arPoint       = new ARPoint
                {
                    x = viewportPoint.x,
                    y = viewportPoint.y
                };

                _hitResultList = session.HitTest(arPoint,
                                                 ARHitTestResultType.ARHitTestResultTypeExistingPlaneUsingExtent);
                if (_hitResultList.Count > 0)
                {
                    // Fetch the closest hit result.
                    int minDistanceIndex = GetMinDistanceIndex(_hitResultList);

                    string identifier = _hitResultList[minDistanceIndex].anchorIdentifier;
                    if (_arPlaneAligmentMapping.ContainsKey(identifier))
                    {
                        planeType = _arPlaneAligmentMapping[identifier] ==
                                    ARPlaneAnchorAlignment.ARPlaneAnchorAlignmentVertical ?
                                    DetectedPlaneType.Vertical : DetectedPlaneType.HorizontalUpwardFacing;
                    }
                    else
                    {
                        Debug.LogWarningFormat("Didn't find anchor identifier: {0}", identifier);
                        return;
                    }

                    Pose hitPose = new Pose();
                    hitPose.position = UnityARMatrixOps.GetPosition(
                        _hitResultList[minDistanceIndex].worldTransform);
                    if (planeType == DetectedPlaneType.Vertical)
                    {
                        hitPose.rotation = UnityARMatrixOps.GetRotation(
                            _hitResultList[minDistanceIndex].worldTransform);
                    }
                    else
                    {
                        // Point the hitPose rotation roughly away from the raycast/camera
                        // to match ARCore.
                        hitPose.rotation.eulerAngles =
                            new Vector3(0.0f, Controller.MainCamera.transform.eulerAngles.y, 0.0f);
                    }

                    _hitPose = hitPose;
                    var anchorGO = new GameObject("ARUserAnchor");
                    _anchorComponent            = anchorGO.AddComponent <UnityARUserAnchorComponent>();
                    anchorGO.transform.position = hitPose.position;
                    anchorGO.transform.rotation = hitPose.rotation;
                }
#endif
            }
            else
            {
                TrackableHit arcoreHitResult = new TrackableHit();
                if (Frame.Raycast(touchPos.x, touchPos.y, TrackableHitFlags.PlaneWithinPolygon,
                                  out arcoreHitResult))
                {
                    DetectedPlane plane = arcoreHitResult.Trackable as DetectedPlane;
                    if (plane == null)
                    {
                        Debug.LogWarning("Hit test result has invalid trackable type: " +
                                         arcoreHitResult.Trackable.GetType());
                        return;
                    }

                    planeType        = plane.PlaneType;
                    _hitPose         = arcoreHitResult.Pose;
                    _anchorComponent =
                        arcoreHitResult.Trackable.CreateAnchor(arcoreHitResult.Pose);
                }
            }

            if (_anchorComponent != null)
            {
                //Instantiate(CloudAnchorPrefab, _anchorComponent.transform); //建立錨點
                if (!SingleObj <PersistentCloudAnchorsCreator> .obj.addPCA(_anchorComponent.transform))   //test
                {
                    return;
                }
                SingleObj <PersistentCloudAnchorsCreator> .obj.switchSelPanel();

                // Attach map quality indicator to this pawn.
                var indicatorGO =
                    Instantiate(MapQualityIndicatorPrefab, _anchorComponent.transform);
                _qualityIndicator = indicatorGO.GetComponent <MapQualityIndicator>();
                _qualityIndicator.DrawIndicator(planeType, Controller.MainCamera);

                InstructionText.text = " To save this location, walk around the object to " +
                                       "capture it from different angles";
                DebugText.text = "Waiting for sufficient mapping quaility...";

                // Hide plane generator so users can focus on the object they placed.
                Controller.PlaneGenerator.SetActive(false);
            }
        }