Sample Scenes
PrestoPad includes complete sample scenes demonstrating key functionality. These examples provide a solid foundation for understanding how to integrate PrestoPad into your own projects.
Sample Scene Overview
SamplePrestoPadScene
Location: Assets/PrestoPad/Samples/Scenes/SamplePrestoPadScene.unity
This comprehensive sample scene demonstrates all core features of PrestoPad:
Components Included
- PrestoPadManager Prefab: Server management and controller coordination
- ConnectionDisplay Prefab: QR code display and connection information
- PrestoPadDeviceMonitor: Visual debugging tool showing real-time controller input
- SamplePlayerController: Example player movement and input handling
Key Sample Scripts
PrestoPadDeviceMonitor
Location: Assets/PrestoPad/Samples/Scripts/PrestoPadDeviceMonitor.cs
Monitors and displays all connected PrestoPad controllers in real-time. Useful for debugging and visualizing input.
Features
- Displays all connected controllers with their IDs
- Shows button states (pressed/released)
- Visualizes joystick and D-Pad input
- Updates in real-time as controllers connect/disconnect
Key Code Snippets
// Detecting all PrestoPad devices
var controllers = InputSystem.devices
.Where(d => d is PrestoPadControllerDevice)
.Cast<PrestoPadControllerDevice>()
.ToList();
// Monitoring device changes
InputSystem.onDeviceChange += (device, change) =>
{
if (device is PrestoPadControllerDevice controller)
{
if (change == InputDeviceChange.Added)
Debug.Log($"Controller {controller.ControllerId} added");
else if (change == InputDeviceChange.Removed)
Debug.Log($"Controller {controller.ControllerId} removed");
}
};
SamplePlayerController
Location: Assets/PrestoPad/Samples/Scripts/SamplePlayerController.cs
Demonstrates basic player movement and input handling using PrestoPad controllers.
Features
- Joystick-based movement
- D-Pad discrete movement
- Button input for actions (jump, fire, etc.)
- Controller assignment and management
Key Code Snippets
using UnityEngine;
using UnityEngine.InputSystem;
using PrestoPad.Input;
public class SamplePlayerController : MonoBehaviour
{
[SerializeField] private float moveSpeed = 5f;
[SerializeField] private float jumpForce = 10f;
private PrestoPadControllerDevice controller;
private Rigidbody rb;
private bool isGrounded;
void Start()
{
rb = GetComponent<Rigidbody>();
InputSystem.onDeviceChange += OnDeviceChange;
}
void OnDeviceChange(InputDevice device, InputDeviceChange change)
{
if (device is PrestoPadControllerDevice pad)
{
if (change == InputDeviceChange.Added && controller == null)
{
// Assign first available controller
controller = pad;
Debug.Log($"Player assigned to controller {pad.ControllerId}");
}
}
}
void Update()
{
if (controller == null) return;
HandleMovement();
HandleActions();
}
void HandleMovement()
{
// Joystick movement (smooth)
Vector2 moveInput = controller.LeftStick.ReadValue();
if (moveInput.magnitude > 0.1f)
{
Vector3 movement = new Vector3(moveInput.x, 0, moveInput.y);
transform.Translate(movement * moveSpeed * Time.deltaTime);
}
// Alternative: D-Pad movement (discrete)
if (controller.DPad.up.isPressed)
transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);
if (controller.DPad.down.isPressed)
transform.Translate(Vector3.back * moveSpeed * Time.deltaTime);
if (controller.DPad.left.isPressed)
transform.Translate(Vector3.left * moveSpeed * Time.deltaTime);
if (controller.DPad.right.isPressed)
transform.Translate(Vector3.right * moveSpeed * Time.deltaTime);
}
void HandleActions()
{
// Jump on A button press
if (controller.ButtonA.wasPressedThisFrame && isGrounded)
{
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
}
// Additional actions
if (controller.ButtonB.wasPressedThisFrame)
Fire();
if (controller.ButtonX.wasPressedThisFrame)
UseItem();
if (controller.ButtonY.wasPressedThisFrame)
Interact();
}
void Fire() { Debug.Log("Fire!"); }
void UseItem() { Debug.Log("Use Item!"); }
void Interact() { Debug.Log("Interact!"); }
void OnCollisionStay() { isGrounded = true; }
void OnCollisionExit() { isGrounded = false; }
}
Running the Sample
- Open the sample scene:
Assets/PrestoPad/Samples/Scenes/SamplePrestoPadScene.unity - Enter Play Mode
- A QR code will appear on screen
- Scan the QR code with your smartphone
- The controller interface will load in your phone's browser
- Use the on-screen controls to interact with the sample
- Watch the DeviceMonitor UI to see input in real-time
Common Patterns
Multi-Player Controller Assignment
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using PrestoPad.Input;
public class MultiPlayerManager : MonoBehaviour
{
[SerializeField] private GameObject playerPrefab;
[SerializeField] private Transform[] spawnPoints;
private Dictionary<int, GameObject> players = new Dictionary<int, GameObject>();
void OnEnable()
{
InputSystem.onDeviceChange += OnDeviceChange;
}
void OnDeviceChange(InputDevice device, InputDeviceChange change)
{
if (device is PrestoPadControllerDevice controller)
{
if (change == InputDeviceChange.Added)
{
SpawnPlayer(controller);
}
else if (change == InputDeviceChange.Removed)
{
RemovePlayer(controller.ControllerId);
}
}
}
void SpawnPlayer(PrestoPadControllerDevice controller)
{
int playerIndex = controller.ControllerId - 1;
if (playerIndex < spawnPoints.Length)
{
GameObject player = Instantiate(playerPrefab, spawnPoints[playerIndex]);
player.GetComponent<PlayerController>().SetController(controller);
players[controller.ControllerId] = player;
}
}
void RemovePlayer(int controllerId)
{
if (players.ContainsKey(controllerId))
{
Destroy(players[controllerId]);
players.Remove(controllerId);
}
}
}
Waiting for Specific Controller
using System.Collections;
using UnityEngine;
using UnityEngine.InputSystem;
using PrestoPad.Input;
public class WaitForController : MonoBehaviour
{
[SerializeField] private int playerIndex = 1;
private PrestoPadControllerDevice controller;
void Start()
{
StartCoroutine(WaitForSpecificController());
}
IEnumerator WaitForSpecificController()
{
while (controller == null)
{
foreach (var device in InputSystem.devices)
{
if (device is PrestoPadControllerDevice pad)
{
if (pad.ControllerId == playerIndex)
{
controller = pad;
Debug.Log($"Found controller {playerIndex}!");
break;
}
}
}
yield return new WaitForSeconds(0.5f);
}
// Controller is ready, start gameplay
OnControllerReady();
}
void OnControllerReady()
{
Debug.Log("Controller ready, starting game!");
}
}
Testing Tips
- Use localhost for quick testing: Type
localhost:8080/controller/in a browser on the same machine - Enable debug logging: Check the
PrestoPadServerConfigasset and enable debug logging for detailed console output - Monitor the DeviceMonitor: Use the sample's DeviceMonitor component to visualize all input in real-time
- Test with multiple devices: Connect several phones to test multiplayer functionality
- Firewall configuration: Ensure ports 8080 and 8081 are open for Unity.exe (see Quick Start guide)
Next Steps
Now that you've explored the samples, you can:
- Integrate PrestoPad into your own game scenes
- Customize the controller UI using the Theme Editor
- Explore the API Reference for advanced features
- Modify the sample scripts to fit your specific needs