FMOD.Studio.EventInstance won't follow the sound source GameObject

I have instantiated the EventInstances and fed it the calling GameObject to know whether the sound needs to be muted (behind an obstacle).

The one-shot EventInstance plays just fine, it picks up on all of the value changes, but won’t follow the GameObject to which it is attached.

To avoid errors, I used the code suggested in other forum post:
evInst.set3DAttributes(FMODUnity.RuntimeUtils.To3DAttributes(callingGO.transform))

See full class code:

public class SoundBiteInstance : MonoBehaviour
{
    public FMOD.Studio.EventInstance evInst;
    public GameObject callingGO;
    public List<string> TagsToIgnore = new List<string>();
    private float _visibilityIncrementMultiplier = 6.5f;
    private float soundClipTimer = 0;
    private bool Started = false;
    private bool _menuOpen = false;
    public bool _isVisible = true;
    [Range(0,1)]public float _visibility = 1f;

    private void OnEnable()
    { MenuManagerScript.OnMenuOpen += ReactToMenuOpenClose; }
    private void OnDisable()
    { MenuManagerScript.OnMenuOpen -= ReactToMenuOpenClose; }

    private void Start()
    { OnEventInstCreation(); }

    private void FixedUpdate()
    {
        if (Started == true && _menuOpen == false)
        {
            DetermineVisibility();
            UpdateVisibilityValue();
            UpdateValuesWhileSoundBiteLasts();
        }
    }

    public void OnEventInstCreation()
    {
        evInst.set3DAttributes(FMODUnity.RuntimeUtils.To3DAttributes(callingGO.transform));

        FMOD.Studio.EventDescription evDescr;
        evInst.getDescription(out evDescr);

        int lengthsOfClipMill = 0;
        evDescr.getLength(out lengthsOfClipMill);

        DetermineVisibility();
        if (_isVisible) _visibility = 1f; else _visibility = 0f;

        soundClipTimer = (float)lengthsOfClipMill * 0.001f;
        evInst.start(); Started = true;
    }

    private void ReactToMenuOpenClose(bool aBool) 
    { 
        _menuOpen = aBool;
        evInst.setPaused(aBool);
    }

    public void DetermineVisibility()
    {
        LayerMask layerMask = (1 << 6) | (1 << 8) | (1 << 10) | (1 << 15);

        GameObject _player = GameObject.Find("Player");
        Vector3 _playerPos = Vector3.zero;
        Vector2 _playerDir = Vector2.zero;
        if (_player != null) _playerPos = _player.transform.position;
        if (_player != null) _playerDir = GetDirection(_player.transform.position, transform.position);

        RaycastHit2D[] collidersHit = Physics2D.RaycastAll(transform.position, _playerDir, Vector3.Distance(transform.position, _playerPos), layerMask);

        if (collidersHit.Any())
        {
            if (collidersHit[0].collider.tag == "Player") _isVisible = true;
            else if (collidersHit.Length > 1 && TagsToIgnore.Contains(collidersHit[0].collider.tag) && collidersHit[1].collider.tag == "Player") { _isVisible = true; }
            else { _isVisible = false; }
        }
    }

    public Vector2Int GetDirection(Vector3 aPlayerPos, Vector3 aSoundPos)
    {
        float posX = aPlayerPos.x - aSoundPos.x;
        float posY = aPlayerPos.y - aSoundPos.y;
        float angle = Mathf.Atan2(posY, posX) * Mathf.Rad2Deg;

        GameObject temp = new GameObject();
        temp.transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle - 90));
        Vector2 dirTemp = temp.transform.up;
        Vector2Int direction = Vector2Int.RoundToInt(dirTemp);
        Destroy(temp);

        return direction;
    }

    private void UpdateValuesWhileSoundBiteLasts()
    {
        if (soundClipTimer >= 0)
        {
            soundClipTimer -= Time.fixedDeltaTime;
            evInst.setParameterByName("Visible", _visibility);
        }
        else { StopImmediately(); }
    }

    private void UpdateVisibilityValue()
    {
        if (_isVisible == true && _visibility < 1)
        {
            if (_visibility + Time.fixedDeltaTime * _visibilityIncrementMultiplier <= 1)
            { _visibility += Time.fixedDeltaTime * _visibilityIncrementMultiplier; }
            else _visibility = 1f;
        }
        else if (_isVisible != true && _visibility > 0)
        {
            if (_visibility - Time.fixedDeltaTime * _visibilityIncrementMultiplier >= 0)
            { _visibility -= Time.fixedDeltaTime * _visibilityIncrementMultiplier; }
            else _visibility = 0f;
        }
    }

    public void StopImmediately()
    {
        evInst.stop(FMOD.Studio.STOP_MODE.IMMEDIATE);
        evInst.release();
        Destroy(gameObject);
    }
}

From what I can see, the 3D attributes of the event instance are only being set once. If you want the event instance’s position to follow your game object, it needs to have its 3D attributes continuously updated to match the game object. This is typically done either by calling EventInstance.set3DAttributes in Update(), or by having the FMOD plugin code handle updating the attributes with RuntimeManager.AttachInstanceToGameObject().

Give those a shot a let me know whether that resolves the issue for you.

Hey, Louis!

I added the .set3DAttributes to the the FixedUpdate loop and it worked like a charm!
Thank You for the help! I was banging my head against the wall.

1 Like

No problem, happy to hear that you managed to get it working.