fix: introduced assetbundles, instead of reading from folder

Reading Assets from folders was only possible in Editor over  LoadAssetFromPath. Now I'm using asset bundles for ScriptedObjects and Audio Prefabs, when the project is built.
When in Editor the folders are still used for convenience (can make changes to assets without rebuilding asset bundles)
This commit is contained in:
Jakob Feldmann 2024-04-18 20:23:17 +02:00
parent 3dbcb69b7f
commit 6d89d9d48e
17 changed files with 184 additions and 68 deletions

3
.gitignore vendored
View File

@ -67,6 +67,9 @@ crashlytics-build.properties
# Packed Addressables
/[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin*
# Temporary auto-generated Assets
/[Aa]ssets/[Ss]treamingAssets/*
# Temporary auto-generated Android Assets
/[Aa]ssets/[Ss]treamingAssets/aa.meta
/[Aa]ssets/[Ss]treamingAssets/aa/*

View File

@ -0,0 +1,18 @@
using UnityEditor;
using System.IO;
public class CreateAssetBundles
{
[MenuItem("Assets/Build AssetBundles")]
static void BuildAllAssetBundles()
{
string assetBundleDirectory = "Assets/StreamingAssets";
if (!Directory.Exists(assetBundleDirectory))
{
Directory.CreateDirectory(assetBundleDirectory);
}
BuildPipeline.BuildAssetBundles(assetBundleDirectory,
BuildAssetBundleOptions.None,
BuildTarget.StandaloneWindows);
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 470f9a7d05d183e4aac0b2759ec5dbda
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -9,6 +9,7 @@ public class AudioLibrary : MonoBehaviour
{
private static ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public List<GameObject> audios;
public string audioAssetsBundleName = "audio";
public string manageableAudioFolder = "Assets/Prefabs/Audio";
public void Awake()
@ -17,10 +18,13 @@ public class AudioLibrary : MonoBehaviour
}
/// <summary>
/// Loads all the ManageableAudio prefabs from the specified folder.
/// Loads all ManageableAudioPrefabs from an asset bundle if built or
/// from the assets folder when in editor.
/// TODO: DO NOT FORGET TO manually BUILD ASSET BUNDLES WHEN BUILDING
/// </summary>
private void LoadAvailableSounds()
{
#if UNITY_EDITOR
string[] files = Directory.GetFiles(manageableAudioFolder, "*.prefab",
SearchOption.TopDirectoryOnly);
List<GameObject> gos = new List<GameObject>();
@ -39,6 +43,28 @@ public class AudioLibrary : MonoBehaviour
Log.Warn("Audio library can only load prefabs with ManageableAudio components!");
}
}
#else
var audioAssetBundle = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, audioAssetsBundleName));
if (audioAssetBundle == null)
{
Log.Error("Failed to load arenas asset bundle!");
return;
}
List<GameObject> gos = new List<GameObject>();
gos.AddRange(audioAssetBundle.LoadAllAssets<GameObject>());
foreach (GameObject go in gos)
{
if (go.TryGetComponent<ManageableAudio>(out _))
{
audios.Add(go);
}
else
{
Log.Warn("Audio library can only load prefabs with ManageableAudio components!");
}
}
#endif
}
}

View File

@ -14,6 +14,10 @@ namespace ShipHandling
private readonly string controlScheme;
private readonly InputDevice device;
public InputUser user;
public ShipInputHandler()
{
}
public ShipInputHandler(ShipState shipState, InputDevice device, string controlScheme)
{
state = shipState;

View File

@ -3,8 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using log4net;
using UnityEditor;
using UnityEditor.PackageManager;
using UnityEngine;
namespace Managers

View File

@ -14,14 +14,15 @@ namespace Managers
/// </summary>
public class CharacterManager : MonoBehaviour
{
private static ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Globally accessible member to use manager with.
/// </summary>
public static CharacterManager G { get; private set; }
public List<ShipProperties> availableShips { get; private set; } = new List<ShipProperties>();
private static string characterAssetsPath = "Assets/ScriptedAssets/Characters";
public List<ShipProperties> AvailableShips { get; private set; } = new List<ShipProperties>();
private static readonly string characterAssetsBundleName = "characters";
private static readonly string characterAssetsPath = "Assets/ScriptedAssets/Characters";
void Awake()
{
@ -40,12 +41,22 @@ namespace Managers
/// </summary>
private void LoadAvailableCharacters()
{
#if UNITY_EDITOR
string[] files = Directory.GetFiles(characterAssetsPath, "*.asset",
SearchOption.TopDirectoryOnly);
foreach (var file in files)
{
availableShips.Add(AssetDatabase.LoadAssetAtPath<ShipProperties>(file));
AvailableShips.Add(AssetDatabase.LoadAssetAtPath<ShipProperties>(file));
}
#else
var characterAssetBundle = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, characterAssetsBundleName));
if (characterAssetBundle == null)
{
Log.Error("Failed to load rules asset bundle!");
return;
}
AvailableShips.AddRange(characterAssetBundle.LoadAllAssets<ShipProperties>());
#endif
}
/// <summary>

View File

@ -55,6 +55,8 @@ namespace Managers
{
private static ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly string arenaAssetsBundleName = "arenas";
private static readonly string ruleAssetsBundleName = "rules";
private static readonly string arenaAssetsPath = "Assets/ScriptedAssets/Arenas";
private static readonly string ruleAssetsPath = "Assets/ScriptedAssets/Rules";
private GameResult CurrentMatchResult;
@ -72,11 +74,6 @@ namespace Managers
/// </summary>
public MatchState matchState = MatchState.CharacterSelect;
/// <summary>
/// The players participating in the match.
/// </summary>
public List<Player> MatchPlayers { get; private set; } =
new List<Player>();
/// <summary>
/// The statistics regarding the current match mapped to the players.
/// </summary>
public Dictionary<Player, MatchPlayerStatistic> MatchPlayerStatistics { get; set; } =
@ -111,6 +108,55 @@ namespace Managers
LoadAvailableArenas();
}
/// <summary>
/// Loads the different rules/game modes which are available,
/// at the fixed asset path.
/// </summary>
private void LoadAvailableRules()
{
#if UNITY_EDITOR
string[] files = Directory.GetFiles(arenaAssetsPath, "*.asset",
SearchOption.TopDirectoryOnly);
foreach (var file in files)
{
AvailableArenas.Add(AssetDatabase.LoadAssetAtPath<Arena>(file));
}
#else
var ruleAssetBundle = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, ruleAssetsBundleName));
if (ruleAssetBundle == null)
{
Log.Error("Failed to load rules asset bundle!");
return;
}
AvailableRules.AddRange(ruleAssetBundle.LoadAllAssets<MatchRule>());
#endif
}
/// <summary>
/// Loads the characters a player can choose from a fixed path
/// in the project.
/// </summary>
private void LoadAvailableArenas()
{
#if UNITY_EDITOR
string[] files = Directory.GetFiles(ruleAssetsPath, "*.asset",
SearchOption.TopDirectoryOnly);
foreach (var file in files)
{
AvailableRules.Add(AssetDatabase.LoadAssetAtPath<MatchRule>(file));
}
#else
var arenasAssetBundle = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, arenaAssetsBundleName));
if (arenasAssetBundle == null)
{
Log.Error("Failed to load arenas asset bundle!");
return;
}
AvailableArenas.AddRange(arenasAssetBundle.LoadAllAssets<Arena>());
#endif
}
/// <summary>
/// Update and check the match conditions in regards to the rules.
/// </summary>
@ -118,7 +164,7 @@ namespace Managers
public void UpdateMatchCondition(MatchConditionUpdate update)
{
Player updatedPlayer = null;
foreach (Player p in MatchPlayers)
foreach (Player p in PlayerManager.G.MatchPlayers)
{
if (p.character.shipName == update.Ship.props.shipName)
{
@ -146,38 +192,11 @@ namespace Managers
else
{
Log.Info($"Round {CurrentMatchResult.RoundsPlayed} of {MatchRule.rounds} has ended." +
$"{CurrentMatchResult.Winner.name} won this round.");
$"{CurrentMatchResult.Winner?.name} won this round.");
AnnounceRoundWinner(CurrentMatchResult);
}
}
/// <summary>
/// Loads the characters a player can choose from a fixed path
/// in the project.
/// </summary>
private void LoadAvailableArenas()
{
string[] files = Directory.GetFiles(arenaAssetsPath, "*.asset",
SearchOption.TopDirectoryOnly);
foreach (var file in files)
{
AvailableArenas.Add(AssetDatabase.LoadAssetAtPath<Arena>(file));
}
}
/// <summary>
/// Loads the different rules/game modes which are available,
/// at the fixed asset path.
/// </summary>
private void LoadAvailableRules()
{
string[] files = Directory.GetFiles(ruleAssetsPath, "*.asset",
SearchOption.TopDirectoryOnly);
foreach (var file in files)
{
AvailableRules.Add(AssetDatabase.LoadAssetAtPath<MatchRule>(file));
}
}
/// <summary>
/// Creates statistics for the players participating in the match.

View File

@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using UnityEditor;
namespace GameLogic
{
@ -71,11 +69,7 @@ namespace GameLogic
public int RoundsPlayed { get; private set; }
public Player Winner { get; private set; }
public List<Player> Opponents { get; private set; }
public GUID GameID { get; private set; }
public GameResult()
{
GameID = GUID.Generate();
}
/// <summary>
/// Checks whether a round is won and if that round decided the match.
/// Sets the class properties accordingly.
@ -85,6 +79,7 @@ namespace GameLogic
public void UpdateGameResult(Dictionary<Player, MatchPlayerStatistic> mps, MatchRule rules)
{
int outPlayers = mps.Count(p => p.Value.IsOut);
// TODO: blatant error here right now
if (outPlayers == mps.Count - 1)
{
Winner = mps.First(p => p.Value.IsOut != true).Key;

View File

@ -1,6 +1,3 @@
using System.Collections;
using System.Collections.Generic;
using UnityEditor.EditorTools;
using UnityEngine;
/// <summary>

View File

@ -1,4 +1,3 @@
using UnityEditor;
using UnityEngine;
/// <summary>
@ -7,14 +6,8 @@ using UnityEngine;
/// </summary>
public class Player : ScriptableObject
{
public GUID PlayerID { get; private set; }
public int playerNumber;
public string playerName = "default";
public ShipProperties character;
public GameObject spawnedCharacter;
void Awake()
{
PlayerID = GUID.Generate();
}
}

View File

@ -1,8 +1,4 @@
using System.Collections;
using System.Collections.Generic;
using ShipHandling;
using Unity.VisualScripting;
using UnityEditor.EditorTools;
using UnityEngine;
/// <summary>

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8f4b678f0cb4496499a8529a1f14138b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -11,6 +11,7 @@
"com.unity.render-pipelines.universal": "14.0.10",
"com.unity.textmeshpro": "3.0.8",
"com.unity.timeline": "1.7.6",
"com.unity.toolchain.win-x86_64-linux-x86_64": "2.0.6",
"com.unity.ugui": "1.0.0",
"com.unity.visualscripting": "1.9.2",
"com.unity.modules.ai": "1.0.0",

View File

@ -190,6 +190,22 @@
"com.unity.searcher": "4.9.2"
}
},
"com.unity.sysroot": {
"version": "2.0.7",
"depth": 1,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.sysroot.linux-x86_64": {
"version": "2.0.6",
"depth": 1,
"source": "registry",
"dependencies": {
"com.unity.sysroot": "2.0.7"
},
"url": "https://packages.unity.com"
},
"com.unity.test-framework": {
"version": "1.1.33",
"depth": 1,
@ -232,6 +248,16 @@
},
"url": "https://packages.unity.com"
},
"com.unity.toolchain.win-x86_64-linux-x86_64": {
"version": "2.0.6",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.sysroot": "2.0.7",
"com.unity.sysroot.linux-x86_64": "2.0.6"
},
"url": "https://packages.unity.com"
},
"com.unity.ugui": {
"version": "1.0.0",
"depth": 0,

View File

@ -19,7 +19,7 @@ PhysicsManager:
m_ClothInterCollisionStiffness: 0
m_ContactsGeneration: 1
m_LayerCollisionMatrix: ffffffffffffffffffffffff4fffffffd7ffffffe7fffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
m_SimulationMode: 0
m_SimulationMode: 2
m_AutoSyncTransforms: 0
m_ReuseCollisionCallbacks: 1
m_InvokeCollisionCallbacks: 1
@ -37,3 +37,4 @@ PhysicsManager:
m_ImprovedPatchFriction: 0
m_SolverType: 0
m_DefaultMaxAngularSpeed: 7
m_FastMotionThreshold: 3.4028235e+38

View File

@ -48,6 +48,7 @@ PlayerSettings:
defaultScreenHeightWeb: 600
m_StereoRenderingPath: 0
m_ActiveColorSpace: 1
unsupportedMSAAFallback: 0
m_SpriteBatchVertexThreshold: 300
m_MTRendering: 1
mipStripping: 0
@ -75,6 +76,7 @@ PlayerSettings:
androidMinimumWindowWidth: 400
androidMinimumWindowHeight: 300
androidFullscreenMode: 1
androidAutoRotationBehavior: 1
defaultIsNativeResolution: 1
macRetinaSupport: 1
runInBackground: 1
@ -86,6 +88,7 @@ PlayerSettings:
hideHomeButton: 0
submitAnalytics: 1
usePlayerLog: 1
dedicatedServerOptimizations: 0
bakeCollisionMeshes: 0
forceSingleInstance: 0
useFlipModelSwapchain: 1
@ -100,7 +103,7 @@ PlayerSettings:
xboxEnableFitness: 0
visibleInBackground: 1
allowFullscreenSwitch: 1
fullscreenMode: 1
fullscreenMode: 3
xboxSpeechDB: 0
xboxEnableHeadOrientation: 0
xboxEnableGuest: 0
@ -125,6 +128,7 @@ PlayerSettings:
switchNVNMaxPublicTextureIDCount: 0
switchNVNMaxPublicSamplerIDCount: 0
switchNVNGraphicsFirmwareMemory: 32
switchMaxWorkerMultiple: 8
stadiaPresentMode: 0
stadiaTargetFramerate: 0
vulkanNumSwapchainBuffers: 3
@ -133,8 +137,12 @@ PlayerSettings:
vulkanEnableLateAcquireNextImage: 0
vulkanEnableCommandBufferRecycling: 1
loadStoreDebugModeEnabled: 0
visionOSBundleVersion: 1.0
tvOSBundleVersion: 1.0
bundleVersion: 0.1
preloadedAssets: []
preloadedAssets:
- {fileID: -4938997134116425971, guid: 4b98f800e99c70140ac675a637d71d3a, type: 2}
- {fileID: 11400000, guid: 7d6dd64b5f2213d4f8cc395ae58ffb43, type: 2}
metroInputSource: 0
wsaTransparentSwapchain: 0
m_HolographicPauseOnTrackingLoss: 1
@ -145,6 +153,7 @@ PlayerSettings:
isWsaHolographicRemotingEnabled: 0
enableFrameTimingStats: 1
enableOpenGLProfilerGPURecorders: 1
allowHDRDisplaySupport: 0
useHDRDisplay: 0
hdrBitDepth: 0
m_ColorGamuts: 00000000
@ -399,7 +408,7 @@ PlayerSettings:
switchSocketConcurrencyLimit: 14
switchScreenResolutionBehavior: 2
switchUseCPUProfiler: 0
switchUseGOLDLinker: 0
switchEnableFileSystemTrace: 0
switchLTOSetting: 0
switchApplicationID: 0x01004b9000490000
switchNSODependencies:
@ -529,7 +538,6 @@ PlayerSettings:
switchSocketBufferEfficiency: 4
switchSocketInitializeEnabled: 1
switchNetworkInterfaceManagerInitializeEnabled: 1
switchPlayerConnectionEnabled: 1
switchUseNewStyleFilepaths: 1
switchUseLegacyFmodPriorities: 0
switchUseMicroSleepForYield: 1
@ -648,7 +656,7 @@ PlayerSettings:
PS5: UNITY_POST_PROCESSING_STACK_V2
QNX: UNITY_POST_PROCESSING_STACK_V2
Stadia: UNITY_POST_PROCESSING_STACK_V2
Standalone: UNITY_POST_PROCESSING_STACK_V2
Standalone: UNITY_POST_PROCESSING_STACK_V2;FISHNET;FISHNET_V4
VisionOS: UNITY_POST_PROCESSING_STACK_V2
WebGL: UNITY_POST_PROCESSING_STACK_V2
XboxOne: UNITY_POST_PROCESSING_STACK_V2
@ -705,6 +713,7 @@ PlayerSettings:
metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0}
metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, a: 1}
metroSplashScreenUseBackgroundColor: 0
syncCapabilities: 0
platformCapabilities: {}
metroTargetDeviceFamilies: {}
metroFTAName: