Jump to content

KSP keeps unloading my sound files from GameDatabase.Instance


Recommended Posts

So basically this is what happens: Sound works as  intended when flight is entered. I go to tracking station, and fly the same craft again.

When I check to see if the database contains my AudioClip, it returns false  after the reload.

Code:

Spoiler

using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

namespace SoundsOfSpace {

    [RequireComponent(typeof(AudioSource))]
    [KSPAddon(KSPAddon.Startup.Flight, false)]
    public class SoundsOfSpace : UnityEngine.MonoBehaviour {

        private Dictionary<string, UnityEngine.AudioClip> planetMap = new Dictionary<string, UnityEngine.AudioClip>();
        private Dictionary<AudioClip, string> fileNames = new Dictionary<AudioClip, string>();

        private GameObject sourceObject;
        private AudioSource source;

        IEnumerator<int> LoadSounds() {
            string pluginDir = AssemblyLoader.loadedAssemblies.GetPathByType(typeof(SoundsOfSpace));
            string sounds_root = pluginDir.Substring(0, pluginDir.IndexOf("SoundsOfSpace") + 13) + "/Sounds/SoundsOfSpace/";
            sounds_root = sounds_root.Replace('\\', '/');
            Debug.Log("[SoundsOfSpace]  " + "Sound directory: " + sounds_root);
            if(Directory.Exists(sounds_root)) {
                string[] strArray = Directory.GetFiles(sounds_root, "*.ogg");
                foreach(string file in strArray) {
                    Debug.Log("[SoundsOfSpace] " + "Loading file: " + file);
                    int len = sounds_root.Length;
                    string filename = file.Substring(len);
                    int dotpos = filename.LastIndexOf(".");

                    string name = filename.Substring(0, dotpos);

                    string gdb_path = "SoundsOfSpace/Sounds/SoundsOfSpace/" + name;
                    if(GameDatabase.Instance.ExistsAudioClip(gdb_path)) {
                        AudioClip clip = GameDatabase.Instance.GetAudioClip(gdb_path);
                        clip.name = name;
                        planetMap.Add(name, clip);
                        fileNames.Add(clip, name);
                        Debug.Log("[SoundsOfSpace] " + "Clip " + clip.name + " loaded OK");
                    } else {
                        Debug.LogWarning("[SoundsOfSpace] " + "Failed to load file through database: " + gdb_path);

                        // Try again with www method.

                        WWW www = new WWW("file://" + sounds_root + name + ".ogg");
                        while(!www.isDone) {
                            yield return 1;
                        }
                        if(www.GetAudioClip() != null) {
                            AudioClip clip2 = www.GetAudioClip(false, false);
                            clip2.LoadAudioData();
                            clip2.name = name;
                            planetMap.Add(name, clip2);
                            fileNames.Add(clip2, name);
                            Debug.Log("[SoundsOfSpace] " + "Clip " + clip2.name + " loaded OK");
                        } else {
                            Debug.LogError("[SoundsOfSpace] " + "Failed to load " + gdb_path + " with secondary method.");
                        }
                    }
                }

            }
        }

        public void Start() {

            // Load sounds into dictionary

            StartCoroutine(LoadSounds());

            sourceObject = new GameObject();
            sourceObject.name = "SOS Audio Player Object";
            source = sourceObject.AddComponent<AudioSource>();
            source.name = "SOS Audio Source";
            source.spatialBlend = 0.0f;
            source.spatialize = false;
            source.loop = true;
            source.volume = 1.3f;
            source.mute = false;
            source.enabled = true;

            Debug.Log("[SoundsOfSpace] " + "Sound player created.");

            GameEvents.onVesselSOIChanged.Add(OnVesselSOIChanged);
            GameEvents.onVesselChange.Add(OnVesselChange);
            GameEvents.onVesselSituationChange.Add(OnVesselSituationChange);
            Debug.Log("[SoundsOfSpace] " + "Events registered.");

            if(FlightGlobals.ActiveVessel != null) {
                OnVesselChange(FlightGlobals.ActiveVessel);
            }
        }

        void playClipFor(Vessel vessel, CelestialBody body) {
            if(source.isPlaying) {
                Debug.Log("[SoundsOfSpace] " + "Audio playing already. Stopping.");
                source.Stop();
            }
            String planetName = body.GetName();
            AudioClip clipForBody = null;
            bool foundClip = planetMap.TryGetValue(planetName, out clipForBody);
            if(foundClip) {
                Debug.Log("[SoundsOfSpace] " + "Play clip for " + planetName + ": " + clipForBody);
                source.clip = clipForBody;
                sourceObject.SetActive(true);
                source.Play();
            } else {
                Debug.LogWarning("[SoundsOfSpace] " + "Did not find audio clip for body: " + planetName);
                if(source.isPlaying) {
                    source.Stop();
                }
            }
        }

        void stopPlaying() {
            if(source.isPlaying) {
                source.Stop();
            }
        }

        void OnVesselSOIChanged(GameEvents.HostedFromToAction<Vessel, CelestialBody> data) {
            if(data.host.isActiveVessel) {
                Debug.Log("[SoundsOfSpace] " + "SOI Changed detected. Changing sounds.");
                if(data.host.situation == Vessel.Situations.ORBITING || data.host.situation == Vessel.Situations.ESCAPING || data.host.situation == Vessel.Situations.DOCKED) {
                    playClipFor(data.host, data.to);
                } else {
                    Debug.Log("[SoundsOfSpace] " + "Canceled due to non orbital trajectory.");
                    stopPlaying();
                }
            }
        }

        void OnVesselChange(Vessel data) {
            if(FlightGlobals.ActiveVessel != null) {
                Debug.Log("[SoundsOfSpace] " + "Vessel changed, getting new sounds.");
                if(data.situation == Vessel.Situations.ORBITING || data.situation == Vessel.Situations.ESCAPING || data.situation == Vessel.Situations.DOCKED) {
                    playClipFor(data, data.mainBody);
                } else {
                    Debug.Log("[SoundsOfSpace] " + "Canceled due to non orbital trajectory.");
                    stopPlaying();
                }
            }
        }

        void OnVesselSituationChange(GameEvents.HostedFromToAction<Vessel, Vessel.Situations> data) {
            if(FlightGlobals.ActiveVessel != null && data.host.isActiveVessel) {
                if(source.isPlaying) {
                    if(!(data.host.situation == Vessel.Situations.ORBITING || data.host.situation == Vessel.Situations.ESCAPING || data.host.situation == Vessel.Situations.DOCKED)) {
                        Debug.Log("[SoundsOfSpace] " + "Vessel has landed or gone suborbital. Stopping Sound.");
                        stopPlaying();
                    }
                } else {
                    if(data.host.situation == Vessel.Situations.ORBITING || data.host.situation == Vessel.Situations.ESCAPING || data.host.situation == Vessel.Situations.DOCKED) {
                        OnVesselChange(data.host); // Update sounds
                    }
                }
            }
        }

        internal void OnDestroy() {
            GameEvents.onVesselSOIChanged.Remove(OnVesselSOIChanged);
            GameEvents.onVesselChange.Remove(OnVesselChange);
            GameEvents.onVesselSituationChange.Remove(OnVesselSituationChange);
            Debug.Log("[SoundsOfSpace] " + "Events unregistered.");
        }

    }
}

 

I have the WWW method as a secondary but  currently that doesn't work and crashes the game because it loads too much at once. That's aside from the point. The real problem is that ExistsAudioClip is false the second  time the flight scene is entered.

Any ideas?

Also, the mod is  a mod that  adds NASA's sounds of planets to the game while orbiting planets :)

Link to comment
Share on other sites

 

AudioClip clip = GameDatabase.Instance.GetAudioClip(gdb_path);
clip.name = name; // <----- bad plan
planetMap.Add(name, clip);
fileNames.Add(clip, name);

I haven't tried running your code but at a glance this stands out. Usually the GameDatabase names are the GameData-relative URLs, so on your first run this clip will likely be named something like SoundsOfSpace/Sounds/SoundsOfSpace/yourfile

After successfully finding this clip the first time, you inexplicably rename it to yourfile.ogg. This will be a problem because GameDatabase.Instance.ExistsAudioClip is checking the clip names for a match

Link to comment
Share on other sites

10 hours ago, xEvilReeperx said:

 


AudioClip clip = GameDatabase.Instance.GetAudioClip(gdb_path);
clip.name = name; // <----- bad plan
planetMap.Add(name, clip);
fileNames.Add(clip, name);

I haven't tried running your code but at a glance this stands out. Usually the GameDatabase names are the GameData-relative URLs, so on your first run this clip will likely be named something like SoundsOfSpace/Sounds/SoundsOfSpace/yourfile

After successfully finding this clip the first time, you inexplicably rename it to yourfile.ogg. This will be a problem because GameDatabase.Instance.ExistsAudioClip is checking the clip names for a match

Thanks! Let me give this a try and get back.

Link to comment
Share on other sites

10 hours ago, xEvilReeperx said:

 


AudioClip clip = GameDatabase.Instance.GetAudioClip(gdb_path);
clip.name = name; // <----- bad plan
planetMap.Add(name, clip);
fileNames.Add(clip, name);

I haven't tried running your code but at a glance this stands out. Usually the GameDatabase names are the GameData-relative URLs, so on your first run this clip will likely be named something like SoundsOfSpace/Sounds/SoundsOfSpace/yourfile

After successfully finding this clip the first time, you inexplicably rename it to yourfile.ogg. This will be a problem because GameDatabase.Instance.ExistsAudioClip is checking the clip names for a match

Thank you! This fixed it. You're right,  it did change the name  from SoundsOfSpace/Sounds/SoundsOfSpace/file  to "file", which was causing  the error.

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...