# How to use setTimelinePosition?

**URL:** <https://qa.fmod.com/t/how-to-use-settimelineposition/18790>\
**Category:** Unity\
**Created:** [May 24, 2022, 5:43am UTC](https://qa.fmod.com/t/how-to-use-settimelineposition/18790 "2022-05-24T05:43:56Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![MarsLit](https://avatars.discourse-cdn.com/v4/letter/m/7993a0/32.png) [@MarsLit](https://qa.fmod.com/u/MarsLit)\
**Post date:** [May 24, 2022, 5:43am UTC](https://qa.fmod.com/t/how-to-use-settimelineposition/18790/1 "2022-05-24T05:43:56Z")

</div>

Is there any example about how to use setTimelinePosition?

I’m trying to add setTimelinePosition to StudioEventEmitter what I want to achieve is to completely control the playback of an sfx.

Call play to only instantiate the event without playing and using setTimelinePosition to control it (like for example, a cassette tape, controlling its speed etc).

---

<div class="post-metadata">

**Author:** ![MarsLit](https://avatars.discourse-cdn.com/v4/letter/m/7993a0/32.png) [@MarsLit](https://qa.fmod.com/u/MarsLit)\
**Post date:** [May 24, 2022, 10:34am UTC](https://qa.fmod.com/t/how-to-use-settimelineposition/18790/2 "2022-05-24T10:34:39Z")

</div>

Added this lines to StudioEventEmitter

```auto
        public int GetLenght()
        {
            int lenght = 0;

            if (instance.isValid())
                eventDescription.getLength(out lenght);

            return lenght;
        }

        public int GetTimelinePos()
        {
            int pos = 0;

            if (instance.isValid())
                instance.getTimelinePosition(out pos);

            return pos;
        }

        public void SetTimelinePos(int pos)
        {
            if (instance.isValid())
            {
                instance.setTimelinePosition(pos);
            }
        }

```

and tried to seek using this test code

```auto
    public StudioEventEmitter emitter;
    private int timelinePos = 0;

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.J))
        {
            PlaySound();
        }
        if (Input.GetKey(KeyCode.L))
        {
            if (emitter.IsPaused())
                emitter.Pause(false);

            timelinePos += 1;
            emitter.SetTimelinePos(timelinePos);

            Debug.Log(timelinePos);
        }
        if (Input.GetKeyUp(KeyCode.L))
        {
            if (!emitter.IsPaused())
                emitter.Pause(true);
        }
    }

    void PlaySound()
    {
        emitter.Play();

        timelinePos = 0;
        emitter.SetTimelinePos(timelinePos);

        emitter.Pause(true);
    }

```

But things aren’t working as expected feels like the sound is playing a thousand times.

---

<div class="post-metadata">

**Author:** ![richard\_simms](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/richard_simms/32/261_2.png) [@richard\_simms](https://qa.fmod.com/u/richard_simms)\
**Post date:** [May 26, 2022, 2:55am UTC](https://qa.fmod.com/t/how-to-use-settimelineposition/18790/3 "2022-05-26T02:55:39Z")

</div>

I would advise against editing the `StudioEventEmitter.cs` file directly as that can lead to unexpected behaviours, especially if you update the integration at some point. It is much better to use the timeline functions on a custom script to avoid this.

In your custom script, you can use something similar to this code:

```cs
FMOD.Studio.EventInstance eventInstance;
    int currentPosition = 0;

    // Start is called before the first frame update
    void Start()
    {
        GetComponent<FMODUnity.StudioEventEmitter>().Play();
        eventInstance = GetComponent<FMODUnity.StudioEventEmitter>().EventInstance;
    }

    // Update is called once per frame
    void Update()
    {
        eventInstance.getTimelinePosition(out currentPosition);

        if (Input.GetKeyDown(KeyCode.UpArrow))
        {
            eventInstance.setTimelinePosition(0);
        }

        Debug.Log("Current position: " + currentPosition);
    }

```

It is important to get the event instance _after_ playing the event emitter in order to grab the event instance. Otherwise, a new event instance is spawned and the rest of the code will not reflect what you are expecting.

---

<div class="post-metadata">

**Author:** ![MarsLit](https://avatars.discourse-cdn.com/v4/letter/m/7993a0/32.png) [@MarsLit](https://qa.fmod.com/u/MarsLit)\
**Post date:** [May 26, 2022, 5:06am UTC](https://qa.fmod.com/t/how-to-use-settimelineposition/18790/4 "2022-05-26T05:06:13Z")

</div>

Thank you for your answer, and what about advancing in the timeline position while stiil being able to hear the sound (cassette tape behaviour)?

---

<div class="post-metadata">

**Author:** ![richard\_simms](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/richard_simms/32/261_2.png) [@richard\_simms](https://qa.fmod.com/u/richard_simms)\
**Post date:** [May 26, 2022, 11:59pm UTC](https://qa.fmod.com/t/how-to-use-settimelineposition/18790/5 "2022-05-26T23:59:57Z")

</div>

There’s no feature that lets you interpolate between timeline positions, so this would require some designing.

You can have a setup such as:

1. Pause the event
2. Play a new event that plays a cassette fast-forward sound
3. Seek to the required timeline position
4. Unpause event

Another possibility is to have a function that advances in chunks from the current position to the new position whilst a similar “fast forward” sound effect plays.

You could even use [`EventInstance::setPitch`](https://www.fmod.com/resources/documentation-api?version=2.02&page=core-api-channelcontrol.html#channelcontrol_setpitch) and increase the pitch (and speed) of the event until you reach the needed timeline position. This cannot work backwards, however.

[https://www.fmod.com/resources/documentation-api?version=2.02&page=studio-api-eventinstance.html#studio\_eventinstance\_setpitch](https://www.fmod.com/resources/documentation-api?version=2.02&page=studio-api-eventinstance.html#studio_eventinstance_setpitch)

Alternatively, a more complicated solution would be to use the Core API to play the audio file you want and use [`Channel::setFrequency`](https://www.fmod.com/resources/documentation-api?version=2.02&page=core-api-channel.html#channel_setfrequency) to speed up or play backwards as needed and [`Channel::getPosition`](https://www.fmod.com/resources/documentation-api?version=2.02&page=core-api-channel.html#channel_getposition) to know when you reach the necessary timeline position.

---

<div class="post-metadata">

**Author:** ![MarsLit](https://avatars.discourse-cdn.com/v4/letter/m/7993a0/32.png) [@MarsLit](https://qa.fmod.com/u/MarsLit)\
**Post date:** [May 27, 2022, 3:06am UTC](https://qa.fmod.com/t/how-to-use-settimelineposition/18790/6 "2022-05-27T03:06:51Z")

</div>

Sorry for themisunderstanding I don’t need the actual cassette effect but rather to play a sound being able to advance it’s playback via code. No need to any pitch change or anything like that.

---

<div class="post-metadata">

**Author:** ![richard\_simms](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/richard_simms/32/261_2.png) [@richard\_simms](https://qa.fmod.com/u/richard_simms)\
**Post date:** [May 30, 2022, 12:29am UTC](https://qa.fmod.com/t/how-to-use-settimelineposition/18790/7 "2022-05-30T00:29:37Z")

</div>

Then you would just need to adjust the event’s pitch to speed the event up at the same time as adjusting a pitch shift to bring it back to its original pitch. You can add a pitch shift effect to the event’s master track and automate it along with the event’s pitch with a parameter.

---

<div class="post-metadata">

**Author:** ![MarsLit](https://avatars.discourse-cdn.com/v4/letter/m/7993a0/32.png) [@MarsLit](https://qa.fmod.com/u/MarsLit)\
**Post date:** [May 30, 2022, 5:54am UTC](https://qa.fmod.com/t/how-to-use-settimelineposition/18790/9 "2022-05-30T05:54:17Z")

</div>

Wait, got me lost here.

This is how I changed my code

```auto
using UnityEngine;
using FMODUnity;
using FMOD.Studio;

public class TestSetTimelinePos : MonoBehaviour
{
    public StudioEventEmitter emitter;

    EventInstance eventInstance;
    int currentPosition = 0;

    // Start is called before the first frame update
    void Start()
    {
        emitter.Play();
        eventInstance = emitter.EventInstance;
    }

    // Update is called once per frame
    void Update()
    {
        eventInstance.getTimelinePosition(out currentPosition);

        if (Input.GetKeyDown(KeyCode.UpArrow))
        {
            eventInstance.setTimelinePosition(0);
        }
        if (Input.GetKey(KeyCode.DownArrow))
        {
            currentPosition += 1;
            eventInstance.setTimelinePosition(currentPosition);
        }

        Debug.Log("Current position: " + currentPosition);
    }
}

```

Now obviously no sound is played when I change the current position but think we’re getting on the right track.  
Now since you adviced me to not change the event emitter code, but how can I get the total timeline lenght so that I can do my % calc to compare to the ingame animations I’m using without accessing the protected eventDescription?

---

<div class="post-metadata">

**Author:** ![richard\_simms](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/richard_simms/32/261_2.png) [@richard\_simms](https://qa.fmod.com/u/richard_simms)\
**Post date:** [June 3, 2022, 3:00am UTC](https://qa.fmod.com/t/how-to-use-settimelineposition/18790/10 "2022-06-03T03:00:10Z")

</div>

I’m not certain what you mean by “protected eventDescription”. I’m able to get the event instance being played and access its event description to get the length of the event without issue. You should be able to do it like this:

```cs
public class TestSetTimelinePos : MonoBehaviour
{
    public StudioEventEmitter emitter;

    EventInstance eventInstance;
    EventDescription eventDescription;
    int eventLength;
    int currentPosition = 0;

    // Start is called before the first frame update
    void Start()
    {
        emitter.Play();
        eventInstance = emitter.EventInstance;
        eventInstance.getDescription(out eventDescription);
        eventDescription.getLength(out eventLength);
    }

}

```

---

<div class="post-metadata">

**Author:** ![MarsLit](https://avatars.discourse-cdn.com/v4/letter/m/7993a0/32.png) [@MarsLit](https://qa.fmod.com/u/MarsLit)\
**Post date:** [June 3, 2022, 6:34am UTC](https://qa.fmod.com/t/how-to-use-settimelineposition/18790/11 "2022-06-03T06:34:40Z")

</div>

Oh sorry just feel dumb.  
I’m almost there, I just need to understand how to resume from a playback after changing the timeline position. Everytime I start the sound it start from pos 0.

```auto
    void Update()
    {
        eventInstance.getTimelinePosition(out currentPosition);

        if (Input.GetKeyDown(KeyCode.UpArrow))
        {
            eventInstance.setTimelinePosition(0);
        }
        if (Input.GetKey(KeyCode.DownArrow))
        {
            currentPosition += 1;
            eventInstance.setTimelinePosition(currentPosition);
        }

        if (Input.GetKey(KeyCode.LeftArrow))
        {
            eventInstance.setPaused(false);
            eventInstance.start();
        }
        if (Input.GetKey(KeyCode.RightArrow))
        {
            eventInstance.setPaused(true);
        }

        Debug.Log("Current position: " + currentPosition);
    }

```

---

<div class="post-metadata">

**Author:** ![richard\_simms](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/richard_simms/32/261_2.png) [@richard\_simms](https://qa.fmod.com/u/richard_simms)\
**Post date:** [June 3, 2022, 6:49am UTC](https://qa.fmod.com/t/how-to-use-settimelineposition/18790/12 "2022-06-03T06:49:16Z")

</div>

> [@MarsLit](#):
>
> ```auto
> if (Input.GetKey(KeyCode.LeftArrow))
> {
> eventInstance.setPaused(false);
> eventInstance.start();
> }
> 
> ```

The problem is here - when you `start()` an event instance it will play from the beginning. You can just `setPause(false)` and it will unpause, playing from where you last paused.

---

<div class="post-metadata">

**Author:** ![MarsLit](https://avatars.discourse-cdn.com/v4/letter/m/7993a0/32.png) [@MarsLit](https://qa.fmod.com/u/MarsLit)\
**Post date:** [June 3, 2022, 9:31am UTC](https://qa.fmod.com/t/how-to-use-settimelineposition/18790/13 "2022-06-03T09:31:38Z")

</div>

Yep you’re right.  
But what I want to achieve is  
1: play the sound on start to get all reference (no one will hear it)  
2: set timeline pos to 0 just to be sure  
3: move timeline position to whatever I want  
4: play from the position I choose  
5: pause the sound  
6: change position back and forth and resume from there

---

<div class="post-metadata">

**Author:** ![richard\_simms](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/richard_simms/32/261_2.png) [@richard\_simms](https://qa.fmod.com/u/richard_simms)\
**Post date:** [June 6, 2022, 12:41am UTC](https://qa.fmod.com/t/how-to-use-settimelineposition/18790/14 "2022-06-06T00:41:11Z")

</div>

1. You can play then immediately pause the event instance
2. `setTimelinePosition(0)` will do that
3. `setTimelinePosition(x)` will do that
4. `setPaused(False)` will unpause and make the event play from the new position set in step 3
5. `setPause(True)` will pause the event
6. I’m not sure what you mean by changing the position back & forth but you can use the functions from steps 3 and 4/5 to move the timeline around
