π Case Study: Our World
Our World is a PokΓ©mon-GO-style AR geolocation game built in Unity on OASIS WEB4 and WEB5. Players explore the real world to discover GeoNFTs, complete location-based missions, battle creatures at AR hotspots, and share cross-game inventory with ODOOM and OQuake. Earth itself is registered as an OASIS CelestialBody β every GPS coordinate maps into the Omniverse.
Tech stack
- Engine: Unity 2022+ (C#), ARFoundation, GPS/location services
- OASIS WEB4: Avatar SSO, cross-game Inventory, Karma, HyperDrive player data, ONET multiplayer
- OASIS WEB5: GeoNFTs, GeoHotSpots, Missions, Quests, CelestialBodies (Earth as planet), WEB5 STAR API
- Unity SDK:
NextGenSoftware.OASIS.API.OASISUnitySDK(NuGet)
Architecture
Unity App (C#) β ββ OASISAvatarManager βββΊ WEB4 Avatar SSO + Karma ββ OASISGeoManager βββΊ WEB5 GeoNFTs + GeoHotSpots (GPS β AR spawn) ββ OASISMissionManager βββΊ WEB5 Missions + Quests (objectives + rewards) ββ OASISInventory βββΊ WEB5 Cross-game inventory (shared with ODOOM/OQuake) ββ OASISMultiplayer βββΊ WEB4 ONET P2P (real-time player positions) ββ OASISHyperDrive βββΊ WEB4 Player save data (persistent across devices)
Step 1 β Avatar Login (Unity)
using NextGenSoftware.OASIS.API.OASISUnitySDK; using NextGenSoftware.OASIS.API.OASISUnitySDK.Avatar; public class OurWorldAuthManager : MonoBehaviour { async void Start() { var result = await OASISDNA.Managers.Avatar .AuthenticateAsync(email, password); if (result.IsError) { Debug.LogError($"Login failed: {result.Message}"); return; } OASISDNA.CurrentAvatar = result.Result; Debug.Log($"Logged in as {result.Result.Username}, karma={result.Result.Karma}"); LoadGame(); } }
Step 2 β Earth as a CelestialBody
Earth is registered as an OASIS CelestialBody. Real GPS coordinates map to positions on the Earth body β GeoNFTs dropped at a GPS location appear in AR at exactly that spot.
// On startup β ensure Earth is registered and warp avatar to it var earthBody = await OASISDNA.Managers.Star .GetCelestialBodyByNameAsync("Earth"); await OASISDNA.Managers.Star.Avatar .WarpToAsync(OASISDNA.CurrentAvatar.Id, earthBody.Id);
Step 3 β Spawning GeoNFTs in AR
public class OASISGeoManager : MonoBehaviour { async void Update() { var loc = Input.location.lastData; // Poll nearby GeoNFTs every 10 seconds if (Time.time - lastPoll > 10f) { lastPoll = Time.time; var nearby = await OASISDNA.Managers.Star.GeoNFTs .GetNearbyAsync(loc.latitude, loc.longitude, radiusMetres: 500); foreach (var geoNft in nearby) SpawnARObject(geoNft); } } void SpawnARObject(GeoNFT geoNft) { var arPos = GpsToARPosition(geoNft.Latitude, geoNft.Longitude); var go = Instantiate(geoNftPrefab, arPos, Quaternion.identity); go.GetComponent<GeoNFTDisplay>().SetData(geoNft); } public async void OnPlayerTapGeoNFT(GeoNFT geoNft) { var result = await OASISDNA.Managers.Star.GeoNFTs .CollectAsync(geoNft.Id, OASISDNA.CurrentAvatar.Id); if (!result.IsError) UIManager.ShowReward($"Collected! +{result.Result.KarmaAwarded} karma"); } }
Step 4 β Missions & Objectives
// Called when player enters a GeoHotSpot radius async void OnHotSpotEntered(GeoHotSpot hotSpot) { if (hotSpot.HotSpotType == "MissionCheckpoint") { await OASISDNA.Managers.Star.Missions .CompleteObjectiveAsync(hotSpot.MissionId, hotSpot.ObjectiveIndex, OASISDNA.CurrentAvatar.Id); UIManager.ShowObjectiveComplete(hotSpot.ObjectiveIndex); } }
Step 5 β Cross-Game Inventory
Items collected in Our World appear in the player's inventory in ODOOM and OQuake β the inventory is stored in WEB5 and is game-agnostic.
// Load cross-game inventory (shared with ODOOM/OQuake) var inventory = await OASISDNA.Managers.Star.Inventory .GetItemsAsync(OASISDNA.CurrentAvatar.Id); // Check if player has the Crimson Key (found in ODOOM) bool hasCrimsonKey = inventory.Items .Any(i => i.Name == "Crimson Key"); if (hasCrimsonKey) UnlockSecretArea(); // A door in Our World that only ODOOM players can open
Browse the Our World Unity project at github.com/NextGenSoftwareUK/OASIS/tree/master/ARWorld β