These steps are intended to be a temporary alternative solution while we update the existing guide.
Hello Lightship development community!
There are a few known issues you may encounter if you follow the Shared AR Host & Peers Communication guide that can result in…
…the host device not sharing tap events with peers…
…the peer car persisting on the host device after closing the app…
…the peer car persisting on the host device when the peer loads into another scene, such as the SceneSelector published with ARDK Examples…
…or the peer car not loading in a pre-existing host car after connecting.
If you’re trying to create a network multiplayer sample scene but have run into the issues with the published guide, you can follow these steps as an alternative peer-to-peer solution that addresses the issues listed above. Let’s build!
NOTE: These steps demonstrate creating the ARDK components manually rather than using the manager components.
- First, begin with a fresh scene.
- Then, alter the
Main Camera
GameObject’s Camera component so that theClear Flags
field is set toSolid Color
, and theBackground
field is set to black.
- Also, add the
AR Camera Position Helper
,AR Rendering Manager
, andAndroid Permission Requester
components to theMain Camera
, and ensure their camera references and Android permissions are set.
- Next, add a new C# script to the
Main Camera
namedP2PGameLogic
.
Note: The following steps go through the script creation process in detail. The resulting script – with in-line comments – is available for download, attached below this post.
- Open the script and start by adding the following using statements to the top of the file:
using Niantic.ARDK.AR;
using Niantic.ARDK.AR.Configuration;
using Niantic.ARDK.AR.Networking;
using Niantic.ARDK.AR.HitTest;
using Niantic.ARDK.Networking;
using Niantic.ARDK.Networking.MultipeerNetworkingEventArgs;
using Niantic.ARDK.Utilities;
using Niantic.ARDK.Utilities.BinarySerialization;
using Niantic.ARDK.Utilities.Input.Legacy;
using System.Collections.ObjectModel;
using System.IO;
using System.Text;
- Within the scope of the
P2PGameLogic
class – but outside the scope of a method – declare private fields of the following types:
IARWorldTrackingConfiguration
IMultipeerNetworking
IARSession
IARNetworking
- Within the
P2PGameLogic
class, create aprivate void OnEnable()
method and initialize the four ARDK objects that were declared in the previous step during this callback.
- Alongside the
OnEnable()
method, create aprivate void OnDisable()
method, and dispose of the four aforementioned objects during this callback.
- Within the scope of the
P2PGameLogic
class – but outside the scope of a method – declare and initialize a byte array to represent the session identifier.
Note: In this example, we’ve hardcoded a string “SampleSessionID” to represent the session identifier.
- During the
Start()
method of theP2PGameLogic
class, call theRun()
method of theARSession
field belonging to theIARNetworking
object, passing in theIARWorldTrackingConfiguration
object. Afterwards, join the networking session by passing the byte array that represents the session identifier into theJoin()
method of theNetworking
field that belongs to theIARNetworking
object.
- Within the scope of the
P2PGameLogic
class, create a series of callback methods that will listen for networking-related events raised by theIMultipeerNetworking
object. We’ll write the methods first – including some logging statements to assist with potential troubleshooting later – and then we’ll subscribe the callbacks to the relevant event handlers in the next step.
- With the callback methods written, subscribe them to the relevant
IMultipeerNetworking
events during theOnEnable()
method…
- …and be sure to unsubscribe the callback methods during the
OnDisable()
method, prior to disposing of the objects.
- Within the scope of the
P2PGameLogic
class, declare a pair of public fields – one to store the scene’sCamera
component, and another to store theGameObject
that represents the car prefab. Also, declare aprivate GameObject
field that will contain a reference to the car that belongs to the local device, as well as a constant unsigned integer to represent the car positioning event that gets broadcast to other devices in the network session.
- After saving the
P2PGameLogic
script, return to the scene and set the references to theCamera
component of theMain Camera
GameObject and theCAR
prefab that comes with the Lightship Hub samples.
- Ensure you’re setting the
Car Prefab
field to the .prefab object, and not the .fbx object of the same name.
- Within the
Update()
method belonging to theP2PGameLogic
class, include the following logic that first checks for a tap on the screen, then performs a hit test. If the hit-test is successful, create a car for the local player at the tapped location if the car doesn’t already exist, or set its destination if it already does exist. Finally, broadcast the car’s position to other players on the network.
Note: The CreateCar()
and BroadcastCarPosition()
methods will be written in the following steps, so disregard any error indicators suggesting that the methods do not yet exist.
- Within the scope of the
P2PGameLogic
class, write aCreateCar()
method that takes in aVector3 position
, and returns the GameObject of the car that was created at that position.
- Within the scope of the
P2PGameLogic
class, write aBroadcastCarPosition()
method that takes in aVector3 position
, serializes it into aMemoryStream
object, and sends it to other peers in the networking session.
- Within the scope of the
P2PGameLogic
class, declare and initialize a dictionary where they key-value pair is aGUID
andGameObject
. This will be populated on each device with the players (theGUID
) and the car associated with that player (theGameObject
).
- Within the
OnPeerDataReceived()
callback method, respond to the signal by first copying the arguments into a newMemoryStream
object and storing the sender’s identifier. Then, in the case of receiving a position event, deserialize the position from theMemoryStream
as aVector3
, and either set the remote player’s car’s position if that player is already in the local dictionary or create a car for that remote player and add them to the dictionary if they’re not yet added.
- Within the
OnPeerAdded()
callback method, call theBroadcastCarPosition()
method to ensure that peers that connect to the network are made aware of any pre-existing cars.
- Within the
OnPeerRemoved()
callback method, be sure to remove the player that left from the local dictionary, and destroy their car in the process.
- Within the scope of the
P2PGameLogic
class, write aLeaveNetworkingSession()
method that calls theLeave()
method of theIMultipeerNetworking
object.
- Call the
LeaveNetworkingSession()
method at the beginning ofOnDisable()
to ensure the player leaves the session when loading into a different scene.
- Within the
P2PGameLogic
class, create aprivate void OnApplicationQuit()
method and call theLeaveNetworkingSession()
method within it to ensure the player leaves the session when they force-quit the app.
- Ensure your scene is added to your Build Settings, and try testing on a pair of test devices.
Note: Before building, don’t forget to set up any project-wide settings for ARDK, such as the ARDKAuthConfig object that requires a valid API key generated by your Lightship account.
Now, you should be able to observe…
…the host device shares its tap events with peers…
…the peer car is cleaned up when closing the app…
…the peer car is also cleaned up when loading into another scene…
…and the peer device loads a pre-existing host car after connecting.
Note: By default, the networking classes will emit a variety of debug output to the console window. However, the debug statements generated by the code written above are prefixed by “Lightship: “
. If you’d like to see the debug statements specific to this code, you can filter your debug output with the “Lightship: “
prefix to only see the debug statements that we wrote as part of P2PGameLogic.cs
.
Thanks for following along with this alternative solution, and we look forward to seeing any networking projects you build with ARDK!
P2PGameLogic.cs (11.3 KB)