mirror of
https://github.com/RHeavenStudio/HeavenStudio.git
synced 2025-06-12 12:17:37 +02:00
Allow games to load assets from AssetBundles (#102)
* Loading improvements: prepwork for loading from assetbundles * note for sfx * cleaner code * correct type * put loaded assetbundle in the minigame data instead also lays groundwork for future localization stuff * add samurai slice gold, coin toss assetbundles * very messy "already loaded" checks * make Dj School load from assetbundle
This commit is contained in:
@ -31,7 +31,7 @@ namespace HeavenStudio
|
||||
Coroutine currentGameSwitchIE;
|
||||
|
||||
[Header("Properties")]
|
||||
public int currentEvent, currentTempoEvent;
|
||||
public int currentEvent, currentTempoEvent, currentPreEvent, currentPreSwitch;
|
||||
public float startOffset;
|
||||
public bool playOnStart;
|
||||
public float startBeat;
|
||||
@ -57,7 +57,11 @@ namespace HeavenStudio
|
||||
|
||||
public void Init()
|
||||
{
|
||||
currentPreEvent= 0;
|
||||
currentPreSwitch = 0;
|
||||
|
||||
this.transform.localScale = new Vector3(30000000, 30000000);
|
||||
|
||||
SpriteRenderer sp = this.gameObject.AddComponent<SpriteRenderer>();
|
||||
sp.enabled = false;
|
||||
sp.color = Color.black;
|
||||
@ -148,6 +152,49 @@ namespace HeavenStudio
|
||||
}
|
||||
}
|
||||
|
||||
public void SeekAheadAndPreload(float start, float seekTime = 8f)
|
||||
{
|
||||
//seek ahead to preload games that have assetbundles
|
||||
//check game switches first
|
||||
var gameSwitchs = Beatmap.entities.FindAll(c => c.datamodel.Split(1) == "switchGame");
|
||||
if (currentPreSwitch < gameSwitchs.Count && currentPreSwitch >= 0)
|
||||
{
|
||||
if (start + seekTime >= gameSwitchs[currentPreSwitch].beat)
|
||||
{
|
||||
string gameName = gameSwitchs[currentPreSwitch].datamodel.Split(2);
|
||||
var inf = GetGameInfo(gameName);
|
||||
if (inf.usesAssetBundle && !inf.AssetsLoaded)
|
||||
{
|
||||
Debug.Log("ASYNC loading assetbundle for game " + gameName);
|
||||
StartCoroutine(inf.LoadCommonAssetBundleAsync());
|
||||
StartCoroutine(inf.LoadLocalizedAssetBundleAsync());
|
||||
}
|
||||
currentPreSwitch++;
|
||||
}
|
||||
}
|
||||
//then check game entities
|
||||
List<float> entities = Beatmap.entities.Select(c => c.beat).ToList();
|
||||
if (currentPreEvent < Beatmap.entities.Count && currentPreEvent >= 0)
|
||||
{
|
||||
if (start + seekTime >= entities[currentPreEvent])
|
||||
{
|
||||
var entitiesAtSameBeat = Beatmap.entities.FindAll(c => c.beat == Beatmap.entities[currentPreEvent].beat && !EventCaller.FXOnlyGames().Contains(EventCaller.instance.GetMinigame(c.datamodel.Split('/')[0])));
|
||||
for (int i = 0; i < entitiesAtSameBeat.Count; i++)
|
||||
{
|
||||
string gameName = entitiesAtSameBeat[i].datamodel.Split('/')[0];
|
||||
var inf = GetGameInfo(gameName);
|
||||
if (inf.usesAssetBundle && !inf.AssetsLoaded)
|
||||
{
|
||||
Debug.Log("ASYNC loading assetbundle for game " + gameName);
|
||||
StartCoroutine(inf.LoadCommonAssetBundleAsync());
|
||||
StartCoroutine(inf.LoadLocalizedAssetBundleAsync());
|
||||
}
|
||||
}
|
||||
currentPreEvent++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// LateUpdate works a bit better(?) but causes some bugs (like issues with bop animations).
|
||||
private void Update()
|
||||
{
|
||||
@ -171,6 +218,10 @@ namespace HeavenStudio
|
||||
}
|
||||
}
|
||||
|
||||
float seekTime = 8f;
|
||||
//seek ahead to preload games that have assetbundles
|
||||
SeekAheadAndPreload(Conductor.instance.songPositionInBeats, seekTime);
|
||||
|
||||
if (currentEvent < Beatmap.entities.Count && currentEvent >= 0)
|
||||
{
|
||||
if (Conductor.instance.songPositionInBeats >= entities[currentEvent] /*&& SongPosLessThanClipLength(Conductor.instance.songPositionInBeats)*/)
|
||||
@ -281,6 +332,7 @@ namespace HeavenStudio
|
||||
List<float> entities = Beatmap.entities.Select(c => c.beat).ToList();
|
||||
|
||||
currentEvent = entities.IndexOf(Mathp.GetClosestInList(entities, beat));
|
||||
currentPreEvent = entities.IndexOf(Mathp.GetClosestInList(entities, beat));
|
||||
|
||||
var gameSwitchs = Beatmap.entities.FindAll(c => c.datamodel.Split(1) == "switchGame");
|
||||
|
||||
@ -289,6 +341,7 @@ namespace HeavenStudio
|
||||
if (gameSwitchs.Count > 0)
|
||||
{
|
||||
int index = gameSwitchs.FindIndex(c => c.beat == Mathp.GetClosestInList(gameSwitchs.Select(c => c.beat).ToList(), beat));
|
||||
currentPreSwitch = index;
|
||||
var closestGameSwitch = gameSwitchs[index];
|
||||
if (closestGameSwitch.beat <= beat)
|
||||
{
|
||||
@ -342,6 +395,8 @@ namespace HeavenStudio
|
||||
}
|
||||
// Debug.Log("currentTempoEvent is now " + currentTempoEvent);
|
||||
}
|
||||
|
||||
SeekAheadAndPreload(beat);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -434,6 +489,14 @@ namespace HeavenStudio
|
||||
return !newGameInfo.fxOnly;
|
||||
}).ToList()[0].datamodel.Split(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gameInfo.usesAssetBundle)
|
||||
{
|
||||
//game is packed in an assetbundle, load from that instead
|
||||
return gameInfo.GetCommonAssetBundle().LoadAsset<GameObject>(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Resources.Load<GameObject>($"Games/{name}");
|
||||
}
|
||||
|
@ -38,7 +38,11 @@ namespace HeavenStudio.Games.Loaders
|
||||
new Param("colorA", Color.white, "Start Color", "The starting color in the fade"),
|
||||
new Param("colorB", CoinToss.defaultFgColor, "End Color", "The ending color in the fade")
|
||||
} ),
|
||||
});
|
||||
},
|
||||
new List<string>() {"ntr", "aim"},
|
||||
"ntrcoin", "en",
|
||||
new List<string>() {}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,11 @@ namespace HeavenStudio.Games.Loaders
|
||||
{
|
||||
new Param("type", DJSchool.DJVoice.Standard, "Voice", "The voice line to play"),
|
||||
}),
|
||||
});
|
||||
},
|
||||
new List<string>() {"ntr", "normal"},
|
||||
"ntrdj", "en",
|
||||
new List<string>(){}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,51 +12,55 @@ namespace HeavenStudio.Games.Loaders
|
||||
{
|
||||
public static Minigame AddGame(EventCaller eventCaller) {
|
||||
return new Minigame("fanClub", "Fan Club", "FDFD00", false, false, new List<GameAction>()
|
||||
{
|
||||
new GameAction("bop", delegate { var e = eventCaller.currentEntity; FanClub.instance.Bop(e.beat, e.length, e.type); }, 0.5f, true, parameters: new List<Param>()
|
||||
{
|
||||
new Param("type", FanClub.IdolBopType.Both, "Bop target", "Who to make bop"),
|
||||
}),
|
||||
|
||||
new GameAction("yeah, yeah, yeah", delegate { var e = eventCaller.currentEntity; FanClub.instance.CallHai(e.beat, e.toggle); }, 8, false, parameters: new List<Param>()
|
||||
new GameAction("bop", delegate { var e = eventCaller.currentEntity; FanClub.instance.Bop(e.beat, e.length, e.type); }, 0.5f, true, parameters: new List<Param>()
|
||||
{
|
||||
new Param("toggle", false, "Disable call", "Disable the idol's call")
|
||||
},
|
||||
inactiveFunction: delegate { var e = eventCaller.currentEntity; FanClub.WarnHai(e.beat, e.toggle);}
|
||||
),
|
||||
new Param("type", FanClub.IdolBopType.Both, "Bop target", "Who to make bop"),
|
||||
}),
|
||||
|
||||
new GameAction("I suppose", delegate { var e = eventCaller.currentEntity; FanClub.instance.CallKamone(e.beat, e.toggle, 0, e.type); }, 6, false, parameters: new List<Param>()
|
||||
new GameAction("yeah, yeah, yeah", delegate { var e = eventCaller.currentEntity; FanClub.instance.CallHai(e.beat, e.toggle); }, 8, false, parameters: new List<Param>()
|
||||
{
|
||||
new Param("toggle", false, "Disable call", "Disable the idol's call")
|
||||
},
|
||||
inactiveFunction: delegate { var e = eventCaller.currentEntity; FanClub.WarnHai(e.beat, e.toggle);}
|
||||
),
|
||||
|
||||
new GameAction("I suppose", delegate { var e = eventCaller.currentEntity; FanClub.instance.CallKamone(e.beat, e.toggle, 0, e.type); }, 6, false, parameters: new List<Param>()
|
||||
{
|
||||
new Param("type", FanClub.KamoneResponseType.Through, "Response type", "Type of response to use"),
|
||||
new Param("toggle", false, "Disable call", "Disable the idol's call")
|
||||
},
|
||||
inactiveFunction: delegate { var e = eventCaller.currentEntity; FanClub.WarnKamone(e.beat, e.toggle, 0, e.type);}
|
||||
),
|
||||
|
||||
new GameAction("double clap", delegate { var e = eventCaller.currentEntity; FanClub.instance.CallBigReady(e.beat, e.toggle); }, 4, false, parameters: new List<Param>()
|
||||
{
|
||||
new Param("toggle", false, "Disable call", "Disable the call")
|
||||
},
|
||||
inactiveFunction: delegate { var e = eventCaller.currentEntity; FanClub.WarnBigReady(e.beat, e.toggle); }
|
||||
),
|
||||
|
||||
new GameAction("play idol animation", delegate { var e = eventCaller.currentEntity; FanClub.instance.PlayAnim(e.beat, e.length, e.type); }, 1, true, parameters: new List<Param>()
|
||||
{
|
||||
new Param("type", FanClub.KamoneResponseType.Through, "Response type", "Type of response to use"),
|
||||
new Param("toggle", false, "Disable call", "Disable the idol's call")
|
||||
},
|
||||
inactiveFunction: delegate { var e = eventCaller.currentEntity; FanClub.WarnKamone(e.beat, e.toggle, 0, e.type);}
|
||||
),
|
||||
new Param("type", FanClub.IdolAnimations.Bop, "Animation", "Animation to play")
|
||||
}),
|
||||
|
||||
new GameAction("double clap", delegate { var e = eventCaller.currentEntity; FanClub.instance.CallBigReady(e.beat, e.toggle); }, 4, false, parameters: new List<Param>()
|
||||
new GameAction("play stage animation", delegate { var e = eventCaller.currentEntity; FanClub.instance.PlayAnimStage(e.beat, e.type); }, 1, true, parameters: new List<Param>()
|
||||
{
|
||||
new Param("toggle", false, "Disable call", "Disable the call")
|
||||
},
|
||||
inactiveFunction: delegate { var e = eventCaller.currentEntity; FanClub.WarnBigReady(e.beat, e.toggle); }
|
||||
),
|
||||
new Param("type", FanClub.StageAnimations.Flash, "Animation", "Animation to play")
|
||||
}),
|
||||
|
||||
new GameAction("play idol animation", delegate { var e = eventCaller.currentEntity; FanClub.instance.PlayAnim(e.beat, e.length, e.type); }, 1, true, parameters: new List<Param>()
|
||||
{
|
||||
new Param("type", FanClub.IdolAnimations.Bop, "Animation", "Animation to play")
|
||||
}),
|
||||
|
||||
new GameAction("play stage animation", delegate { var e = eventCaller.currentEntity; FanClub.instance.PlayAnimStage(e.beat, e.type); }, 1, true, parameters: new List<Param>()
|
||||
{
|
||||
new Param("type", FanClub.StageAnimations.Flash, "Animation", "Animation to play")
|
||||
}),
|
||||
|
||||
new GameAction("set performance type", delegate { var e = eventCaller.currentEntity; FanClub.SetPerformanceType(e.type);}, 0.5f, false, parameters: new List<Param>()
|
||||
{
|
||||
new Param("type", FanClub.IdolPerformanceType.Normal, "Performance Type", "Set of animations for the idol to use")
|
||||
},
|
||||
inactiveFunction: delegate { var e = eventCaller.currentEntity; FanClub.SetPerformanceType(e.type); }
|
||||
),
|
||||
});
|
||||
new GameAction("set performance type", delegate { var e = eventCaller.currentEntity; FanClub.SetPerformanceType(e.type);}, 0.5f, false, parameters: new List<Param>()
|
||||
{
|
||||
new Param("type", FanClub.IdolPerformanceType.Normal, "Performance Type", "Set of animations for the idol to use")
|
||||
},
|
||||
inactiveFunction: delegate { var e = eventCaller.currentEntity; FanClub.SetPerformanceType(e.type); }
|
||||
),
|
||||
},
|
||||
new List<string>() {"ntr", "normal"},
|
||||
"ntridol", "jp",
|
||||
new List<string>() {"jp"}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
8
Assets/Scripts/Games/LaunchParty.meta
Normal file
8
Assets/Scripts/Games/LaunchParty.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5566a9e256ded1e4f9c7a6a6d177da67
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -21,7 +21,6 @@ namespace HeavenStudio.Games
|
||||
public float createBeat;
|
||||
}
|
||||
|
||||
|
||||
public List<PlayerActionEvent> scheduledInputs = new List<PlayerActionEvent>();
|
||||
|
||||
/**
|
||||
|
@ -91,10 +91,10 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
|
||||
else
|
||||
{
|
||||
startThrowTime = Single.MinValue;
|
||||
Projectile.transform.localPosition = new Vector3(0, 0);
|
||||
Projectile.transform.rotation = Quaternion.Euler(0, 0, 0);
|
||||
if (hasThrown)
|
||||
{
|
||||
Projectile.transform.localPosition = new Vector3(0, 0);
|
||||
Projectile.transform.rotation = Quaternion.Euler(0, 0, 0);
|
||||
anim.DoUnscaledAnimation("MonkeyBeat");
|
||||
Projectile.SetActive(false);
|
||||
hasThrown = false;
|
||||
|
@ -114,12 +114,12 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
|
||||
}
|
||||
else
|
||||
{
|
||||
Projectile.GetComponent<Animator>().Play("NoPose", -1, 0);
|
||||
startThrowTime = Single.MinValue;
|
||||
Projectile_Root.transform.localPosition = new Vector3(0, 0);
|
||||
Projectile.transform.rotation = Quaternion.Euler(0, 0, 0);
|
||||
if (hasThrown)
|
||||
{
|
||||
Projectile.GetComponent<Animator>().Play("NoPose", -1, 0);
|
||||
Projectile.transform.rotation = Quaternion.Euler(0, 0, 0);
|
||||
if (throwNg)
|
||||
{
|
||||
anim.DoUnscaledAnimation("MakoCatchNg");
|
||||
@ -129,7 +129,7 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
|
||||
anim.DoUnscaledAnimation("MakoCatch");
|
||||
}
|
||||
//TODO: change when locales are a thing
|
||||
Jukebox.PlayOneShotGame("pajamaParty/jp/catch" + UnityEngine.Random.Range(0, 2)); //bruh
|
||||
Jukebox.PlayOneShotGame("pajamaParty/catch" + UnityEngine.Random.Range(0, 2)); //bruh
|
||||
|
||||
Projectile.SetActive(false);
|
||||
hasThrown = false;
|
||||
@ -197,7 +197,7 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
|
||||
beat + 0.5f,
|
||||
delegate {
|
||||
anim.DoScaledAnimationAsync("MakoPickUp");
|
||||
Jukebox.PlayOneShotGame("pajamaParty/jp/catch" + UnityEngine.Random.Range(0, 2)); //bruh
|
||||
Jukebox.PlayOneShotGame("pajamaParty/catch" + UnityEngine.Random.Range(0, 2)); //bruh
|
||||
Projectile.SetActive(false);
|
||||
canCharge = true;
|
||||
canJump = true;
|
||||
@ -273,7 +273,7 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
|
||||
public void ChargeJustOrNg(PlayerActionEvent caller, float state) {
|
||||
StartCharge();
|
||||
throwNg = (state <= -1f || state >= 1f);
|
||||
Jukebox.PlayOneShotGame("pajamaParty/jp/throw4");
|
||||
Jukebox.PlayOneShotGame("pajamaParty/throw4");
|
||||
}
|
||||
|
||||
public void ThrowJustOrNg(PlayerActionEvent caller, float state)
|
||||
@ -288,7 +288,7 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
|
||||
}
|
||||
else
|
||||
{
|
||||
Jukebox.PlayOneShotGame("pajamaParty/jp/throw5");
|
||||
Jukebox.PlayOneShotGame("pajamaParty/throw5");
|
||||
EndCharge(cond.songPositionInBeats, true, (throwNg || false));
|
||||
}
|
||||
caller.CanHit(false);
|
||||
|
@ -13,28 +13,32 @@ namespace HeavenStudio.Games.Loaders
|
||||
{
|
||||
public static Minigame AddGame(EventCaller eventCaller) {
|
||||
return new Minigame("pajamaParty", "Pajama Party", "965076", false, false, new List<GameAction>()
|
||||
{
|
||||
// both same timing
|
||||
new GameAction("jump (side to middle)", delegate {PajamaParty.instance.DoThreeJump(eventCaller.currentEntity.beat);}, 4f, false,
|
||||
inactiveFunction: delegate {PajamaParty.WarnThreeJump(eventCaller.currentEntity.beat);}
|
||||
),
|
||||
new GameAction("jump (back to front)", delegate {PajamaParty.instance.DoFiveJump(eventCaller.currentEntity.beat);}, 4f, false,
|
||||
inactiveFunction: delegate {PajamaParty.WarnFiveJump(eventCaller.currentEntity.beat);}
|
||||
{
|
||||
// both same timing
|
||||
new GameAction("jump (side to middle)", delegate {PajamaParty.instance.DoThreeJump(eventCaller.currentEntity.beat);}, 4f, false,
|
||||
inactiveFunction: delegate {PajamaParty.WarnThreeJump(eventCaller.currentEntity.beat);}
|
||||
),
|
||||
//idem
|
||||
new GameAction("slumber", delegate {var e = eventCaller.currentEntity; PajamaParty.instance.DoSleepSequence(e.beat, e.toggle);}, 8f, false, parameters: new List<Param>()
|
||||
{
|
||||
new Param("toggle", false, "Alt. Animation", "Use an alternate animation for Mako")
|
||||
},
|
||||
inactiveFunction: delegate {var e = eventCaller.currentEntity; PajamaParty.WarnSleepSequence(e.beat, e.toggle);}
|
||||
),
|
||||
new GameAction("throw", delegate {PajamaParty.instance.DoThrowSequence(eventCaller.currentEntity.beat);}, 8f, false,
|
||||
inactiveFunction: delegate {PajamaParty.WarnThrowSequence(eventCaller.currentEntity.beat);}
|
||||
),
|
||||
//cosmetic
|
||||
// new GameAction("open / close background", delegate { }, 2f, true),
|
||||
// do shit with mako's face? (talking?)
|
||||
});
|
||||
new GameAction("jump (back to front)", delegate {PajamaParty.instance.DoFiveJump(eventCaller.currentEntity.beat);}, 4f, false,
|
||||
inactiveFunction: delegate {PajamaParty.WarnFiveJump(eventCaller.currentEntity.beat);}
|
||||
),
|
||||
//idem
|
||||
new GameAction("slumber", delegate {var e = eventCaller.currentEntity; PajamaParty.instance.DoSleepSequence(e.beat, e.toggle);}, 8f, false, parameters: new List<Param>()
|
||||
{
|
||||
new Param("toggle", false, "Alt. Animation", "Use an alternate animation for Mako")
|
||||
},
|
||||
inactiveFunction: delegate {var e = eventCaller.currentEntity; PajamaParty.WarnSleepSequence(e.beat, e.toggle);}
|
||||
),
|
||||
new GameAction("throw", delegate {PajamaParty.instance.DoThrowSequence(eventCaller.currentEntity.beat);}, 8f, false,
|
||||
inactiveFunction: delegate {PajamaParty.WarnThrowSequence(eventCaller.currentEntity.beat);}
|
||||
),
|
||||
//cosmetic
|
||||
// new GameAction("open / close background", delegate { }, 2f, true),
|
||||
// do shit with mako's face? (talking?)
|
||||
},
|
||||
new List<string>() {"ctr", "normal"},
|
||||
"ctrpillow", "jp",
|
||||
new List<string>() {"en", "jp", "ko"}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -233,8 +237,10 @@ namespace HeavenStudio.Games
|
||||
new MultiSound.Sound("pajamaParty/throw1", beat),
|
||||
new MultiSound.Sound("pajamaParty/throw2", beat + 0.5f),
|
||||
new MultiSound.Sound("pajamaParty/throw3", beat + 1f),
|
||||
|
||||
//TODO: change when locales are a thing
|
||||
//new MultiSound.Sound("pajamaParty/en/throw4a", beat + 1.5f), //will only play if this clip exists (aka just en)
|
||||
new MultiSound.Sound("pajamaParty/throw4a", beat + 1.5f),
|
||||
|
||||
new MultiSound.Sound("pajamaParty/charge", beat + 2f),
|
||||
}, forcePlay: force);
|
||||
}
|
||||
|
@ -23,7 +23,11 @@ namespace HeavenStudio.Games.Loaders
|
||||
new Param("valA", new EntityTypes.Integer(0, 30, 1), "Money", "The amount of coins the object spills out when sliced"),
|
||||
}),
|
||||
//new GameAction("start bopping", delegate { SamuraiSliceNtr.instance.Bop(eventCaller.currentEntity.beat, eventCaller.currentEntity.length); }, 1),
|
||||
});
|
||||
},
|
||||
new List<string>() {"ntr", "normal"},
|
||||
"ntrsamurai", "en",
|
||||
new List<string>() {"en"}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using UnityEngine;
|
||||
using DG.Tweening;
|
||||
|
||||
@ -10,6 +11,7 @@ using HeavenStudio.Games;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
|
||||
namespace HeavenStudio
|
||||
{
|
||||
@ -26,7 +28,24 @@ namespace HeavenStudio
|
||||
public bool fxOnly;
|
||||
public List<GameAction> actions = new List<GameAction>();
|
||||
|
||||
public Minigame(string name, string displayName, string color, bool threeD, bool fxOnly, List<GameAction> actions)
|
||||
public List<string> tags;
|
||||
public string defaultLocale = "en";
|
||||
public string wantAssetBundle = "";
|
||||
public List<string> supportedLocales;
|
||||
|
||||
public bool usesAssetBundle => (wantAssetBundle != "");
|
||||
public bool hasLocales => (supportedLocales.Count > 0);
|
||||
public bool AssetsLoaded => (((hasLocales && localeLoaded && currentLoadedLocale == defaultLocale) || (!hasLocales)) && commonLoaded);
|
||||
|
||||
private AssetBundle bundleCommon = null;
|
||||
private bool commonLoaded = false;
|
||||
private bool commonPreloaded = false;
|
||||
private string currentLoadedLocale = "";
|
||||
private AssetBundle bundleLocalized = null;
|
||||
private bool localeLoaded = false;
|
||||
private bool localePreloaded = false;
|
||||
|
||||
public Minigame(string name, string displayName, string color, bool threeD, bool fxOnly, List<GameAction> actions, List<string> tags = null, string assetBundle = "", string defaultLocale = "en", List<string> supportedLocales = null)
|
||||
{
|
||||
this.name = name;
|
||||
this.displayName = displayName;
|
||||
@ -34,6 +53,83 @@ namespace HeavenStudio
|
||||
this.actions = actions;
|
||||
this.threeD = threeD;
|
||||
this.fxOnly = fxOnly;
|
||||
|
||||
this.tags = tags ?? new List<string>();
|
||||
this.wantAssetBundle = assetBundle;
|
||||
this.defaultLocale = defaultLocale;
|
||||
this.supportedLocales = supportedLocales ?? new List<string>();
|
||||
}
|
||||
|
||||
public AssetBundle GetLocalizedAssetBundle()
|
||||
{
|
||||
if (!hasLocales) return null;
|
||||
if (!usesAssetBundle) return null;
|
||||
if (bundleLocalized == null || currentLoadedLocale != defaultLocale) //TEMPORARY: use the game's default locale until we add localization support
|
||||
{
|
||||
if (localeLoaded) return bundleLocalized;
|
||||
// TODO: try/catch for missing assetbundles
|
||||
currentLoadedLocale = defaultLocale;
|
||||
bundleLocalized = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, wantAssetBundle + "/locale." + defaultLocale));
|
||||
localeLoaded = true;
|
||||
}
|
||||
return bundleLocalized;
|
||||
}
|
||||
|
||||
public AssetBundle GetCommonAssetBundle()
|
||||
{
|
||||
if (commonLoaded) return bundleCommon;
|
||||
if (!usesAssetBundle) return null;
|
||||
if (bundleCommon == null)
|
||||
{
|
||||
// TODO: try/catch for missing assetbundles
|
||||
bundleCommon = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, wantAssetBundle + "/common"));
|
||||
commonLoaded = true;
|
||||
}
|
||||
return bundleCommon;
|
||||
}
|
||||
|
||||
public IEnumerator LoadCommonAssetBundleAsync()
|
||||
{
|
||||
if (commonPreloaded || commonLoaded) yield break;
|
||||
commonPreloaded = true;
|
||||
if (!usesAssetBundle) yield break;
|
||||
if (bundleCommon != null) yield break;
|
||||
|
||||
AssetBundleCreateRequest asyncBundleRequest = AssetBundle.LoadFromFileAsync(Path.Combine(Application.streamingAssetsPath, wantAssetBundle + "/common"));
|
||||
if (bundleCommon != null) yield break;
|
||||
yield return asyncBundleRequest;
|
||||
|
||||
AssetBundle localAssetBundle = asyncBundleRequest.assetBundle;
|
||||
if (bundleCommon != null) yield break;
|
||||
yield return localAssetBundle;
|
||||
|
||||
if (localAssetBundle == null) yield break;
|
||||
|
||||
bundleCommon = localAssetBundle;
|
||||
commonLoaded = true;
|
||||
}
|
||||
|
||||
public IEnumerator LoadLocalizedAssetBundleAsync()
|
||||
{
|
||||
if (localePreloaded) yield break;
|
||||
localePreloaded = true;
|
||||
if (!hasLocales) yield break;
|
||||
if (!usesAssetBundle) yield break;
|
||||
if (localeLoaded && bundleLocalized != null && currentLoadedLocale == defaultLocale) yield break;
|
||||
|
||||
AssetBundleCreateRequest asyncBundleRequest = AssetBundle.LoadFromFileAsync(Path.Combine(Application.streamingAssetsPath, wantAssetBundle + "/locale." + defaultLocale));
|
||||
if (localeLoaded && bundleLocalized != null && currentLoadedLocale == defaultLocale) yield break;
|
||||
yield return asyncBundleRequest;
|
||||
|
||||
AssetBundle localAssetBundle = asyncBundleRequest.assetBundle;
|
||||
if (localeLoaded && bundleLocalized != null && currentLoadedLocale == defaultLocale) yield break;
|
||||
yield return localAssetBundle;
|
||||
|
||||
if (localAssetBundle == null) yield break;
|
||||
|
||||
bundleLocalized = localAssetBundle;
|
||||
currentLoadedLocale = defaultLocale;
|
||||
localeLoaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ namespace HeavenStudio.Util
|
||||
FindJukebox().GetComponent<AudioSource>().volume = volume;
|
||||
}
|
||||
|
||||
public static Sound PlayOneShot(string name, float beat = -1, float pitch = 1f, float volume = 1f, bool looping = false)
|
||||
public static Sound PlayOneShot(string name, float beat = -1, float pitch = 1f, float volume = 1f, bool looping = false, string game = null)
|
||||
{
|
||||
GameObject oneShot = new GameObject("oneShot");
|
||||
|
||||
@ -49,7 +49,29 @@ namespace HeavenStudio.Util
|
||||
audioSource.playOnAwake = false;
|
||||
|
||||
Sound snd = oneShot.AddComponent<Sound>();
|
||||
AudioClip clip = Resources.Load<AudioClip>($"Sfx/{name}");
|
||||
AudioClip clip = null;
|
||||
if (game != null)
|
||||
{
|
||||
string soundName = name.Split('/')[2];
|
||||
var inf = GameManager.instance.GetGameInfo(game);
|
||||
//first try the game's common assetbundle
|
||||
// Debug.Log("Jukebox loading sound " + soundName + " from common");
|
||||
clip = inf.GetCommonAssetBundle()?.LoadAsset<AudioClip>(soundName);
|
||||
//then the localized one
|
||||
if (clip == null)
|
||||
{
|
||||
// Debug.Log("Jukebox loading sound " + soundName + " from locale");
|
||||
clip = inf.GetLocalizedAssetBundle()?.LoadAsset<AudioClip>(soundName);
|
||||
}
|
||||
}
|
||||
|
||||
//can't load from assetbundle, load from resources
|
||||
if (clip == null)
|
||||
{
|
||||
// Debug.Log("Jukebox loading sound " + name + " from resources");
|
||||
clip = Resources.Load<AudioClip>($"Sfx/{name}");
|
||||
}
|
||||
|
||||
snd.clip = clip;
|
||||
snd.beat = beat;
|
||||
snd.pitch = pitch;
|
||||
@ -62,7 +84,7 @@ namespace HeavenStudio.Util
|
||||
return snd;
|
||||
}
|
||||
|
||||
public static Sound PlayOneShotScheduled(string name, double targetTime, float pitch = 1f, float volume = 1f, bool looping = false)
|
||||
public static Sound PlayOneShotScheduled(string name, double targetTime, float pitch = 1f, float volume = 1f, bool looping = false, string game = null)
|
||||
{
|
||||
GameObject oneShot = new GameObject("oneShotScheduled");
|
||||
|
||||
@ -70,8 +92,26 @@ namespace HeavenStudio.Util
|
||||
audioSource.playOnAwake = false;
|
||||
|
||||
var snd = oneShot.AddComponent<Sound>();
|
||||
AudioClip clip = null;
|
||||
if (game != null)
|
||||
{
|
||||
string soundName = name.Split('/')[2];
|
||||
var inf = GameManager.instance.GetGameInfo(game);
|
||||
//first try the game's common assetbundle
|
||||
// Debug.Log("Jukebox loading sound " + soundName + " from common");
|
||||
clip = inf.GetCommonAssetBundle()?.LoadAsset<AudioClip>(soundName);
|
||||
//then the localized one
|
||||
if (clip == null)
|
||||
{
|
||||
// Debug.Log("Jukebox loading sound " + soundName + " from locale");
|
||||
clip = inf.GetLocalizedAssetBundle()?.LoadAsset<AudioClip>(soundName);
|
||||
}
|
||||
}
|
||||
|
||||
//can't load from assetbundle, load from resources
|
||||
if (clip == null)
|
||||
clip = Resources.Load<AudioClip>($"Sfx/{name}");
|
||||
|
||||
var clip = Resources.Load<AudioClip>($"Sfx/{name}");
|
||||
audioSource.clip = clip;
|
||||
snd.clip = clip;
|
||||
snd.pitch = pitch;
|
||||
@ -89,9 +129,11 @@ namespace HeavenStudio.Util
|
||||
|
||||
public static Sound PlayOneShotGame(string name, float beat = -1, float pitch = 1f, float volume = 1f, bool looping = false, bool forcePlay = false)
|
||||
{
|
||||
if (GameManager.instance.currentGame == name.Split('/')[0] || forcePlay)
|
||||
string gameName = name.Split('/')[0];
|
||||
var inf = GameManager.instance.GetGameInfo(gameName);
|
||||
if (GameManager.instance.currentGame == gameName || forcePlay)
|
||||
{
|
||||
return PlayOneShot($"games/{name}", beat, pitch, volume, looping);
|
||||
return PlayOneShot($"games/{name}", beat, pitch, volume, looping, inf.usesAssetBundle ? gameName : null);
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -99,14 +141,18 @@ namespace HeavenStudio.Util
|
||||
|
||||
public static Sound PlayOneShotScheduledGame(string name, double targetTime, float pitch = 1f, float volume = 1f, bool looping = false, bool forcePlay = false)
|
||||
{
|
||||
if (GameManager.instance.currentGame == name.Split('/')[0] || forcePlay)
|
||||
string gameName = name.Split('/')[0];
|
||||
var inf = GameManager.instance.GetGameInfo(gameName);
|
||||
if (GameManager.instance.currentGame == gameName || forcePlay)
|
||||
{
|
||||
return PlayOneShotScheduled($"games/{name}", targetTime, pitch, volume, looping);
|
||||
return PlayOneShotScheduled($"games/{name}", targetTime, pitch, volume, looping, inf.usesAssetBundle ? gameName : null);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
//TODO: playing sounds from assetbundles
|
||||
|
||||
public static void KillLoop(Sound source, float fadeTime)
|
||||
{
|
||||
// Safeguard against previously-destroyed sounds.
|
||||
|
Reference in New Issue
Block a user