微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

加载延迟超出警告 - 程序员工具 - Unity

如何解决加载延迟超出警告 - 程序员工具 - Unity

每当我尝试将 FMOD 中的示例代码用于 Programmer Instrument

我想也许我需要等待 FMOD.sound openState == READY,但这似乎不起作用。我错过了什么吗?这是我的代码

    public static void PlayDialogue(string key,Action callback = null)
    {
        // Create Instance
        FMOD.Studio.EventInstance dialogueInstance = FMODUnity.RuntimeManager.CreateInstance(instance.dialogueEvent);
        // Pin the key string in memory and pass a pointer through the user data
        GCHandle stringHandle = GCHandle.Alloc(key,GCHandleType.Pinned);
        dialogueInstance.setUserData(GCHandle.ToIntPtr(stringHandle));
        dialogueInstance.setCallback(instance.dialogueCallback);
    }
    
    [AOT.MonopInvokeCallback(typeof(FMOD.Studio.EVENT_CALLBACK))]
    static FMOD.RESULT DialogueCallback(FMOD.Studio.EVENT_CALLBACK_TYPE type,IntPtr instancePtr,IntPtr parameterPtr)
    {
        // Get Instance
        FMOD.Studio.EventInstance instance = new FMOD.Studio.EventInstance(instancePtr);

        // Retrieve the user data
        IntPtr stringPtr;
        instance.getUserData(out stringPtr);

        // Get the string object
        GCHandle stringHandle = GCHandle.FromIntPtr(stringPtr);
        String key = stringHandle.Target as String;

        switch (type)
        {
            case FMOD.Studio.EVENT_CALLBACK_TYPE.CREATE_PROGRAMMER_SOUND:
                {
                    FMOD.MODE soundMode = FMOD.MODE.LOOP_norMAL
                        | FMOD.MODE.CREATECOMpressedSAMPLE
                        | FMOD.MODE.NONBLOCKING;
                    FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES programmerSoundProperties =
                        (FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES)Marshal.PtrToStructure(
                            parameterPtr,typeof(FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES));
                    FMOD.sound dialogueSound;

                    if (key.Contains("."))
                    {
                        // Load Sound by Given Path
                        FMOD.RESULT soundResult = FMODUnity.RuntimeManager.CoreSystem.createSound(
                            Application.streamingAssetsPath + "/" + key,soundMode,out dialogueSound);
                        if (soundResult == FMOD.RESULT.OK)
                        {
                            programmerSoundProperties.sound = dialogueSound.handle;
                            programmerSoundProperties.subsoundindex = -1;
                            Marshal.StructuretoPtr(programmerSoundProperties,parameterPtr,false);
                            // Wait To Play
                            WaitForLoadThenPlay(instancePtr,parameterPtr);
                        }
                    }
                    else
                    {
                        // Load Sound Path
                        FMOD.Studio.soUND_INFO dialogueSoundInfo;
                        FMOD.RESULT keyResult = FMODUnity.RuntimeManager.StudioSystem.getSoundInfo(key,out dialogueSoundInfo);
                        if (keyResult != FMOD.RESULT.OK) break;
                        // Load Sound
                        FMOD.RESULT soundResult = FMODUnity.RuntimeManager.CoreSystem.createSound(
                            dialogueSoundInfo.name_or_data,soundMode | dialogueSoundInfo.mode,ref dialogueSoundInfo.exinfo,out dialogueSound);
                        if (soundResult == FMOD.RESULT.OK)
                        {
                            programmerSoundProperties.sound = dialogueSound.handle;
                            programmerSoundProperties.subsoundindex = dialogueSoundInfo.subsoundindex;
                            Marshal.StructuretoPtr(programmerSoundProperties,parameterPtr);
                        }
                    }
                    break;
                }
            case FMOD.Studio.EVENT_CALLBACK_TYPE.DESTROY_PROGRAMMER_SOUND:
                {
                    FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES parameter =
                        (FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES)Marshal.PtrToStructure(
                            parameterPtr,typeof(FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES));
                    FMOD.sound sound = new FMOD.sound(parameter.sound);
                    sound.release();
                    break;
                }
            case FMOD.Studio.EVENT_CALLBACK_TYPE.DESTROYED:
                {
                    // Now the event has been destroyed,unpin the string memory so it can be garbage collected
                    stringHandle.Free();
                    break;
                }
        }
        return FMOD.RESULT.OK;
    }

    private static void WaitForLoadThenPlay(IntPtr instancePtr,IntPtr parameterPtr)
        => instance.StartCoroutine(instance.WaitForLoadThenPlayRoutine(instancePtr,parameterPtr));
    private IEnumerator WaitForLoadThenPlayRoutine(IntPtr instancePtr,IntPtr parameterPtr)
    {
        // Get Instance
        FMOD.Studio.EventInstance instance = new FMOD.Studio.EventInstance(instancePtr);
        // Grab Sound Reference
        FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES parameter =
            (FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES)Marshal.PtrToStructure(
                parameterPtr,typeof(FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES));
        FMOD.sound sound = new FMOD.sound(parameter.sound);

        // Wait for Load
        FMOD.OPENSTATE state = FMOD.OPENSTATE.BUFFERING;
        uint percentbuffered;
        bool starving;
        bool diskbusy;
        while (state != FMOD.OPENSTATE.READY)
        {
            yield return null;
            sound.getopenState(out state,out percentbuffered,out starving,out diskbusy);
        }
        instance.start();
        instance.release();
    }

解决方法

这就是我最终做的事情。我不知道这是否有意义,但它确实消除了警告。我真的希望他们修复文档。示例脚本无法正常工作。

    public static void PlayDialogue(string key,Action callback = null) => instance.StartCoroutine(PlayDialogueRoutine(key,callback));
    public static IEnumerator PlayDialogueRoutine(string key,Action callback = null)
    {
        // Check if Already Playing
        if (instance.activeDialogue.ContainsKey(key))
        {
            Debug.LogError("Tried to play already playing dialogue");
            callback?.Invoke();
            yield break;
        }

        // Load Sound Path
        FMOD.Studio.SOUND_INFO dialogueSoundInfo;
        FMOD.RESULT keyResult = FMODUnity.RuntimeManager.StudioSystem.getSoundInfo(key,out dialogueSoundInfo);
        if (keyResult != FMOD.RESULT.OK)
        {
            Debug.LogError("Couldn't find dialogue with key: " + key);
            callback?.Invoke();
            yield break;
        }

        // Load Sound
        FMOD.Sound dialogueSound;
        FMOD.MODE soundMode = FMOD.MODE.LOOP_NORMAL
            | FMOD.MODE.CREATECOMPRESSEDSAMPLE
            | FMOD.MODE.NONBLOCKING;
        FMOD.RESULT soundResult = FMODUnity.RuntimeManager.CoreSystem.createSound(
            dialogueSoundInfo.name_or_data,soundMode | dialogueSoundInfo.mode,ref dialogueSoundInfo.exinfo,out dialogueSound);
        if (soundResult != FMOD.RESULT.OK)
        {
            Debug.LogError("Couldn't load sound: " + key);
            callback?.Invoke();
            yield break;
        }

        // Wait to Load
        int maxFrameWait = 120;
        FMOD.OPENSTATE openstate = FMOD.OPENSTATE.BUFFERING;
        uint percentbuffered;
        bool starving;
        bool diskbusy;
        while (openstate != FMOD.OPENSTATE.READY)
        {
            yield return null;
            dialogueSound.getOpenState(out openstate,out percentbuffered,out starving,out diskbusy);
            if (--maxFrameWait <= 0)
            {
                dialogueSound.release();
                Debug.LogError("Failed to load dialogue sound " + key);
                yield break;
            }
        }

        // Create Instance 
        FMOD.Studio.EventInstance dialogueInstance = FMODUnity.RuntimeManager.CreateInstance(instance.dialogueEvent);

        // Store Reference (and remove in play stopped callback) 
        instance.activeDialogue[key] = dialogueInstance;

        // Pin Memory
        FMODDialogueParameterWrapper soundWrapper = new FMODDialogueParameterWrapper(dialogueSound,dialogueSoundInfo,() =>
        {
            instance.activeDialogue.Remove(key);
            callback?.Invoke();
        });
        GCHandle soundWrapperHandle = GCHandle.Alloc(soundWrapper,GCHandleType.Pinned);
        dialogueInstance.setUserData(GCHandle.ToIntPtr(soundWrapperHandle));
        // Set Callback
        dialogueInstance.setCallback(instance.dialogueCallback,FMOD.Studio.EVENT_CALLBACK_TYPE.CREATE_PROGRAMMER_SOUND
            | FMOD.Studio.EVENT_CALLBACK_TYPE.CREATE_PROGRAMMER_SOUND
            | FMOD.Studio.EVENT_CALLBACK_TYPE.DESTROYED
            | FMOD.Studio.EVENT_CALLBACK_TYPE.STOPPED);

        // Play One Shot
        dialogueInstance.start();
        dialogueInstance.release();
    }

    [AOT.MonoPInvokeCallback(typeof(FMOD.Studio.EVENT_CALLBACK))]
    static FMOD.RESULT DialogueCallback(FMOD.Studio.EVENT_CALLBACK_TYPE type,IntPtr instancePtr,IntPtr parameterPtr)
    {
        // Get Instance
        FMOD.Studio.EventInstance instance = new FMOD.Studio.EventInstance(instancePtr);

        // Retrieve the user data FMODDialogueParameterWrapper
        IntPtr dialogueParameterWrapperPtr;
        FMOD.RESULT result = instance.getUserData(out dialogueParameterWrapperPtr);
        if (result != FMOD.RESULT.OK)
        {
            Debug.LogError("Failed to fetch user data for dialogue callback: " + result);
        }
        else if (dialogueParameterWrapperPtr != IntPtr.Zero)
        {
            GCHandle dialogueParameterWrapperHandle = GCHandle.FromIntPtr(dialogueParameterWrapperPtr);
            FMODDialogueParameterWrapper dialogueParameterWrapper =
                (FMODDialogueParameterWrapper)dialogueParameterWrapperHandle.Target;
            switch (type)
            {
                case FMOD.Studio.EVENT_CALLBACK_TYPE.CREATE_PROGRAMMER_SOUND:
                    {
                        FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES programmerSoundProperties =
                            (FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES)Marshal.PtrToStructure(
                                parameterPtr,typeof(FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES));
                        programmerSoundProperties.sound = dialogueParameterWrapper.sound.handle;
                        programmerSoundProperties.subsoundIndex = dialogueParameterWrapper.soundInfo.subsoundindex;
                        Marshal.StructureToPtr(programmerSoundProperties,parameterPtr,false);
                        break;
                    }
                case FMOD.Studio.EVENT_CALLBACK_TYPE.DESTROY_PROGRAMMER_SOUND:
                    {
                        FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES parameter =
                            (FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES)Marshal.PtrToStructure(
                                parameterPtr,typeof(FMOD.Studio.PROGRAMMER_SOUND_PROPERTIES));
                        FMOD.Sound sound = new FMOD.Sound(parameter.sound);
                        sound.release();
                        break;
                    }
                case FMOD.Studio.EVENT_CALLBACK_TYPE.DESTROYED:
                    {
                        // Now the event has been destroyed,unpin the string memory so it can be garbage collected
                        Debug.Log("Freeing");
                        dialogueParameterWrapperHandle.Free();
                        break;
                    }
                case FMOD.Studio.EVENT_CALLBACK_TYPE.STOPPED:
                    {
                        dialogueParameterWrapper.onStopCallback?.Invoke();
                        break;
                    }
            }
        }
        return FMOD.RESULT.OK;
    }

        [StructLayout(LayoutKind.Sequential)]
class FMODDialogueParameterWrapper
{
    public FMOD.Sound sound;
    public FMOD.Studio.SOUND_INFO soundInfo;
    public Action onStopCallback;

    public FMODDialogueParameterWrapper(FMOD.Sound sound,FMOD.Studio.SOUND_INFO soundInfo,Action onStopCallback)
    {
        this.sound = sound;
        this.soundInfo = soundInfo;
        this.onStopCallback = onStopCallback;
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?