diff --git a/OWML.Assets/DontDestroyOnLoad.cs b/OWML.Assets/DontDestroyOnLoad.cs deleted file mode 100644 index 6f74c687..00000000 --- a/OWML.Assets/DontDestroyOnLoad.cs +++ /dev/null @@ -1,13 +0,0 @@ -using UnityEngine; - -namespace OWML.Assets -{ - public class DontDestroyOnLoad : MonoBehaviour - { - private void Start() - { - DontDestroyOnLoad(gameObject); - } - - } -} diff --git a/OWML.Assets/ModAssets.cs b/OWML.Assets/ModAssets.cs index d9cbf8ed..604501fa 100644 --- a/OWML.Assets/ModAssets.cs +++ b/OWML.Assets/ModAssets.cs @@ -16,79 +16,103 @@ public ModAssets(IModConsole console) _objImporter = new ObjImporter(); } - public GameObject Load3DObject(ModBehaviour modBehaviour, string objectFilename, string imageFilename) + public ObjectAsset Load3DObject(ModBehaviour modBehaviour, string objectFilename, string imageFilename) { var objectPath = modBehaviour.ModManifest.FolderPath + objectFilename; var imagePath = modBehaviour.ModManifest.FolderPath + imageFilename; _console.WriteLine("Loading object from " + objectPath); var go = new GameObject(); - go.AddComponent(); - var meshFilter = go.AddComponent(); - var meshRenderer = go.AddComponent(); + var modAsset = go.AddComponent(); - modBehaviour.StartCoroutine(LoadMesh(meshFilter, objectPath)); - modBehaviour.StartCoroutine(LoadTexture(meshRenderer, imagePath)); + modBehaviour.StartCoroutine(LoadMesh(modAsset, objectPath)); + modBehaviour.StartCoroutine(LoadTexture(modAsset, imagePath)); - return go; + return modAsset; } - public MeshFilter LoadMesh(ModBehaviour modBehaviour, string objectFilename) + public MeshAsset LoadMesh(ModBehaviour modBehaviour, string objectFilename) { var objectPath = modBehaviour.ModManifest.FolderPath + objectFilename; _console.WriteLine("Loading mesh from " + objectPath); var go = new GameObject(); - go.AddComponent(); - var meshFilter = go.AddComponent(); + var modAsset = go.AddComponent(); - modBehaviour.StartCoroutine(LoadMesh(meshFilter, objectPath)); + modBehaviour.StartCoroutine(LoadMesh(modAsset, objectPath)); - return meshFilter; + return modAsset; } - public MeshRenderer LoadTexture(ModBehaviour modBehaviour, string imageFilename) + public TextureAsset LoadTexture(ModBehaviour modBehaviour, string imageFilename) { var imagePath = modBehaviour.ModManifest.FolderPath + imageFilename; _console.WriteLine("Loading texture from " + imagePath); var go = new GameObject(); - go.AddComponent(); - var meshRenderer = go.AddComponent(); + var modAsset = go.AddComponent(); - modBehaviour.StartCoroutine(LoadTexture(meshRenderer, imagePath)); + modBehaviour.StartCoroutine(LoadTexture(modAsset, imagePath)); - return meshRenderer; + return modAsset; } - public AudioSource LoadAudio(ModBehaviour modBehaviour, string audioFilename) + public AudioAsset LoadAudio(ModBehaviour modBehaviour, string audioFilename) { var audioPath = modBehaviour.ModManifest.FolderPath + audioFilename; _console.WriteLine("Loading audio from " + audioPath); var go = new GameObject(); - go.AddComponent(); - var audioSource = go.AddComponent(); + var modAsset = go.AddComponent(); var loadAudioFrom = audioFilename.EndsWith(".mp3") - ? LoadAudioFromMp3(audioSource, audioPath) - : LoadAudioFromWav(audioSource, audioPath); + ? LoadAudioFromMp3(modAsset, audioPath) + : LoadAudioFromWav(modAsset, audioPath); modBehaviour.StartCoroutine(loadAudioFrom); - return audioSource; + + return modAsset; + } + + private IEnumerator LoadMesh(ObjectAsset modAsset, string objectPath) + { + var mesh = _objImporter.ImportFile(objectPath); + var meshFilter = modAsset.AddComponent(); + meshFilter.mesh = mesh; + yield return new WaitForEndOfFrame(); + modAsset.SetAsset(modAsset.gameObject); + } + + private IEnumerator LoadTexture(ObjectAsset modAsset, string imagePath) + { + var texture = new Texture2D(4, 4, TextureFormat.DXT1, false); + var url = "file://" + imagePath; + using (var www = new WWW(url)) + { + yield return www; + www.LoadImageIntoTexture(texture); + } + if (texture == null) + { + _console.WriteLine("Texture is null"); + } + var meshRenderer = modAsset.AddComponent(); + meshRenderer.material.mainTexture = texture; } - private IEnumerator LoadMesh(MeshFilter meshFilter, string objectPath) + private IEnumerator LoadMesh(MeshAsset modAsset, string objectPath) { var mesh = _objImporter.ImportFile(objectPath); if (mesh == null) { _console.WriteLine("Mesh is null"); } + var meshFilter = modAsset.AddComponent(); meshFilter.mesh = mesh; - yield return null; + yield return new WaitForEndOfFrame(); + modAsset.SetAsset(meshFilter); } - private IEnumerator LoadTexture(MeshRenderer meshRenderer, string imagePath) + private IEnumerator LoadTexture(TextureAsset modAsset, string imagePath) { var texture = new Texture2D(4, 4, TextureFormat.DXT1, false); var url = "file://" + imagePath; @@ -101,39 +125,45 @@ private IEnumerator LoadTexture(MeshRenderer meshRenderer, string imagePath) { _console.WriteLine("Texture is null"); } + var meshRenderer = modAsset.AddComponent(); meshRenderer.material.mainTexture = texture; + yield return new WaitForEndOfFrame(); + modAsset.SetAsset(meshRenderer); } - private IEnumerator LoadAudioFromMp3(AudioSource audioSource, string audioPath) + private IEnumerator LoadAudioFromMp3(AudioAsset modAsset, string audioPath) { - _console.WriteLine("Loading mp3"); - AudioClip audioClip; + AudioClip clip; using (var reader = new AudioFileReader(audioPath)) { var outputBytes = new float[reader.Length]; reader.Read(outputBytes, 0, (int)reader.Length); - audioClip = AudioClip.Create(audioPath, (int)reader.Length, reader.WaveFormat.Channels, reader.WaveFormat.SampleRate, false); - audioClip.SetData(outputBytes, 0); + clip = AudioClip.Create(audioPath, (int)reader.Length, reader.WaveFormat.Channels, reader.WaveFormat.SampleRate, false); + clip.SetData(outputBytes, 0); } - audioSource.clip = audioClip; - yield return null; + var audioSource = modAsset.AddComponent(); + audioSource.clip = clip; + yield return new WaitForEndOfFrame(); + modAsset.SetAsset(audioSource); } - private IEnumerator LoadAudioFromWav(AudioSource audioSource, string audioPath) + private IEnumerator LoadAudioFromWav(AudioAsset modAsset, string audioPath) { - _console.WriteLine("Loading wav"); - AudioClip audio; + AudioClip clip; var url = "file://" + audioPath; using (var www = new WWW(url)) { yield return www; - audio = www.GetAudioClip(true); + clip = www.GetAudioClip(true); } - if (audio == null) + if (clip == null) { _console.WriteLine("Audio is null"); } - audioSource.clip = audio; + var audioSource = modAsset.AddComponent(); + audioSource.clip = clip; + yield return new WaitForEndOfFrame(); + modAsset.SetAsset(audioSource); } } diff --git a/OWML.Assets/OWML.Assets.csproj b/OWML.Assets/OWML.Assets.csproj index 54db7c7a..686e3a53 100644 --- a/OWML.Assets/OWML.Assets.csproj +++ b/OWML.Assets/OWML.Assets.csproj @@ -56,7 +56,6 @@ - diff --git a/OWML.Common/AudioAsset.cs b/OWML.Common/AudioAsset.cs new file mode 100644 index 00000000..1b089b22 --- /dev/null +++ b/OWML.Common/AudioAsset.cs @@ -0,0 +1,8 @@ +using UnityEngine; + +namespace OWML.Common +{ + public class AudioAsset : ModAsset + { + } +} diff --git a/OWML.Common/IHarmonyHelper.cs b/OWML.Common/IHarmonyHelper.cs index 2025235f..af1e6112 100644 --- a/OWML.Common/IHarmonyHelper.cs +++ b/OWML.Common/IHarmonyHelper.cs @@ -1,5 +1,4 @@ using System; -using UnityEngine; namespace OWML.Common { diff --git a/OWML.Common/IModAssets.cs b/OWML.Common/IModAssets.cs index 5a641922..72a71f9c 100644 --- a/OWML.Common/IModAssets.cs +++ b/OWML.Common/IModAssets.cs @@ -1,12 +1,10 @@ -using UnityEngine; - -namespace OWML.Common +namespace OWML.Common { public interface IModAssets { - GameObject Load3DObject(ModBehaviour modBehaviour, string objectFilename, string imageFilename); - MeshFilter LoadMesh(ModBehaviour modBehaviour, string objectFilename); - MeshRenderer LoadTexture(ModBehaviour modBehaviour, string imageFilename); - AudioSource LoadAudio(ModBehaviour modBehaviour, string audioFilename); + ObjectAsset Load3DObject(ModBehaviour modBehaviour, string objectFilename, string imageFilename); + MeshAsset LoadMesh(ModBehaviour modBehaviour, string objectFilename); + TextureAsset LoadTexture(ModBehaviour modBehaviour, string imageFilename); + AudioAsset LoadAudio(ModBehaviour modBehaviour, string audioFilename); } } diff --git a/OWML.Common/MeshAsset.cs b/OWML.Common/MeshAsset.cs new file mode 100644 index 00000000..b2d46b8d --- /dev/null +++ b/OWML.Common/MeshAsset.cs @@ -0,0 +1,8 @@ +using UnityEngine; + +namespace OWML.Common +{ + public class MeshAsset : ModAsset + { + } +} diff --git a/OWML.Common/ModAsset.cs b/OWML.Common/ModAsset.cs new file mode 100644 index 00000000..687a6705 --- /dev/null +++ b/OWML.Common/ModAsset.cs @@ -0,0 +1,33 @@ +using System; +using UnityEngine; + +namespace OWML.Common +{ + public class ModAsset : MonoBehaviour + { + public event Action OnLoaded; + + public T Asset { get; private set; } + + public void SetAsset(T asset) + { + Asset = asset; + if (OnLoaded == null) + { + ModBehaviour.ModHelper.Console.WriteLine("Invoking OnLoaded with no subscribers :("); + } + OnLoaded?.Invoke(asset); + } + + private void Start() + { + DontDestroyOnLoad(gameObject); + } + + public T1 AddComponent() where T1 : Component + { + return gameObject.AddComponent(); + } + + } +} diff --git a/OWML.Common/OWML.Common.csproj b/OWML.Common/OWML.Common.csproj index 960c7407..eb8ba7db 100644 --- a/OWML.Common/OWML.Common.csproj +++ b/OWML.Common/OWML.Common.csproj @@ -55,12 +55,17 @@ + + + + + diff --git a/OWML.Common/ObjectAsset.cs b/OWML.Common/ObjectAsset.cs new file mode 100644 index 00000000..c73cab6f --- /dev/null +++ b/OWML.Common/ObjectAsset.cs @@ -0,0 +1,8 @@ +using UnityEngine; + +namespace OWML.Common +{ + public class ObjectAsset : ModAsset + { + } +} diff --git a/OWML.Common/TextureAsset.cs b/OWML.Common/TextureAsset.cs new file mode 100644 index 00000000..2ebe28b4 --- /dev/null +++ b/OWML.Common/TextureAsset.cs @@ -0,0 +1,8 @@ +using UnityEngine; + +namespace OWML.Common +{ + public class TextureAsset : ModAsset + { + } +} diff --git a/OWML.Launcher/App.cs b/OWML.Launcher/App.cs index 777b3734..d29115f5 100644 --- a/OWML.Launcher/App.cs +++ b/OWML.Launcher/App.cs @@ -11,7 +11,7 @@ namespace OWML.Launcher { public class App { - private const string OWMLVersion = "0.2.2"; + private const string OWMLVersion = "0.2.3"; private readonly string[] _filesToCopy = { "UnityEngine.CoreModule.dll", "Assembly-CSharp.dll" }; diff --git a/OWML.SampleMods/OWML.EnableDebugMode/manifest.json b/OWML.SampleMods/OWML.EnableDebugMode/manifest.json index 9652d9ef..1a389093 100644 --- a/OWML.SampleMods/OWML.EnableDebugMode/manifest.json +++ b/OWML.SampleMods/OWML.EnableDebugMode/manifest.json @@ -4,6 +4,6 @@ "name": "EnableDebugMode", "uniqueName": "Alek.EnableDebugMode", "version": "0.2", - "owmlVersion": "0.2.2", + "owmlVersion": "0.2.3", "enabled": false } \ No newline at end of file diff --git a/OWML.SampleMods/OWML.LoadCustomAssets/LoadCustomAssets.cs b/OWML.SampleMods/OWML.LoadCustomAssets/LoadCustomAssets.cs index 8f2904ff..0bb506d2 100644 --- a/OWML.SampleMods/OWML.LoadCustomAssets/LoadCustomAssets.cs +++ b/OWML.SampleMods/OWML.LoadCustomAssets/LoadCustomAssets.cs @@ -15,28 +15,42 @@ public class LoadCustomAssets : ModBehaviour private void Start() { ModHelper.Console.WriteLine($"In {nameof(LoadCustomAssets)}!"); - _duckBody = CreateDuck(); - _shootSound = ModHelper.Assets.LoadAudio(this, "blaster-firing.wav"); - _music = ModHelper.Assets.LoadAudio(this, "spiral-mountain.mp3"); - ModHelper.Events.AddEvent(Common.Events.AfterStart); + var gunSoundAsset = ModHelper.Assets.LoadAudio(this, "blaster-firing.wav"); + gunSoundAsset.OnLoaded += OnGunSoundLoaded; + var duckAsset = ModHelper.Assets.Load3DObject(this, "duck.obj", "duck.png"); + duckAsset.OnLoaded += OnDuckLoaded; + var musicAsset = ModHelper.Assets.LoadAudio(this, "spiral-mountain.mp3"); + musicAsset.OnLoaded += OnMusicLoaded; + ModHelper.Events.AddEvent(Common.Events.AfterAwake); ModHelper.Events.OnEvent += OnEvent; } - private OWRigidbody CreateDuck() + private void OnMusicLoaded(AudioSource audio) { - var duck = ModHelper.Assets.Load3DObject(this, "duck.obj", "duck.png"); + _music = audio; + ModHelper.Console.WriteLine("Music loaded!"); + } + + private void OnGunSoundLoaded(AudioSource audio) + { + _shootSound = audio; + ModHelper.Console.WriteLine("Gun sound loaded!"); + } + + private void OnDuckLoaded(GameObject duck) + { + ModHelper.Console.WriteLine("Duck loaded!"); duck.AddComponent(); duck.AddComponent(); - var duckBody = duck.AddComponent(); - return duckBody; + _duckBody = duck.AddComponent(); } private void OnEvent(MonoBehaviour behaviour, Common.Events ev) { - if (behaviour.GetType() == typeof(Flashlight) && ev == Common.Events.AfterStart) + if (behaviour.GetType() == typeof(PlayerBody) && ev == Common.Events.AfterAwake) { - _playerTransform = Locator.GetPlayerTransform(); - _playerBody = _playerTransform.GetAttachedOWRigidbody(); + _playerBody = (PlayerBody)behaviour; + _playerTransform = behaviour.transform; _isStarted = true; _music.Play(); } @@ -54,7 +68,7 @@ private void ShootDuck() { ModHelper.Console.WriteLine("Shooting duck"); var duckBody = Instantiate(_duckBody); - duckBody.SetPosition(_playerTransform.position + _playerTransform.forward * 1f); + duckBody.SetPosition(_playerTransform.position + _playerTransform.forward * 2f); duckBody.SetRotation(_playerTransform.rotation); duckBody.SetVelocity(_playerBody.GetVelocity() + _playerTransform.forward * 10f); _shootSound.Play(); diff --git a/OWML.SampleMods/OWML.LoadCustomAssets/manifest.json b/OWML.SampleMods/OWML.LoadCustomAssets/manifest.json index 56ae8d24..5b32ee8b 100644 --- a/OWML.SampleMods/OWML.LoadCustomAssets/manifest.json +++ b/OWML.SampleMods/OWML.LoadCustomAssets/manifest.json @@ -4,6 +4,6 @@ "name": "LoadCustomAssets", "uniqueName": "Alek.LoadCustomAssets", "version": "0.2", - "owmlVersion": "0.2.2", + "owmlVersion": "0.2.3", "enabled": false } \ No newline at end of file diff --git a/OWML.SampleMods/OWML.TestMod/manifest.json b/OWML.SampleMods/OWML.TestMod/manifest.json index d9dc9433..84e61737 100644 --- a/OWML.SampleMods/OWML.TestMod/manifest.json +++ b/OWML.SampleMods/OWML.TestMod/manifest.json @@ -4,6 +4,6 @@ "name": "TestMod", "uniqueName": "Alek.TestMod", "version": "0.1", - "owmlVersion": "0.2.2", + "owmlVersion": "0.2.3", "enabled": false } \ No newline at end of file diff --git a/Readme.md b/Readme.md index ec6efc91..91b8bb1d 100644 --- a/Readme.md +++ b/Readme.md @@ -103,8 +103,11 @@ ModHelper.Assets lets you load assets at runtime. See the sample mod OWML.LoadCu Put your custom assets in your mod folder, then load them like this: ~~~~ -var duck = ModHelper.Assets.Load3DObject(this, "duck.obj", "duck.png"); -var audio = ModHelper.Assets.LoadAudio(this, "blaster-firing.wav"); +var duckAsset = ModHelper.Assets.Load3DObject(this, "duck.obj", "duck.png"); +duckAsset.OnLoaded += duck => ... + +var audioAsset = ModHelper.Assets.LoadAudio(this, "blaster-firing.wav"); +audioAsset.OnLoaded += audioSource => ... ~~~~ It's recommended to load custom assets at the start of the game, then copy/play when needed, like this: @@ -190,7 +193,7 @@ Add a manifest file called manifest.json. Example: "name": "EnableDebugMode", "uniqueName": "Alek.EnableDebugMode", "version": "0.1", - "owmlVersion": "0.2.2", + "owmlVersion": "0.2.3", "enabled": true } ~~~~