Skip to main content

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 ConjureKit Demo sample

  • 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");
note

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();
info

Calling Connect without a parameter will connect to the fastest available Hagall server and give you a new session id.

Example device

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
note

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);
}
note

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. ConjureKit Demo sample

  • Open the Main scene of the Demo sample.

  • Insert your Aukiverse console app key and secret in Main.cs of the Demo sample.

Main.cs
_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