2020-11-28 16:54:41 +02:00

396 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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 users 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<string> DestinationAPINames = new List<string>();
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<string> message)
{
if (message.IsError)
{
UpdateConsole(message.GetError().Message);
} else
{
UpdateConsole("Updated launch details:\n" + GetAppLaunchDetails());
}
}
void OnGetDestinations(Message<Oculus.Platform.Models.DestinationList> 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<Oculus.Platform.Models.User> 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
}