Cross Platforming Help

Sorry if I put this in the wrong category I spent like 30 minutes trying to figure out if I should put this in Developer Discussion or Scripting Support.

So I actually have multiple questions because I really want to make compatible on all platforms as I go.

The Questions

1.) Searching for what platform they are on?

I really want to get this right the first time instead of getting a laggy mess and spending a little looking at the error output

2.) Is UserInputService or ContextActionService better to use?

This has been an argument that I’m just tired of and want the correct answer before I get too deep into the game. I am kind of looking for pros and cons on both as well so I can get my own opinion.

3.) Making XBOX UI’s work well!!!

I’ve played a couple games on and off on xbox the last few days and have noticed that its never easy to select a button/option in game is there a way to make sure I don’t got to worry about that pesky little blue box ruining a players experience?

Thank you for taking your time and reading this by the way(and hopefully answering so I don’t make a huge bug that makes me want to touch the red brick in your Obstacle course)

  1. I don’t think there’s a good way to do this. For instance, you could do this:
local Platforms = {
Enum.UserInputType.Touch = "Mobile",
Enum.UserInputType.Mouse = "Computer" -- Can't remember input type for this lol

BUT, the player can have a touchscreen laptop and vice versa a tablet with a mouse.

  1. Depends what context it is. If you want to only want it to run under certain conditions, use ContextActionService. You can’t really say one’s better than the other, I use both. (CAS also lets you make mobile input
    (What I mean:)
if Humanoid.Sit == true then
CAS:BindAction("Honk Horn", Horn, true, Enum.KeyCode.H) -- When the Humanoid is seated, let them honk the horn
CAS:UnbindAction("Honk Horn") -- When they leave, don't

For Xbox UI system, there is a new beta feature on studio when you you to File -> Beta features That allows the controller to act as a cursor instead, if that helps!

  1. Determining Platform:

Outside of console (which can be determined definitively via GuiService:IsTenFootInterface()), platform determination is at best heuristic; that said, you can generally make safe inferences. For instance, I assume any client that can use a mouse and keyboard is a desktop, and I assume any touch-enabled device without a mouse or keyboard is a mobile device. With these definitions, I can treat touch-enabled desktops as desktops since they will not meet the criteria of a mobile device unless they have all their peripherals unplugged, at which point the device will need to be treated as mobile device anyway.

I tend to make platform assessments within a ModuleScript that can be required all across the client so that the evaluations only need to be made once. I also generally hook up gamepad logic even when a gamepad is not detected if the user is on desktop, although a more nuanced approach can be used by monitoring the event UserInputService.LastInputTypeChanged.

  1. Which Input Service to Use:

Flat out, ContextActionService provides the most functionality for the least amount of developer input and work very well in most circumstances. Set-up is simple, and the arguments that get passed to the functions are not wildly foreign compared to UIS arguments. Because functions can be easily bound and unbound to the service, it works especially well for nuanced control schemes that are dependent on, well, context. That’s why the service was created.

Where CAS falls short though is mobile development. Every time CAS runs a function, it sends a new UserInputObject to that function. That is fine for desktop and console where each control type can only be in use in one place at a time under normal use. You can’t press “B” while already pressing “B,” for instance. This is not true with mobile development where a user can touch the screen while already touching the screen. Because a new object is passed during every function call, it can be difficult to keep track of which touch action is which. UserInputService does not suffer from this problem: UIS creates an input object during its corresponding InputBegin events and changes that object when the input it corresponds with changes. This means that if the objects are saved to variables, different objects can be compared against each other to figure out which input is which, or which touch is which more specifically.

That said, if you are only interested in the start or stop of a touch event, CAS can still get the job done. CAS also works nicely when actions are mutually-exclusive, since the completion of an action can block calls to other actions.

  1. XBOX Interfacing:

The difficulty you are having with menus and the blue boxes you are seeing are the result of developers utilizing the default behavior provided by the ROBLOX engine. Without this behavior, most games would be entirely unplayable with a gamepad. The default behavior generally works well enough to use in most cases even if it isn’t perfect; that is to say, overriding the behavior isn’t always worth the development time. However, all of it can be overridden or improved, but it requires losing and re-implementing a lot of the default behavior. GuiService offers means of enabling or disabling a default menu navigation. Navigation must then be defined in UI elements’ NextSelection... properties, either manually or during runtime via code.

The blue boxes can also be changed by changing individual UI elements’ SelectionImageObject property, or for all elements by changing the user’s PlayerGui.SelectionImageObject. Bear in mind that these properties are looking for other GUI elements, not image links.

1 Like