Easy3DPositional.cs

Used for 3D positional channels, meant to be attached to your Player

Overview

This script is for 3d Positional Channels only.

If your channel is NonPositional or Echo channel it won’t work and you may get errors. This script searches your connected channels for any 3D positional channels (can only have 1) and sends updates to Vivox to update the 3d Positional sound based on the game objects/players location.

These libraries are necessary to run this script

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using VivoxUnity;

Inherits from MonoBehaviour to be attached to game objects

public class Easy3DPositional : MonoBehaviour

This is a Unity custom attribute that displays a header in the Unity Editor.

[Header("3D Positional Settings")]

Transform variables

  • listenerPosition = transform of the gameObject that is to act as listener/ears

  • speakerPosition = transform of the gameObject that is to act as the speaker/mouth

  • lastListenerPosition = last position of the listener transform

  • lastSpeakerPosition = last position of the speaker transform

Both speaker and listener should be on the same gameObject and for realism on a human or creature model the speaker gameObject(can be empty gameObject) should be by mouth and listener in the middle of the head level with the ears.

 [Header("3D Positional Settings")]
 public Transform listenerPosition;
 public Transform speakerPosition;
 private Vector3 lastListenerPosition;
 private Vector3 lastSpeakerPosition;
  • positionalChannelExists - updated based on if a 3D positional exists

  • channelName - keeps track of channel name

  • userName - keeps track of username to use their current login session

 private bool positionalChannelExists = false;
 private string channelName;
 private string userName;

Sets Username using first logged in user in EasyCode. You can change especially if you are using multiple LoginSessions or custom Player identity service that provides username (Ex. Playfab, Unity Authentication, Firebase, GameSparks. etc...)

    private void Awake()
    {
        userName = EasySession.LoginSessions.FirstOrDefault().Value.LoginSessionId.DisplayName;
    }

Starts a coroutine that waits for seconds in float time before sending 3d position/coordinates to Vivox

 private void Start()
 {
     StartCoroutine(Handle3DPositionUpdates(.3f));
 }

Coroutine is run based on the seconds in the parameter nextUpdate. Once the specified time has passed this method checks if a 3D positional channel exists. If the player is logged in and if a 3d positional exists, then the 3d positional sound is updated based on the speaker(mouth) and listener(ears) game object/player location (transform position). If no 3d channel exists a check continues to run, based on the specified time, until a 3d channel exists.

IEnumerator Handle3DPositionUpdates(float nextUpdate, string userName)
{
    yield return new WaitForSeconds(nextUpdate);
    if (EasySession.LoginSessions[userName].State == LoginState.LoggedIn)
    {
        if (_positionalChannelExists)
        {
            Update3DPosition();
        }
        else
        {
            _positionalChannelExists = CheckIfChannelExists();
        }
    }

    StartCoroutine(Handle3DPositionUpdates(nextUpdate, userName));
}

Method that checks if a 3d channel exists and is connected

public bool CheckIfChannelExists()
{
    foreach (KeyValuePair<string, IChannelSession> session in EasySession.ChannelSessions)
    {
        if (session.Value.Channel.Type == ChannelType.Positional)
        {
            _channelName = session.Value.Channel.Name;
            if (EasySession.ChannelSessions[_channelName].ChannelState == ConnectionState.Connected)
            {
                Debug.Log($"Channel : {_channelName} is connected");
                if (EasySession.ChannelSessions[_channelName].AudioState == ConnectionState.Connected)
                {
                    Debug.Log($"Audio is Connected in Channel : {_channelName}");
                    return true;
                }
            }
            else
            {
                Debug.Log($"Channel : {_channelName} is not Connected");
            }
        }
    }
    return false;
}

Method that sends the location of the speaker(mouth) and listener(ears) transforms of their respective game objects to Vivox. Vivox updates the sound based on the positional coordinates of both speaker and listener. Saves the last position of both speaker and listener and only updates again if the player has moved. Vivox Documentation

public void Update3DPosition()
{
    if (listenerPosition.position != _lastListenerPosition || speakerPosition.position != _lastSpeakerPosition)
    {
        EasySession.ChannelSessions[_channelName].Set3DPosition(speakerPosition.position, listenerPosition.position, listenerPosition.forward, listenerPosition.up);
        Debug.Log($"{EasySession.ChannelSessions[_channelName].Channel.Name} 3D positon has been updated");
    }
    _lastListenerPosition = listenerPosition.position;
    _lastSpeakerPosition = speakerPosition.position;
}

Last updated