Text print according to corresponding voice clip

All about user interface, be it customizing built-in UIs or adding new ones.
Post Reply
1668069501qq.com
Posts: 3
Joined: 27 Mar 2022 08:06

Text print according to corresponding voice clip

Post by 1668069501qq.com »

Is it possible to adpat the text printer speed to corresponding audio clip?
I have checked the TextPrinter class and it just has some basic speed options, lack of accessing to the voice clip.(I'm using a auto voice mode).
What I need is just print the text using the same time duration as the audio file.

1668069501qq.com
Posts: 3
Joined: 27 Mar 2022 08:06

Re: Text print according to corresponding voice clip

Post by 1668069501qq.com »

A Video to show what the result talking about: https://www.youtube.com/watch?v=WOze3BX ... x=4&t=235s

idaot
support
Posts: 275
Joined: 01 Aug 2020 08:25

Re: Text print according to corresponding voice clip

Post by idaot »

You can override the PrintTextAsync method in ITextPrinterManager with a method that matches the text rev eal duration to the played voice clip. You can obtain the voice clip path with GetPlayedVoicePath via the IAudioManager engine service.

More information on engine services can be found here: https://naninovel.com/guide/engine-serv ... e-services
Information on overriding built-in services can be found here: https://naninovel.com/guide/engine-serv ... n-services

1668069501qq.com
Posts: 3
Joined: 27 Mar 2022 08:06

Re: Text print according to corresponding voice clip

Post by 1668069501qq.com »


using System.Threading;
using UnityEngine;

namespace animals.NaniNovel.scripts
{
using Naninovel;
using Naninovel.Commands;

Code: Select all

[InitializeAtRuntime]
public class ChangeNextRevealSpeedService : IStatefulService<GameStateMap>
{
    [System.Serializable]
    class GameState { public float Modifier; }

    public float NextRevealSpeedMofifier { get; set; }

    public UniTask InitializeServiceAsync () => UniTask.CompletedTask;

    public void ResetService () => NextRevealSpeedMofifier = 1;

    public void DestroyService () { }

    public void SaveServiceState (GameStateMap stateMap)
    {
        var state = new GameState() { Modifier = NextRevealSpeedMofifier };
        stateMap.SetState(state);
    }

    public UniTask LoadServiceStateAsync (GameStateMap stateMap)
    {
        NextRevealSpeedMofifier = stateMap.GetState<GameState>()?.Modifier ?? 1;
        return UniTask.CompletedTask;
    }
}

[CommandAlias("s")]
public class ChangeNextRevealSpeedCommand : Command
{
    [ParameterAlias(NamelessParameterAlias), RequiredParameter]
    public DecimalParameter Modifier;

    public override UniTask ExecuteAsync (AsyncToken asyncToken)
    {
        Engine.GetService<ChangeNextRevealSpeedService>().NextRevealSpeedMofifier = Modifier;
        return UniTask.CompletedTask;
    }
}

[CommandAlias("print")]
public class MyCustomPrintCommand : PrintText
{
    protected override float AssignedRevealSpeed => base.AssignedRevealSpeed * 
                                                    Engine.GetService<ChangeNextRevealSpeedService>().NextRevealSpeedMofifier;

    protected float audioDuration=1;
    protected const float durationFactor=8;
    public override async UniTask PreloadResourcesAsync()
    {
        base.PreloadResourcesAsync();
        if (AudioManager.Configuration.EnableAutoVoicing && !string.IsNullOrEmpty(PlaybackSpot.ScriptName))
        {
            var voice = await AudioManager.VoiceLoader.LoadAsync(AutoVoicePath);
            var voice2=Resources.Load<AudioClip>("Naninovel/Voice/" + AutoVoicePath);
            if (voice.Object?.length!=null)
            {
                audioDuration = voice.Object.length;
                Engine.GetService<ChangeNextRevealSpeedService>().NextRevealSpeedMofifier =durationFactor/voice.Object.length;
            }
           
        }
    }

    public override async UniTask ExecuteAsync (AsyncToken asyncToken)
    {
        var voice = await AudioManager.VoiceLoader.LoadAsync(AutoVoicePath);

        await base.ExecuteAsync(asyncToken);
        Engine.GetService<ChangeNextRevealSpeedService>().NextRevealSpeedMofifier = durationFactor/voice.Object.length;
    }
}

}


I copy some codes online and adapt it. Basiclly it overrides the custom @print method, and get the voice clip length tochange the revealSpeed.

Post Reply