PrestoPad Sample Scenes

Example implementations and code

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

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

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

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

  1. Open the sample scene: Assets/PrestoPad/Samples/Scenes/SamplePrestoPadScene.unity
  2. Enter Play Mode
  3. A QR code will appear on screen
  4. Scan the QR code with your smartphone
  5. The controller interface will load in your phone's browser
  6. Use the on-screen controls to interact with the sample
  7. 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

Next Steps

Now that you've explored the samples, you can: