Samples
ConjureKit package includes basic samples that demonstrate how to use ConjureKit capabilities.
Requirements
- Aukiverse app key and secret.
- Unity project with ConjureKit package.
Basics
The example code in the Demo sample demonstrates how to join a Session and send custom messages to other participants in the same session.
Import
Import the Demo sample from the package manager
Open the
Main
scene of the Demo sample.Insert your Aukiverse console app key and secret in
Main.cs
of the Demo sample.
_conjureKit = new ConjureKit(ConjureKitConfiguration.Get(), cameraTransform, "insert_app_key_here", "insert_app_secret_here");
ConjureKit requires a Camera
reference. If you have an AR project, this will reference the camera from your AR scene rig. If you use the ConjureKit for a non-AR project, this can be any active camera in the scene.
Overview
This example demonstrates connecting to a shared session with a specific session id and sending custom messages to other participants in that session. Run two instances of the Main scene from the sample. This can be two Unity editor instances, two smartphones, or a combination of both. Now you should be able to join the same session on both devices and send custom messages between the two.
Connecting to session
The sample app will register to the OnJoined, OnLeft events, and use them to update the text field with the session id.
_conjureKit.OnJoined += session => sessionInfo.text = session.Id;
_conjureKit.OnLeft += () => sessionInfo.text = "";
We use OnStateChanged event to make the buttons interactable and update the state text on the screen.
_conjureKit.OnStateChanged += state =>
{
ToggleControlsState(state == State.JoinedSession || state == State.Calibrated);
conjureKitStateInfo.text = state.ToString();
};
Finally, the Connect method is used to join a new session.
_conjureKit.Connect();
Calling Connect
without a parameter will connect to the fastest available Hagall server and give you a new session id.
![Example device](/assets/images/conjurekit-sample-device1-0211166a2fcf0ab9efd23be8600b073d.png)
Joining a custom session
Once the sample app connects to a session, you can use that session id on the other device to join the same session.
public void JoinCustomSessionButtonPressed()
{
var targetSessionId = customSessionInputField.text;
if (string.IsNullOrEmpty(targetSessionId) || targetSessionId == _lastJoinedSessionId) return;
Debug.Log($"Joining custom session: {targetSessionId}");
_conjureKit.Disconnect();
_conjureKit.Connect(targetSessionId, _ =>
{
Debug.LogWarning($"Failed to join session {targetSessionId}, connecting to a new session instead.");
_conjureKit.Connect();
});
}
Pressing the Join
button on the second device will try to connect to a session with the session id from customSessionInputField
.
If the connection to that specific session fails, it will call the Connect
method with no session id and connect to a new session.
![Example device](/assets/images/conjurekit-sample-device2-0033580d411c26b609606bcb31e316b7.png)
Connecting to a session with a session id will let you join the specific session, but you won't be calibrated into the same coordinate system. To get instant calibration when joining a session, use the Manna module.
Sending custom messages
Once both devices are in the same session, pressing the Send Msg
button on one device will send a custom message to all other participants in the session.
public void SendSampleMessageButtonPressed()
{
var encodedMessage = Encoding.UTF8.GetBytes($"Message from participant {_conjureKit.GetSession().ParticipantId}.");
var participantIds = _conjureKit.GetSession().Participants.Keys.ToArray();
_conjureKit.SendCustomMessage(participantIds, encodedMessage);
}
The current maximum size of each custom message is 10 kB. If the message is too big, it will be rejected with an error log message.
In the Start
method, participants will register to the OnCustomMessageBroadcast to get custom messages from other participants and print those in the console.
_conjureKit.OnCustomMessageBroadcast += broadcast =>
{
var decodedMessage = Encoding.UTF8.GetString(broadcast.Body);
Debug.Log($"Received custom message: {decodedMessage}");
};
Entities and components
The example in the ECSDemo sample demonstrates adding and updating entities.
Import
Import the ECSDemo sample from the package manager.
Open the
Main
scene of the Demo sample.Insert your Aukiverse console app key and secret in
Main.cs
of the Demo sample.
_conjureKit = new ConjureKit(ConjureKitConfiguration.Get(), cameraTransform, "insert_app_key_here", "insert_app_secret_here");
Adding an Entity
Pressing the Spawn button will create a primitive cube in front of the camera or return if the participant hasn't joined a session yet.
public void Spawn()
{
if (!_joined) return;
var position = cameraTransform.position + cameraTransform.forward * 0.05f;
var cubePose = new Pose(position, Quaternion.identity);
_cubeGameObject = GameObject.CreatePrimitive(PrimitiveType.Cube);
_cubeGameObject.transform.SetPositionAndRotation(cubePose.position, cubePose.rotation);
_cubeGameObject.transform.localScale = Vector3.one * 0.1f;
After creating the primitive cube, an Entity will be created with the cubePose
, and the entity id will be stored in the _spawnedCubeEntity
field.
_conjureKit.AddEntity(cubePose, entity =>
{
_spawnedCubeEntity = entity;
var scaleArray = new float[] {0.1f};
var byteArray = new byte[sizeof(float)];
Buffer.BlockCopy(scaleArray, 0, byteArray, 0, 1 * sizeof(float));
// Add component to the cube entity.
_conjureKit.AddComponent(_testScaleComponentId, entity.Id, byteArray, () => { }, Debug.Log);
}, Debug.Log);
Adding a component
First, the component type needs to be added to ConjureKit.
private const string TEST_SCALE_COMPONENT_NAME = "test_scale";
_conjureKit.OnJoined += session =>
{
sessionInfo.text = session.Id;
_joined = true;
_lastJoinedSessionId = session.Id;
// Create/retrieve the id of a component of type TEST_SCALE_COMPONENT_NAME and subscribe to its updates.
_conjureKit.AddComponentType(TEST_SCALE_COMPONENT_NAME, componentTypeId =>
{
_testScaleComponentId = componentTypeId;
_conjureKit.SubscribeToComponentType(componentTypeId, () => { }, Debug.Log);
}, Debug.Log);
};
The AddComponentType
method would register a new component type with TEST_SCALE_COMPONENT_NAME
name and return a componentTypeId
if it was successful. This id will be used to add, remove, update and subscribe to component updates of this type.
var scaleArray = new float[] {0.1f};
var byteArray = new byte[sizeof(float)];
Buffer.BlockCopy(scaleArray, 0, byteArray, 0, 1 * sizeof(float));
// Add component to the cube entity.
_conjureKit.AddComponent(_testScaleComponentId, entity.Id, byteArray, () => { }, Debug.Log);
Updating a component
The scale of the primitive cube will be updated in the Update
method, and the entity component will be updated with the new scale values.
private void Update()
{
if (_spawnedCubeEntity == null) return;
var scale = (Time.time % 2 + 1) * 0.01f;
var scaleArray = new float[] {scale};
var byteArray = new byte[sizeof(float)];
Buffer.BlockCopy(scaleArray, 0, byteArray, 0, 1 * sizeof(float));
_cubeGameObject.transform.localScale = Vector3.one * scale;
_conjureKit.UpdateComponent(_testScaleComponentId, _spawnedCubeEntity.Id, byteArray);
}
Other participants will listen to OnComponentUpdate event to update the scale of the primitive cube with the new values from the component.
_conjureKit.OnComponentUpdate += broadcast =>
{
var floatArray = new float[1];
Buffer.BlockCopy(broadcast.EntityComponent.Data, 0, floatArray, 0, 1 * sizeof(float));
var go = _entityMap[broadcast.EntityComponent.EntityId];
go.transform.localScale = Vector3.one * floatArray[0];
};
![Example device](/assets/images/conjurekit-ecs-sample-cube-scale-1b0839e6a66c935ade535a1029c7cb22.gif)