// Uncomment this if you have the Touch controller classes in your project //#define USE_OVRINPUT using Oculus.Platform; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; /** * This class shows a very simple way to integrate setting the Rich Presence * with a destination and how to respond to a user's app launch details that * include the destination they wish to travel to. */ public class RichPresenceSample : MonoBehaviour { /** * Sets extra fields on the rich presence */ // Optional message to override the deep-link message set in the developer // dashboard. This is where you can specify the ID for a room, party, // matchmaking pool or group server. There should be no whitespaces. public string DeeplinkMessageOverride; // A boolean to indicate whether the destination is joinable. You can check // the current capacity against the max capacity to determine whether the room // is joinable. public bool IsJoinable; // A boolean to indicate whether the current user is idling in the app. public bool IsIdle; // The current capacity at that destination. Used for displaying with the // extra context when it's set to RichPresenceExtraContext.CurrentCapacity public uint CurrentCapacity; // The maximum capacity of the destination. Can be used with current capacity // to see if a user can join. For example, when used with a room, set the max // capacity of the destination to the max capacity of the room. // Used for displaying with the extra context when it's set to // RichPresenceExtraContext.CurrentCapacity public uint MaxCapacity; // The time the current match starts or started. Used for displaying with the // extra context when it's set to RichPresenceExtraContext.StartedAgo public System.DateTime StartTime = System.DateTime.Now; // The time the current match ends. Used for displaying with the // extra context when it's set to RichPresenceExtraContext.EndingIn public System.DateTime EndTime = System.DateTime.Now.AddHours(2); // Extra information to set the user’s presence correctly. This should give // more insight for people to decided whether or not to join the user. public RichPresenceExtraContext ExtraContext = RichPresenceExtraContext.LookingForAMatch; public Text InVRConsole; public Text DestinationsConsole; private List DestinationAPINames = new List(); private ulong LoggedInUserID = 0; // Start is called before the first frame update void Start() { UpdateConsole("Init Oculus Platform SDK..."); Core.AsyncInitialize().OnComplete(message => { if (message.IsError) { // Init failed, nothing will work UpdateConsole(message.GetError().Message); } else { /** * Get the deeplink message when the app starts up */ UpdateConsole("Init complete!\n" + GetAppLaunchDetails()); /** * Get and cache the Logged in User ID for future queries */ Users.GetLoggedInUser().OnComplete(OnLoggedInUser); /** * Get the list of destinations defined for this app from the developer portal */ RichPresence.GetDestinations().OnComplete(OnGetDestinations); /** * Listen for future deeplink message changes that might come in */ ApplicationLifecycle.SetLaunchIntentChangedNotificationCallback(OnLaunchIntentChangeNotif); } }); } /** * Setting the rich presence */ void SetPresence() { var options = new RichPresenceOptions(); // Only Destination API Name is required options.SetApiName(DestinationAPINames[DestinationIndex]); // Override the deeplink message if you like, otherwise it will use the one found in the destination if (!string.IsNullOrEmpty(DeeplinkMessageOverride)) { options.SetDeeplinkMessageOverride(DeeplinkMessageOverride); } // Set is Joinable to let other players deeplink and join this user via the presence options.SetIsJoinable(IsJoinable); // Set if the user is idle options.SetIsIdle(IsIdle); // Used when displaying the current to max capacity on the user's presence options.SetCurrentCapacity(CurrentCapacity); options.SetMaxCapacity(MaxCapacity); // Used to display how long since this start / when will this end options.SetStartTime(StartTime); options.SetEndTime(EndTime); // Used to display extra info like the capacity, start/end times, or looking for a match options.SetExtraContext(ExtraContext); UpdateConsole("Setting Rich Presence to " + DestinationAPINames[DestinationIndex] + " ..."); // Here we are setting the rich presence then fetching it after we successfully set it RichPresence.Set(options).OnComplete(message => { if (message.IsError) { UpdateConsole(message.GetError().Message); } else { // Note that Users.GetLoggedInUser() does not do a server fetch and will // not get an updated presence status Users.Get(LoggedInUserID).OnComplete(message2 => { if (message2.IsError) { UpdateConsole("Success! But rich presence is unknown!"); } else { UpdateConsole("Rich Presence set to:\n" + message2.Data.Presence + "\n" + message2.Data.PresenceDeeplinkMessage + "\n" + message2.Data.PresenceDestinationApiName); } }); } }); } /** * Clearing the rich presence */ void ClearPresence() { UpdateConsole("Clearing Rich Presence..."); RichPresence.Clear().OnComplete(message => { if (message.IsError) { UpdateConsole(message.GetError().Message); } else { // Clearing the rich presence then fetching the user's presence afterwards Users.Get(LoggedInUserID).OnComplete(message2 => { if (message2.IsError) { UpdateConsole("Rich Presence cleared! But rich presence is unknown!"); } else { UpdateConsole("Rich Presence cleared!\n" + message2.Data.Presence + "\n"); } }); } }); } /** * Getting the deeplink information off the app launch details. When a user requests * to travel to a destination from outside your app, their request will be found here * Get the info to bring the user to the expected destination. */ string GetAppLaunchDetails() { var launchDetails = ApplicationLifecycle.GetLaunchDetails(); // The other users this user expect to see after traveling to the destination // If there is conflicting data between the inputted users and destination, // favor using the users. // For example, if user A & destination 1 was passed in, but user A is now // in destination 2, it is better to bring the current user to destination 2 // if possible. var users = launchDetails.UsersOptional; var usersCount = (users != null) ? users.Count : 0; // The deeplink message, this should give enough info on how to go the // destination in the app. var deeplinkMessage = launchDetails.DeeplinkMessage; // The API Name of the destination. You can set the user to this after // navigating to the app var destinationApiName = launchDetails.DestinationApiName; var detailsString = "-Deeplink Message:\n" + deeplinkMessage + "\n-Api Name:\n" + destinationApiName + "\n-Users:\n"; if (usersCount > 0) { foreach(var user in users) { detailsString += user.OculusID + "\n"; } } else { detailsString += "null\n"; } detailsString += "\n"; return detailsString; } // User has interacted with a deeplink outside this app void OnLaunchIntentChangeNotif(Oculus.Platform.Message message) { if (message.IsError) { UpdateConsole(message.GetError().Message); } else { UpdateConsole("Updated launch details:\n" + GetAppLaunchDetails()); } } void OnGetDestinations(Message message) { if (message.IsError) { UpdateConsole("Could not get the list of destinations!"); } else { foreach(Oculus.Platform.Models.Destination destination in message.Data) { DestinationAPINames.Add(destination.ApiName); UpdateDestinationsConsole(); } } } #region Helper Functions private int DestinationIndex = 0; private bool OnlyPushUpOnce = false; // Update is called once per frame void Update() { if (PressAButton()) { if (DestinationAPINames.Count > 0) { SetPresence(); } else { UpdateConsole("No destinations to set to!"); return; } } else if (PressBButton()) { ClearPresence(); } ScrollThroughDestinations(); } private void ScrollThroughDestinations() { if (PressUp()) { if (!OnlyPushUpOnce) { DestinationIndex--; if (DestinationIndex < 0) { DestinationIndex = DestinationAPINames.Count - 1; } OnlyPushUpOnce = true; UpdateDestinationsConsole(); } } else if (PressDown()) { if (!OnlyPushUpOnce) { DestinationIndex++; if (DestinationIndex >= DestinationAPINames.Count) { DestinationIndex = 0; } OnlyPushUpOnce = true; UpdateDestinationsConsole(); } } else { OnlyPushUpOnce = false; } } private void UpdateDestinationsConsole() { if (DestinationAPINames.Count == 0) { DestinationsConsole.text = "Add some destinations to the developer dashboard first!"; } string destinations = "Destination API Names:\n"; for (int i = 0; i < DestinationAPINames.Count; i++) { if (i == DestinationIndex) { destinations += "==>"; } destinations += DestinationAPINames[i] + "\n"; } DestinationsConsole.text = destinations; } private void OnLoggedInUser(Message message) { if (message.IsError) { Debug.LogError("Cannot get logged in user"); } else { LoggedInUserID = message.Data.ID; } } private void UpdateConsole(string value) { Debug.Log(value); InVRConsole.text = "Scroll Up/Down on Right Thumbstick\n(A) - Set Rich Presence to selected\n(B) - Clear Rich Presence\n\n" + value; } #endregion #region I/O Inputs private bool PressAButton() { #if USE_OVRINPUT return OVRInput.GetUp(OVRInput.Button.One) || Input.GetKeyUp(KeyCode.A); #else return Input.GetKeyUp(KeyCode.A); #endif } private bool PressBButton() { #if USE_OVRINPUT return OVRInput.GetUp(OVRInput.Button.Two) || Input.GetKeyUp(KeyCode.B); #else return Input.GetKeyUp(KeyCode.B); #endif } private bool PressUp() { #if USE_OVRINPUT Vector2 axis = OVRInput.Get(OVRInput.Axis2D.SecondaryThumbstick); return (axis.y > 0.2 || Input.GetKeyUp(KeyCode.UpArrow)); #else return Input.GetKeyUp(KeyCode.UpArrow); #endif } private bool PressDown() { #if USE_OVRINPUT Vector2 axis = OVRInput.Get(OVRInput.Axis2D.SecondaryThumbstick); return (axis.y < -0.2 || Input.GetKeyUp(KeyCode.DownArrow)); #else return Input.GetKeyUp(KeyCode.DownArrow); #endif } #endregion }