Develop

Ultimate Glove Ball sample

Updated: May 10, 2026

Overview

This sample is a multiplayer VR sports game built with Unity Netcode for GameObjects and Photon Realtime. It demonstrates custom physics synchronization, Meta Avatars integration, asymmetric player/spectator roles, and social platform features including group presence and invites. The sample targets developers building networked VR experiences who want to see how Meta XR SDKs combine with third-party networking solutions in a production-ready architecture.

What you will learn

  • Integrating Unity Netcode for GameObjects with Photon Realtime as a transport layer, including host migration and connection approval
  • Implementing custom state synchronization for fast-moving physics objects using jitter buffers and client-side prediction
  • Creating asymmetric multiplayer experiences with distinct player and spectator roles, input maps, and capacity limits
  • Integrating Meta Avatars with networked gameplay, including multi-object avatar construction and LOD-based streaming
  • Using Meta Platform SDK features including group presence, friend invites, join intents, user blocking, and in-app purchases

Requirements

  • Device: Meta Quest 2 or newer
  • Development environment: Unity 6000.0.59f2 or newer
For detailed SDK versions, build prerequisites, and platform setup, see the sample README.

Get started

Clone the repository from GitHub and open the project in Unity 6000.0.59f2 or newer. The main entry point is the Startup.unity scene in Assets/UltimateGloveBall/Scenes/. For detailed build instructions including Photon configuration and platform entitlement setup, see the sample README.

Explore the sample

The sample separates reusable multiplayer infrastructure from game-specific logic using a two-layer architecture. The Packages/com.meta.multiplayer.netcode-photon/ package provides networking, avatars, VoIP, and social features that you can adapt for other projects, while Assets/UltimateGloveBall/ implements the sports game logic on top of it.
Scene / ScriptWhat it demonstratesKey concepts
Startup.unity
Application entry point and platform initialization
Oculus Platform SDK entitlement check, Photon lobby connection
MainMenu.unity
Matchmaking and social UI
Quick match, host match, watch match, friends list, store
Arena.unity
Gameplay environment
Game phases, team assignment, ball spawning, scoring
UGBApplication.cs
Application lifecycle singleton
Platform SDK init, group presence, join intent handling, IAP
NetworkLayer.cs
Core networking state machine
Photon + Netcode hybrid, host migration, connection approval
BallStateSync.cs
Custom physics synchronization
Jitter buffer, lerp/slerp correction, snap threshold
GameManager.cs
Game state machine
PreGame, CountDown, InGame (3 min), PostGame phases
PlayerControllerNetwork.cs
Player mechanics and shields
Shield charge/drain system, invulnerability
Glove.cs
Glove states and ball throwing
Anchored/Flying states, charge-up mechanics, ball anchoring, target selection
ArenaApprovalController.cs
Asymmetric capacity management
6 player limit, 4 spectator limit, connection approval
SpectatorNetwork.cs
Spectator-specific behavior
Crowd NPC body, item cycling, fireworks
AvatarEntity.cs
Meta Avatar integration
Body tracking, lip sync, face tracking, eye tracking
ArenaPlayerSpawningManager.cs
Multi-object networked avatar
5 network objects per player (avatar + armatures + gloves)

Runtime behavior

When you run the sample, the app initializes the Oculus Platform SDK and connects to the Photon lobby, then transitions to the main menu. You see your Meta Avatar in a VR menu environment with options for Quick Match, Host Match, Watch Match, Friends, and Store. Selecting Quick Match joins or creates a Photon room and loads the Arena scene.
During PreGame, you walk around and choose a team side. When the host starts the game, a 4-second countdown begins, followed by 3 minutes of gameplay. Balls spawn at center court with random types:
  • Normal — standard ball with no special behavior
  • Electric — passes through shields and obstacles
  • Ghost — grants temporary invulnerability to the holder
  • Homing — tracks the nearest opponent’s chest
  • Triple — splits into 3 balls shortly after being thrown
You throw balls by grabbing with grip, charging up, and releasing. Shields activate with grip buttons but drain quickly when active and recharge faster when idle.
Spectators spawn as crowd NPCs in the stands and can cycle held items with the left trigger and launch fireworks with the right trigger. After 3 minutes, the game transitions to PostGame, separating winners and losers, with options to restart or return to the main menu.

Key concepts

Custom ball physics synchronization

The sample implements custom state synchronization for balls instead of using Unity’s built-in NetworkTransform. Notice how BallStateSync.cs uses a jitter buffer and client-side prediction to handle fast-moving physics objects. The server sends BallPacket structs via ClientRpc at a configurable rate, and clients smoothly interpolate position, velocity, and rotation to reduce network jitter. A snap threshold handles large discrepancies when prediction drifts too far from server state.
See the full implementation in BallStateSync.cs.

Photon Realtime as Unity Netcode transport

The sample uses Photon Realtime as the transport layer for Unity Netcode for GameObjects, combining Photon’s mature relay infrastructure with Netcode’s high-level API. Notice how NetworkLayer.cs implements a state machine (Disconnected, StartingLobby, StartingHost, StartingClient, MigratingHost) and handles host migration via Photon’s OnMasterClientSwitched callback, preserving game state when the original host disconnects.
See the state machine implementation in NetworkLayer.cs.

Asymmetric player and spectator experiences

The sample creates distinct roles for players and spectators with separate capacity limits, input maps, and spawned objects. Notice how ArenaApprovalController.cs enforces a maximum of 6 players and 4 spectators during connection approval by checking the connection payload. Spectators spawn as crowd NPCs with a SpectatorNetwork.cs component that enables item cycling and fireworks, while players spawn with full avatar rigs, gloves, and shields.
See connection approval logic in ArenaApprovalController.cs.

Multi-object networked avatars

The sample constructs each player from 5 separate networked objects to enable independent ownership of throwable gloves and support LOD-based streaming for bandwidth optimization. Notice how ArenaPlayerSpawningManager.cs spawns an avatar root, two armature hierarchies, and two glove objects, then parents them correctly. The AvatarEntity.cs component handles body tracking, lip sync, face tracking, and eye tracking, while AvatarNetworking.cs streams avatar data via RPCs with update frequencies that adjust based on distance.
See multi-object spawning in ArenaPlayerSpawningManager.cs.

Social platform integration

The sample integrates multiple Meta Platform SDK features including group presence, join intents, friend lists, user blocking, and in-app purchases. Notice how UGBApplication.cs initializes the platform SDK, sets group presence via GroupPresenceState.cs, and handles join intents when users accept invites. The BlockUserManager.cs component fetches blocked users and prevents them from joining the same match.
See platform initialization in UGBApplication.cs.

Extend the sample

  • Add new ball types: Create a new script inheriting from BallBehaviour and implement custom behavior in Update() or override ResetBall() as needed. See ElectricBall.cs, GhostBall.cs, HomingBall.cs, and TripleBall.cs for reference implementations. Add the new ball prefab to the BallSpawningData ScriptableObject’s ball list with an appropriate spawn weight.
  • Implement tournament mode: Extend GameManager.cs to track multiple rounds and persistent scores across game phases. Use PlayerPresenceHandler.cs to set custom destination metadata for tournament lobbies, and leverage the existing NetworkedScore component to aggregate results across rounds.
  • Add power-ups for spectators: Extend SpectatorNetwork.cs to include interactive abilities that affect gameplay, such as spawning obstacles or healing players. The existing spectator item system (SpectatorItem base class) provides a pattern for adding new interactive objects, and ServerRpc calls synchronize effects across clients.