Beispiel #1
0
 /// <summary>
 /// Upon game start, any ASL Objects in the scene do not have synchronized IDs. This function changes their ID to be synced with other clients
 /// </summary>
 /// <param name="_id">The new id for _object</param>
 /// <param name="_object">The ASL object that will be getting a new id</param>
 /// <returns></returns>
 private bool InitializeStartObject(string _id, ASLObject _object)
 {
     if (ASLHelper.m_ASLObjects.ContainsKey(_id))
     {
         _object._LocallySetID(_id);
         _object._LocallyRemoveReleaseCallback();
         return(true);
     }
     else
     {
         Debug.LogError("Attempted to set the id of an object to a value that does not exist in our dictionary. If this was intended, then" +
                        " add this object to the m_ASLObjects dictionary first.");
         return(false);
     }
 }
Beispiel #2
0
        /// <summary>
        /// Creates an ARCore Cloud Anchor at the location the user tapped and passed into it. This function can be used to set the world origin or just a normal cloud anchor.
        /// It is advisable to only have 1 user in your application set cloud anchors.
        /// </summary>
        /// <param name="_hitResults">Holds information about where the user tapped on the screen. This variable should be created using the ARWorldOriginHelper Raycast method </param>
        /// <param name="_anchorObjectPrefab">The ASL object you want to have located at the cloud anchor. If you don't want any object to be located at the cloud anchor, you can pass in null.
        /// Doing so will create an empty gameobject - thus making it invisible to users</param>
        /// <param name="_myPostCreateCloudAnchorFunction">This is the function you want to call after a cloud anchor has successfully been created. Only the user that called this function
        /// will execute this function - it is not sent to other users. This is a good way to move or create objects after a cloud anchor has been created.</param>
        /// <param name="_waitForAllUsersToResolve">This determines if users should wait to setup (and if they are the caller of this function, to execute the _myPostCreateCloudAnchorFunction)
        /// the cloud anchor once they receive and find it, or if they should wait for all users to receive and find it first before executing anything. The default is to wait for all users
        /// and is the suggested value as not waiting as the potential to cause synchronization problems.</param>
        /// <param name="_setWorldOrigin">This determines if this cloud anchor should be used to set the world origin for all users or not. If you are setting the world origin, you should do
        /// so right away in your app and as the first (if you have more than 1) cloud anchor created. You should never set the world origin more than once.</param>
        public static void CreateARCoreCloudAnchor(Pose?_hitResults, ASLObject _anchorObjectPrefab = null, ASLObject.PostCreateCloudAnchorFunction _myPostCreateCloudAnchorFunction = null,
                                                   bool _waitForAllUsersToResolve = true, bool _setWorldOrigin = true)
        {
#if UNITY_ANDROID || UNITY_IOS
            if (m_ARCloudAnchor != null)
            {
                Debug.LogError("You can only resolve 1 Cloud Anchor at a time. " + m_ARCloudAnchor.name + " is currently being resolved...");
                return;
            }
            if (_anchorObjectPrefab != null)
            {
                if (!_anchorObjectPrefab.m_Mine)
                {
                    Debug.LogError("You must claim the ASL object before setting it as an anchor");
                    return;
                }
            }
            Debug.Log("Creating the cloud anchor now...");

            //Create local anchor at hit location
            ARAnchor localAnchor = ARWorldOriginHelper.GetInstance().m_ARAnchorManager.AddAnchor((Pose)_hitResults);
            localAnchor.name = "Local anchor created when creating cloud anchor";

            //Create CLoud anchor
            m_ARCloudAnchor = ARWorldOriginHelper.GetInstance().m_ARAnchorManager.HostCloudAnchor(localAnchor);

            if (m_ARCloudAnchor == null)
            {
                Debug.LogError("Failed to create a cloud anchor.");
                return;
            }

            ARWorldOriginHelper.GetInstance().StartCoroutine(ARWorldOriginHelper.GetInstance().WaitForCloudAnchorToBeCreated(m_ARCloudAnchor, (Pose)_hitResults,
                                                                                                                             _anchorObjectPrefab, _myPostCreateCloudAnchorFunction,
                                                                                                                             _waitForAllUsersToResolve, _setWorldOrigin));

            //Reset
            m_ARCloudAnchor = null;
#else
            Debug.LogError("Can only create cloud anchors on mobile devices.");
#endif
        }
Beispiel #3
0
        /// <summary>
        /// Creates an ARCore Cloud Anchor at the location the user tapped and passed into it. This function can be used to set the world origin or just a normal cloud anchor.
        /// It is advisable to only have 1 user in your application set cloud anchors.
        /// </summary>
        /// <param name="_hitResults">Holds information about where the user tapped on the screen. This variable should be created using the ARWorldOriginHelper Raycast method </param>
        /// <param name="_anchorObjectPrefab">The ASL object you want to have located at the cloud anchor. If you don't want any object to be located at the cloud anchor, you can pass in null.
        /// Doing so will create an empty gameobject - thus making it invisible to users</param>
        /// <param name="_myPostCreateCloudAnchorFunction">This is the function you want to call after a cloud anchor has successfully been created. Only the user that called this function
        /// will execute this function - it is not sent to other users. This is a good way to move or create objects after a cloud anchor has been created.</param>
        /// <param name="_waitForAllUsersToResolve">This determines if users should wait to setup (and if they are the caller of this function, to execute the _myPostCreateCloudAnchorFunction)
        /// the cloud anchor once they receive and find it, or if they should wait for all users to receive and find it first before executing anything. The default is to wait for all users
        /// and is the suggested value as not waiting as the potential to cause synchronization problems.</param>
        /// <param name="_setWorldOrigin">This determines if this cloud anchor should be used to set the world origin for all users or not. If you are setting the world origin, you should do
        /// so right away in your app and as the first (if you have more than 1) cloud anchor created. You should never set the world origin more than once.</param>
        public static void CreateARCoreCloudAnchor(TrackableHit _hitResults, ASLObject _anchorObjectPrefab = null, ASLObject.PostCreateCloudAnchorFunction _myPostCreateCloudAnchorFunction = null,
                                                   bool _waitForAllUsersToResolve = true, bool _setWorldOrigin = true)
        {
            if (_anchorObjectPrefab != null)
            {
                if (!_anchorObjectPrefab.m_Mine)
                {
                    Debug.LogError("You must claim the ASL object before setting it as an anchor");
                }
                return;
            }
            //Create local anchor at hit location
            Anchor localAnchor = _hitResults.Trackable.CreateAnchor(_hitResults.Pose);

            localAnchor.name = "Local anchor created when creating cloud anchor";

            //Create CLoud anchor
            XPSession.CreateCloudAnchor(localAnchor).ThenAction(result =>
            {
                //If failed to host
                if (result.Response != CloudServiceResponse.Success)
                {
                    Debug.LogError("Failed to host Cloud Anchor: " + result.Response);
                    return; //Break out
                }
                //Successful:
                Debug.Log("Successfully created and saved Cloud Anchor: " + result.Anchor.CloudId);

                if (_anchorObjectPrefab == null)
                {
                    //Uncomment the line below to aid in visual debugging (helps display the cloud anchor)
                    //_anchorObjectPrefab = GameObject.CreatePrimitive(PrimitiveType.Cube).AddComponent<ASLObject>(); //if null, then create empty game object
                    _anchorObjectPrefab = new GameObject().AddComponent <ASLObject>();
                    _anchorObjectPrefab._LocallySetAnchorID(result.Anchor.CloudId); //Add ASLObject component to this anchor and set its anchor id variable
                    _anchorObjectPrefab._LocallySetID(result.Anchor.CloudId);       //Locally set the id of this object to be that of the anchor id (which is unique)

                    //Add this anchor object to our ASL dictionary using the anchor id as its key. All users will do this once they resolve this cloud anchor to ensure they still in sync.
                    m_ASLObjects.Add(result.Anchor.CloudId, _anchorObjectPrefab.GetComponent <ASLObject>());
                    //_anchorObjectPrefab.GetComponent<Material>().color = Color.magenta;
                    _anchorObjectPrefab.transform.localScale = new Vector3(0.04f, 0.04f, 0.04f); //Set scale to be 4 cm
                }
                else
                {
                    _anchorObjectPrefab.GetComponent <ASLObject>()._LocallySetAnchorID(result.Anchor.CloudId); //Set anchor id variable
                    _anchorObjectPrefab.transform.localScale = new Vector3(0.05f, 0.05f, 0.05f);               //Set scale to be 5 cm
                }

                //Send Resolve packet using _anchorObjectPrefab
                _anchorObjectPrefab.GetComponent <ASLObject>().SendCloudAnchorToResolve(_setWorldOrigin, _waitForAllUsersToResolve);

                if (_waitForAllUsersToResolve)
                {
                    //Send packet to relay server letting it know this user is ready
                    using (RTData data = RTData.Get())
                    {
                        data.SetString((int)GameController.DataCode.Id, _anchorObjectPrefab.m_Id);
                        GameSparksManager.Instance().GetRTSession().SendData((int)GameSparksManager.OpCode.ResolvedCloudAnchor, GameSparksRT.DeliveryIntent.RELIABLE, data);
                    }
                    _anchorObjectPrefab.StartWaitForAllUsersToResolveCloudAnchor(result, _setWorldOrigin, _myPostCreateCloudAnchorFunction, _hitResults);
                }
                else //Don't wait for users to know about this cloud anchor
                {
                    _anchorObjectPrefab.GetComponent <ASLObject>()._LocallySetCloudAnchorResolved(true);
                    _anchorObjectPrefab.StartWaitForAllUsersToResolveCloudAnchor(result, _setWorldOrigin, _myPostCreateCloudAnchorFunction, _hitResults);
                }
            });
        }
        /// <summary>
        /// Waits for the cloud anchor to be created so it can then send it's information to other users
        /// </summary>
        /// <param name="_cloudAnchor">The cloud anchor that is being created</param>
        /// <param name="_hitResult">The location where it was created</param>
        /// <param name="_anchorObjectPrefab">The object that will be attached to the cloud anchor</param>
        /// <param name="_myPostCreateCloudAnchorFunction">The function to call after creating the cloud anchor</param>
        /// <param name="_waitForAllUsersToResolve">Flag indicating to wait or not for all users to resolve before calling the post create function</param>
        /// <param name="_setWorldOrigin">Flag indicating to set this cloud anchor as the world origin or not</param>
        /// <returns>Nothing - just waits until the cloud anchor succeeds or fails</returns>
        public IEnumerator WaitForCloudAnchorToBeCreated(ARCloudAnchor _cloudAnchor, Pose _hitResult, ASLObject _anchorObjectPrefab = null,
                                                         ASLObject.PostCreateCloudAnchorFunction _myPostCreateCloudAnchorFunction   = null,
                                                         bool _waitForAllUsersToResolve = true, bool _setWorldOrigin = true)
        {
            while (_cloudAnchor.cloudAnchorState == CloudAnchorState.TaskInProgress)
            {
                yield return(new WaitForEndOfFrame());
            }

            if (_cloudAnchor.cloudAnchorState == CloudAnchorState.Success)
            {
                //Successful:
                Debug.Log("Successfully Resolved cloud anchor: " + _cloudAnchor.cloudAnchorId + " for object: " + _anchorObjectPrefab?.m_Id);
                if (_anchorObjectPrefab == null)
                {
                    //Uncomment the line below to aid in visual debugging (helps display the cloud anchor)
                    //_anchorObjectPrefab = GameObject.CreatePrimitive(PrimitiveType.Cube).AddComponent<ASLObject>(); //if null, then create empty game object
                    _anchorObjectPrefab = new GameObject().AddComponent <ASLObject>();
                    _anchorObjectPrefab._LocallySetAnchorID(_cloudAnchor.cloudAnchorId); //Add ASLObject component to this anchor and set its anchor id variable

                    _anchorObjectPrefab._LocallySetID(Guid.NewGuid().ToString());        //Locally set the id of this object to a new id

                    //Add this anchor object to our ASL dictionary using the anchor id as its key. All users will do this once they resolve this cloud anchor to ensure they still in sync.
                    ASLHelper.m_ASLObjects.Add(_anchorObjectPrefab.m_Id, _anchorObjectPrefab.GetComponent <ASLObject>());
                    //_anchorObjectPrefab.GetComponent<Material>().color = Color.magenta;
                    _anchorObjectPrefab.transform.localScale = new Vector3(0.05f, 0.05f, 0.05f); //Set scale to be 5 cm
                }
                else
                {
                    _anchorObjectPrefab.GetComponent <ASLObject>()._LocallySetAnchorID(_cloudAnchor.cloudAnchorId); //Set anchor id variable
                    _anchorObjectPrefab.transform.localScale = new Vector3(0.05f, 0.05f, 0.05f);                    //Set scale to be 5 cm
                }
                //Send Resolve packet using _anchorObjectPrefab
                _anchorObjectPrefab.GetComponent <ASLObject>().SendCloudAnchorToResolve(_setWorldOrigin, _waitForAllUsersToResolve);

                if (_waitForAllUsersToResolve)
                {
                    byte[]    id      = Encoding.ASCII.GetBytes(_anchorObjectPrefab.m_Id);
                    RTMessage message = GameLiftManager.GetInstance().CreateRTMessage(GameLiftManager.OpCode.ResolvedCloudAnchor, id);
                    GameLiftManager.GetInstance().m_Client.SendMessage(message);

                    _anchorObjectPrefab.StartWaitForAllUsersToResolveCloudAnchor(_cloudAnchor, _setWorldOrigin, _myPostCreateCloudAnchorFunction, _hitResult);
                }
                else //Don't wait for users to know about this cloud anchor
                {
                    _anchorObjectPrefab.GetComponent <ASLObject>()._LocallySetCloudAnchorResolved(true);
                    _anchorObjectPrefab.StartWaitForAllUsersToResolveCloudAnchor(_cloudAnchor, _setWorldOrigin, _myPostCreateCloudAnchorFunction, _hitResult);
                }
            }
            else
            {
                Debug.LogError("Failed to host Cloud Anchor " + _cloudAnchor.name + " " + _cloudAnchor.cloudAnchorState.ToString());
            }
        }