initial commit
This commit is contained in:
parent
6715289efe
commit
788c3389af
37645 changed files with 2526849 additions and 80 deletions
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8f396561f7e3d884b88624fb49efcc3b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"displayName": "Addressables Utility",
|
||||
"description": "This sample contains a set of utility functions for Addressables."
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
using UnityEngine.AddressableAssets;
|
||||
|
||||
/// <summary>
|
||||
/// A utility class for various Addressables functionality
|
||||
/// </summary>
|
||||
public static class AddressablesUtility
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the address of a given AssetReference.
|
||||
/// </summary>
|
||||
/// <param name="reference">The AssetReference you want to find the address of.</param>
|
||||
/// <returns>The address of a given AssetReference.</returns>
|
||||
public static string GetAddressFromAssetReference(AssetReference reference)
|
||||
{
|
||||
var loadResourceLocations = Addressables.LoadResourceLocationsAsync(reference);
|
||||
var result = loadResourceLocations.WaitForCompletion();
|
||||
if (result.Count > 0)
|
||||
{
|
||||
string key = result[0].PrimaryKey;
|
||||
Addressables.Release(loadResourceLocations);
|
||||
return key;
|
||||
}
|
||||
|
||||
Addressables.Release(loadResourceLocations);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7d2d37c2cf13be949b2fa25b2df83880
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4051cd5a483c84040a502ec9d89f652a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"displayName": "ComponentReference",
|
||||
"description": "This sample creates an AssetReference that is restricted to having a specific Component. See the ComponentReference sample project located at github.com/Unity-Technologies/Addressables-Sample"
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Creates an AssetReference that is restricted to having a specific Component.
|
||||
/// * This is the class that inherits from AssetReference. It is generic and does not specify which Components it might care about. A concrete child of this class is required for serialization to work.
|
||||
/// * At edit-time it validates that the asset set on it is a GameObject with the required Component.
|
||||
/// * At runtime it can load/instantiate the GameObject, then return the desired component. API matches base class (LoadAssetAsync & InstantiateAsync).
|
||||
/// </summary>
|
||||
/// <typeparam name="TComponent">The component type.</typeparam>
|
||||
public class ComponentReference<TComponent> : AssetReference
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public ComponentReference(string guid) : base(guid)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public new AsyncOperationHandle<TComponent> InstantiateAsync(Vector3 position, Quaternion rotation, Transform parent = null)
|
||||
{
|
||||
return Addressables.ResourceManager.CreateChainOperation<TComponent, GameObject>(base.InstantiateAsync(position, Quaternion.identity, parent), GameObjectReady);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public new AsyncOperationHandle<TComponent> InstantiateAsync(Transform parent = null, bool instantiateInWorldSpace = false)
|
||||
{
|
||||
return Addressables.ResourceManager.CreateChainOperation<TComponent, GameObject>(base.InstantiateAsync(parent, instantiateInWorldSpace), GameObjectReady);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public AsyncOperationHandle<TComponent> LoadAssetAsync()
|
||||
{
|
||||
return Addressables.ResourceManager.CreateChainOperation<TComponent, GameObject>(base.LoadAssetAsync<GameObject>(), GameObjectReady);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
AsyncOperationHandle<TComponent> GameObjectReady(AsyncOperationHandle<GameObject> arg)
|
||||
{
|
||||
var comp = arg.Result.GetComponent<TComponent>();
|
||||
return Addressables.ResourceManager.CreateCompletedOperation<TComponent>(comp, string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates that the assigned asset has the component type
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
/// <returns></returns>
|
||||
public override bool ValidateAsset(Object obj)
|
||||
{
|
||||
var go = obj as GameObject;
|
||||
return go != null && go.GetComponent<TComponent>() != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates that the assigned asset has the component type, but only in the Editor
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
public override bool ValidateAsset(string path)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
//this load can be expensive...
|
||||
var go = AssetDatabase.LoadAssetAtPath<GameObject>(path);
|
||||
return go != null && go.GetComponent<TComponent>() != null;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ReleaseInstance(AsyncOperationHandle<TComponent> op)
|
||||
{
|
||||
// Release the instance
|
||||
var component = op.Result as Component;
|
||||
if (component != null)
|
||||
{
|
||||
Addressables.ReleaseInstance(component.gameObject);
|
||||
}
|
||||
|
||||
// Release the handle
|
||||
Addressables.Release(op);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: bbc7bb869f290d74da99320c3bd575c6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 30c0b4f2538b84541b866788961d4237
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"displayName": "Custom Analyze Rules",
|
||||
"description": "This sample shows how to create custom AnalyzeRules for use within the Analyze window. Both rules follow the recommended pattern for adding themselves to the UI. See the Custom Analyze Rules sample project located at github.com/Unity-Technologies/Addressables-Sample"
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6796f792860ff7d4c999d47a82b39295
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
#if UNITY_EDITOR
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEditor.AddressableAssets.Build;
|
||||
using UnityEditor.AddressableAssets.GUI;
|
||||
using UnityEditor.AddressableAssets.Settings;
|
||||
using UnityEditor.AddressableAssets.Settings.GroupSchemas;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// * This is a non-fixable rule (meaning it will not fix itself).
|
||||
/// * When run, it checks that all addresses have a capital C in them. Any that do not are flagged as errors.
|
||||
/// * A rule like this would be useful if your studio enforced some sort of naming convention on addresses. (though it would probably be best if it could fix itself)
|
||||
/// </summary>
|
||||
public class AddressHasC : UnityEditor.AddressableAssets.Build.AnalyzeRules.AnalyzeRule
|
||||
{
|
||||
public override bool CanFix
|
||||
{
|
||||
get { return false; }
|
||||
set { }
|
||||
}
|
||||
|
||||
public override string ruleName
|
||||
{
|
||||
get { return "Ensure all addresses have a 'C'"; }
|
||||
}
|
||||
|
||||
public override List<AnalyzeResult> RefreshAnalysis(AddressableAssetSettings settings)
|
||||
{
|
||||
List<AnalyzeResult> results = new List<AnalyzeResult>();
|
||||
foreach (var group in settings.groups)
|
||||
{
|
||||
if (group.HasSchema<PlayerDataGroupSchema>())
|
||||
continue;
|
||||
|
||||
foreach (var e in group.entries)
|
||||
{
|
||||
if (!e.address.Contains("C"))
|
||||
results.Add(new AnalyzeResult {resultName = group.Name + kDelimiter + e.address, severity = MessageType.Error});
|
||||
}
|
||||
}
|
||||
|
||||
if (results.Count == 0)
|
||||
results.Add(new AnalyzeResult {resultName = ruleName + " - No issues found."});
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[InitializeOnLoad]
|
||||
class RegisterAddressHasC
|
||||
{
|
||||
static RegisterAddressHasC()
|
||||
{
|
||||
AnalyzeSystem.RegisterNewRule<AddressHasC>();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e7f8f48de5f3e9341b19f0a6844c2e48
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
#if UNITY_EDITOR
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEditor.AddressableAssets.Build;
|
||||
using UnityEditor.AddressableAssets.Build.AnalyzeRules;
|
||||
using UnityEditor.AddressableAssets.Settings;
|
||||
using UnityEditor.AddressableAssets.Settings.GroupSchemas;
|
||||
|
||||
public class CheckBundleDupeDependenciesMultiIsolatedGroups : CheckBundleDupeDependencies
|
||||
{
|
||||
protected internal struct GroupComparator : IEqualityComparer<List<AddressableAssetGroup>>
|
||||
{
|
||||
public bool Equals(List<AddressableAssetGroup> x, List<AddressableAssetGroup> y)
|
||||
{
|
||||
foreach (AddressableAssetGroup group in x)
|
||||
{
|
||||
if (y.Find(i => i.Guid == group.Guid) == null)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int GetHashCode(List<AddressableAssetGroup> obj)
|
||||
{
|
||||
int hashCode = obj.Count > 0 ? 17 : 0;
|
||||
foreach (AddressableAssetGroup group in obj)
|
||||
hashCode = hashCode * 31 + group.Guid.GetHashCode();
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ruleName
|
||||
{
|
||||
get { return "Check Duplicate Bundle Dependencies Multi-Isolated Groups"; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fix duplicates by moving them to new groups.
|
||||
/// </summary>
|
||||
/// <param name="settings">The current Addressables settings object</param>
|
||||
/// <remarks>Duplicates referenced by the same groups will be moved to the same new group.</remarks>
|
||||
public override void FixIssues(AddressableAssetSettings settings)
|
||||
{
|
||||
if (CheckDupeResults == null)
|
||||
CheckForDuplicateDependencies(settings);
|
||||
|
||||
Dictionary<GUID, List<AddressableAssetGroup>> implicitAssetsToGroup = GetImplicitAssetsToGroup(CheckDupeResults);
|
||||
|
||||
var groupsToAssets = new Dictionary<List<AddressableAssetGroup>, List<GUID>>(new GroupComparator());
|
||||
foreach (KeyValuePair<GUID, List<AddressableAssetGroup>> pair in implicitAssetsToGroup)
|
||||
{
|
||||
if (!groupsToAssets.TryGetValue(pair.Value, out List<GUID> assets))
|
||||
{
|
||||
assets = new List<GUID>();
|
||||
groupsToAssets.Add(pair.Value, assets);
|
||||
}
|
||||
|
||||
groupsToAssets[pair.Value].Add(pair.Key);
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<List<AddressableAssetGroup>, List<GUID>> pair in groupsToAssets)
|
||||
{
|
||||
var group = settings.CreateGroup("Duplicate Asset Isolation", false, false, false, null, typeof(BundledAssetGroupSchema), typeof(ContentUpdateGroupSchema));
|
||||
group.GetSchema<ContentUpdateGroupSchema>().StaticContent = true;
|
||||
foreach (GUID asset in pair.Value)
|
||||
settings.CreateOrMoveEntry(asset.ToString(), group, false, false);
|
||||
}
|
||||
|
||||
settings.SetDirty(AddressableAssetSettings.ModificationEvent.BatchModification, null, true, true);
|
||||
}
|
||||
|
||||
protected Dictionary<GUID, List<AddressableAssetGroup>> GetImplicitAssetsToGroup(IEnumerable<CheckDupeResult> checkDupeResults)
|
||||
{
|
||||
var implicitAssetsToGroup = new Dictionary<GUID, List<AddressableAssetGroup>>();
|
||||
foreach (var checkDupeResult in checkDupeResults)
|
||||
{
|
||||
GUID assetGuid = checkDupeResult.DuplicatedGroupGuid;
|
||||
if (!implicitAssetsToGroup.TryGetValue(assetGuid, out List<AddressableAssetGroup> groups))
|
||||
{
|
||||
groups = new List<AddressableAssetGroup>();
|
||||
implicitAssetsToGroup.Add(assetGuid, groups);
|
||||
}
|
||||
|
||||
implicitAssetsToGroup[assetGuid].Add(checkDupeResult.Group);
|
||||
}
|
||||
|
||||
return implicitAssetsToGroup;
|
||||
}
|
||||
}
|
||||
|
||||
[InitializeOnLoad]
|
||||
class RegisterCheckBundleDupeDependenciesMultiIsolatedGroups
|
||||
{
|
||||
static RegisterCheckBundleDupeDependenciesMultiIsolatedGroups()
|
||||
{
|
||||
AnalyzeSystem.RegisterNewRule<CheckBundleDupeDependenciesMultiIsolatedGroups>();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 088af34993ef24e4bb1eef60a41942d9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
#if UNITY_EDITOR
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEditor.AddressableAssets.Build;
|
||||
using UnityEditor.AddressableAssets.GUI;
|
||||
using UnityEditor.AddressableAssets.Settings;
|
||||
using UnityEditor.AddressableAssets.Settings.GroupSchemas;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// * This is a fixable rule. Running fix on it will change addresses to comply with the rule.
|
||||
/// * When run, it first identifies all addresses that seem to be paths. Of those, it makes sure that the address actually matches the path of the asset.
|
||||
/// * This would be useful if you primarily left the addresses of your assets as the path (which is the default when marking an asset addressable). If the asset is moved within the project, then the address no longer maps to where it is. This rule could fix that.
|
||||
/// </summary>
|
||||
public class PathAddressIsPath : UnityEditor.AddressableAssets.Build.AnalyzeRules.AnalyzeRule
|
||||
{
|
||||
public override bool CanFix
|
||||
{
|
||||
get { return true; }
|
||||
set { }
|
||||
}
|
||||
|
||||
public override string ruleName
|
||||
{
|
||||
get { return "Addresses that are paths, match path"; }
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
List<AddressableAssetEntry> m_MisnamedEntries = new List<AddressableAssetEntry>();
|
||||
|
||||
public override List<AnalyzeResult> RefreshAnalysis(AddressableAssetSettings settings)
|
||||
{
|
||||
List<AnalyzeResult> results = new List<AnalyzeResult>();
|
||||
foreach (var group in settings.groups)
|
||||
{
|
||||
if (group.HasSchema<PlayerDataGroupSchema>())
|
||||
continue;
|
||||
|
||||
foreach (var e in group.entries)
|
||||
{
|
||||
if (e.address.Contains("Assets") && e.address.Contains("/") && e.address != e.AssetPath)
|
||||
{
|
||||
m_MisnamedEntries.Add(e);
|
||||
results.Add(new AnalyzeResult {resultName = group.Name + kDelimiter + e.address, severity = MessageType.Error});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (results.Count == 0)
|
||||
results.Add(new AnalyzeResult {resultName = "No issues found."});
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public override void FixIssues(AddressableAssetSettings settings)
|
||||
{
|
||||
foreach (var e in m_MisnamedEntries)
|
||||
{
|
||||
e.address = e.AssetPath;
|
||||
}
|
||||
|
||||
m_MisnamedEntries = new List<AddressableAssetEntry>();
|
||||
}
|
||||
|
||||
public override void ClearAnalysis()
|
||||
{
|
||||
m_MisnamedEntries = new List<AddressableAssetEntry>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[InitializeOnLoad]
|
||||
class RegisterPathAddressIsPath
|
||||
{
|
||||
static RegisterPathAddressIsPath()
|
||||
{
|
||||
AnalyzeSystem.RegisterNewRule<PathAddressIsPath>();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5e44340fa5cd66c46ba43dd3bdbdba4f
|
||||
timeCreated: 1559935065
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 232697c075e7a374e881d423dd384c35
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"displayName": "Custom Build and Playmode Scripts",
|
||||
"description": "Example custom build and play mode scripts provided. Along with a README discussing how to add them to the Addressables system."
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: bf14725523681894dbac667caaa0316b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f66315e0705fa82438547ab07bbe65e8, type: 3}
|
||||
m_Name: CustomBuild
|
||||
m_EditorClassIdentifier: Unity.Addressables.SamplesFolder:UnityEditor.AddressableAssets.Build.DataBuilders:BuildScriptPackedMode
|
||||
instanceProviderType:
|
||||
m_AssemblyName: Unity.ResourceManager, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_ClassName: UnityEngine.ResourceManagement.ResourceProviders.InstanceProvider
|
||||
sceneProviderType:
|
||||
m_AssemblyName: Unity.ResourceManager, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_ClassName: UnityEngine.ResourceManagement.ResourceProviders.SceneProvider
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3c8ea4c2ec27a354f9b5c8d162aff2c4
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f66315e0705fa82438547ab07bbe65e8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5796c4ece8a8f054dbd288aa4e18acff, type: 3}
|
||||
m_Name: CustomPlayMode
|
||||
m_EditorClassIdentifier:
|
||||
instanceProviderType:
|
||||
m_AssemblyName: Unity.ResourceManager, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_ClassName: UnityEngine.ResourceManagement.ResourceProviders.InstanceProvider
|
||||
sceneProviderType:
|
||||
m_AssemblyName: Unity.ResourceManager, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
|
||||
m_ClassName: UnityEngine.ResourceManagement.ResourceProviders.SceneProvider
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ef55377076f186e4fb78d6f117bb52ac
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEditor.AddressableAssets.Build;
|
||||
using UnityEditor.AddressableAssets.Build.DataBuilders;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.AddressableAssets.Initialization;
|
||||
|
||||
/// <summary>
|
||||
/// Uses data built by BuildScriptPacked class. This script just sets up the correct variables and runs.
|
||||
/// </summary>
|
||||
[CreateAssetMenu(fileName = "CustomPlayMode.asset", menuName = "Addressables/Content Builders/Use CustomPlayMode Script")]
|
||||
public class CustomPlayModeScript : BuildScriptBase
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string Name
|
||||
{
|
||||
get { return "Use Custom Build (requires built groups)"; }
|
||||
}
|
||||
|
||||
private bool m_DataBuilt;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void ClearCachedData()
|
||||
{
|
||||
m_DataBuilt = false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsDataBuilt()
|
||||
{
|
||||
return m_DataBuilt;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanBuildData<T>()
|
||||
{
|
||||
return typeof(T).IsAssignableFrom(typeof(AddressablesPlayModeBuildResult));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override TResult BuildDataImplementation<TResult>(AddressablesDataBuilderInput builderInput)
|
||||
{
|
||||
var timer = new System.Diagnostics.Stopwatch();
|
||||
timer.Start();
|
||||
var settingsPath = Addressables.BuildPath + "/settings.json";
|
||||
var buildLogsPath = Addressables.BuildPath + "/buildLogs.json";
|
||||
if (!File.Exists(settingsPath))
|
||||
{
|
||||
IDataBuilderResult resE = new AddressablesPlayModeBuildResult()
|
||||
{Error = "Player content must be built before entering play mode with packed data. This can be done from the Addressables window in the Build->Build Player Content menu command."};
|
||||
return (TResult)resE;
|
||||
}
|
||||
|
||||
var rtd = JsonUtility.FromJson<ResourceManagerRuntimeData>(File.ReadAllText(settingsPath));
|
||||
if (rtd == null)
|
||||
{
|
||||
IDataBuilderResult resE = new AddressablesPlayModeBuildResult()
|
||||
{
|
||||
Error = string.Format("Unable to load initialization data from path {0}. This can be done from the Addressables window in the Build->Build Player Content menu command.", settingsPath)
|
||||
};
|
||||
return (TResult)resE;
|
||||
}
|
||||
|
||||
PackedPlayModeBuildLogs buildLogs = new PackedPlayModeBuildLogs();
|
||||
BuildTarget dataBuildTarget = BuildTarget.NoTarget;
|
||||
if (!Enum.TryParse(rtd.BuildTarget, out dataBuildTarget))
|
||||
{
|
||||
buildLogs.RuntimeBuildLogs.Add(new PackedPlayModeBuildLogs.RuntimeBuildLog(LogType.Warning,
|
||||
$"Unable to parse build target from initialization data: '{rtd.BuildTarget}'."));
|
||||
}
|
||||
|
||||
else if (BuildPipeline.GetBuildTargetGroup(dataBuildTarget) != BuildTargetGroup.Standalone)
|
||||
{
|
||||
buildLogs.RuntimeBuildLogs.Add(new PackedPlayModeBuildLogs.RuntimeBuildLog(LogType.Warning,
|
||||
$"Asset bundles built with build target {dataBuildTarget} may not be compatible with running in the Editor."));
|
||||
}
|
||||
|
||||
if (buildLogs.RuntimeBuildLogs.Count > 0)
|
||||
File.WriteAllText(buildLogsPath, JsonUtility.ToJson(buildLogs));
|
||||
|
||||
var runtimeSettingsPath = "{UnityEngine.AddressableAssets.Addressables.RuntimePath}/settings.json";
|
||||
PlayerPrefs.SetString(Addressables.kAddressablesRuntimeDataPath, runtimeSettingsPath);
|
||||
PlayerPrefs.SetString(Addressables.kAddressablesRuntimeBuildLogPath, buildLogsPath);
|
||||
IDataBuilderResult res = new AddressablesPlayModeBuildResult() {OutputPath = settingsPath, Duration = timer.Elapsed.TotalSeconds};
|
||||
m_DataBuilt = true;
|
||||
return (TResult)res;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5796c4ece8a8f054dbd288aa4e18acff
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
|
||||
/// <summary>
|
||||
/// Script added to bootstrap scene loading for the scene built by the <see cref="CustomBuildScript"/> Sample.
|
||||
/// </summary>
|
||||
public class LoadSceneForCustomBuild : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// Assigned the address of an AddressableAsset to bootstrap dynamically loading a scene at runtime.
|
||||
/// </summary>
|
||||
public string SceneKey;
|
||||
|
||||
/// <summary>
|
||||
/// Start is called before the first frame update.
|
||||
/// </summary>
|
||||
void Start()
|
||||
{
|
||||
Addressables.LoadSceneAsync(SceneKey);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 69be213651d80fa4e91e08f167430e1a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
Custom Play Mode and Build Scripts
|
||||
A custom play mode script and build script have been provided in this sample. This custom build script creates a build that only includes the currently open scene. A bootstrap scene is automatically created and a script is added that loads the built scene on startup. The custom play mode script works similarly to the Use Existing Build (requires built groups) play mode script already included. The methods added to accomplish this are CreateCurrentSceneOnlyBuildSetup and RevertCurrentSceneSetup on the CustomBuildScript.
|
||||
|
||||
For this examples, the build and load paths used by default are [UnityEngine.AddressableAssets.Addressables.BuildPath]/[BuildTarget] and {UnityEngine.AddressableAssets.Addressables.RuntimePath}/[BuildTarget] respectively.
|
||||
|
||||
Custom play mode scripts inherit from BuildScriptBase. There are several overridable methods, such as ClearCachedData, IsDataBuilt, and CanBuildData<T>. However, the most noteable method to override is BuildDataImplementation<TResult>. This is the method that is used to setup or build content.
|
||||
|
||||
The CanBuildData<T> determines if the customs script shows up in the Build/New Build/ menu or the Play Mode Scripts menu. If the data type being built is AddressablesPlayModeBuildResult, the script shows up in the Play Mode Scripts menu. If the type is AddressablesPlayerBuildResult, the script shows up in the Build/New Build/ menu.
|
||||
|
||||
The ScriptableObject of the class has already been created, but the Create menu can be used to make another ScriptableObject if you desire. For this CustomPlayModeScript the create menu path is Addressables/Content Builders/Use CustomPlayMode Script. By default, this creates a CustomPlayMode.asset ScriptableObject. The same goes for the CustomBuildScript.
|
||||
|
||||
When creating custom scripts, you need to specify the CreateAssetMenu tag on your class in order to create the ScriptableObject.
|
||||
|
||||
Once the ScriptableObject is created, add it to the list of ScriptableObjects called Build and Play Mode Scripts on the AddressableAssetSettings object.
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b092ee038e51419478aad6a1e0bb611c
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a0ad1be6d42efd842b7c66b0f2e0bf3c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"displayName": "Disable AssetImport on Build",
|
||||
"description": "A script that disables asset importing during a player build. This improves build performance since AssetBundles are copied into StreamingAssets at build time."
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b6f38bdfddda93c4e94a543875738d14
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build.Reporting;
|
||||
#endif
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Disabled AssetImporter for Player Build.
|
||||
/// </summary>
|
||||
public class DisableAssetImportOnBuild
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// Disables the AssetImporter for a player build.
|
||||
/// </summary>
|
||||
[MenuItem("Build/Disabled Importer Build")]
|
||||
public static void DisabledImporterBuild()
|
||||
{
|
||||
try
|
||||
{
|
||||
string buildPath = $"DisabledImporterBuildPath/{EditorUserBuildSettings.activeBuildTarget}/";
|
||||
Directory.CreateDirectory(buildPath);
|
||||
|
||||
AssetDatabase.StartAssetEditing(); // prevent imports until AssetDatabase.StopAssetEditing is called
|
||||
BuildPlayerOptions options = new BuildPlayerOptions()
|
||||
{
|
||||
target = EditorUserBuildSettings.activeBuildTarget,
|
||||
scenes = EditorBuildSettings.scenes.Select(s => s.path).ToArray(),
|
||||
options = BuildOptions.None,
|
||||
locationPathName = $"{buildPath}/build{GetExtension()}"
|
||||
};
|
||||
|
||||
BuildReport report = BuildPipeline.BuildPlayer(options);
|
||||
|
||||
Addressables.Log(report.summary.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
AssetDatabase.StopAssetEditing();
|
||||
}
|
||||
}
|
||||
|
||||
static string GetExtension()
|
||||
{
|
||||
if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneWindows
|
||||
|| EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneWindows64)
|
||||
return ".exe";
|
||||
else if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneOSX)
|
||||
return ".app";
|
||||
else if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android)
|
||||
return ".apk";
|
||||
else if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.iOS)
|
||||
return ".ipa";
|
||||
return "";
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 972c027f27cd52247a88f65fef7ad8ed
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5a7501c50d3f9304c960e1d1be564ebd
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"displayName": "Import Groups Tool",
|
||||
"description": "A tool that imports group assets (for example from a custom package) to the current project."
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 84f6a4f5c4b77e44aa3e2decf12f1bfc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,179 @@
|
|||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEditor.AddressableAssets;
|
||||
using UnityEditor.AddressableAssets.Settings;
|
||||
using UnityEditor.AddressableAssets.Settings.GroupSchemas;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Imports an existing AddressableAssetGroup and existing AddressableAssetGroupSchemas.
|
||||
/// </summary>
|
||||
public class ImportExistingGroup : EditorWindow
|
||||
{
|
||||
string groupPath;
|
||||
string groupName;
|
||||
string schemaFolder;
|
||||
|
||||
[MenuItem("Window/Asset Management/Addressables/Import Groups", priority = 2063)]
|
||||
public static void ShowWindow()
|
||||
{
|
||||
AddressableAssetSettings settings = AddressableAssetSettingsDefaultObject.Settings;
|
||||
if (settings == null)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Error",
|
||||
"Attempting to open Import Groups window, but no Addressables Settings file exists. \n\nOpen 'Window/Asset Management/Addressables/Groups' for more info.", "Ok");
|
||||
return;
|
||||
}
|
||||
|
||||
GetWindow(typeof(ImportExistingGroup), false, "Import Groups");
|
||||
}
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
groupPath = EditorGUILayout.TextField(new GUIContent("Group Path", "The path of the group asset to import, for example 'Packages/com.unity.example/MyGroup.asset'."), groupPath);
|
||||
using (new GUILayout.HorizontalScope())
|
||||
{
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button("Import Groups"))
|
||||
{
|
||||
ImportGroup(groupPath, schemaFolder);
|
||||
groupName = Path.GetFileNameWithoutExtension(groupPath);
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.Space(10f);
|
||||
groupName = EditorGUILayout.TextField(
|
||||
new GUIContent("Group Name", "The name of the group that the schemas will be added to. This should be the filename of the imported group, for example 'MyGroup'."), groupName);
|
||||
schemaFolder = EditorGUILayout.TextField(new GUIContent("Schema Folder", "The folder containing the schema assets of the group to import, for example 'Packages/com.unity.example/Schemas'."),
|
||||
schemaFolder);
|
||||
using (new GUILayout.HorizontalScope())
|
||||
{
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button("Import Schemas"))
|
||||
ImportSchemas(groupName, schemaFolder);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an existing group to the default Settings. This will copy the group to the default location, typically in the Assets/AddressableAssetsData folder.
|
||||
/// </summary>
|
||||
/// <param name="groupPath">The path of the group.</param>
|
||||
/// <param name="schemaFolder">The folder containing only the group's schema assets.</param>
|
||||
public void ImportGroup(string groupPath, string schemaFolder)
|
||||
{
|
||||
AddressableAssetSettings settings = AddressableAssetSettingsDefaultObject.Settings;
|
||||
if (settings == null)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Error", "Cannot import group. No Addressables Settings file exists. \n\nOpen 'Window/Asset Management/Addressables/Groups' for more info.", "Ok");
|
||||
return;
|
||||
}
|
||||
|
||||
ImportGroupInternal(settings, groupPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds existing schemas to a group. This will copy the schemas to the default location, typically in the Assets/AddressableAssetsData folder.
|
||||
/// </summary>
|
||||
/// <param name="groupPath">The name of the group.</param>
|
||||
/// <param name="schemaFolder">The folder containing the schema assets.</param>
|
||||
public void ImportSchemas(string groupName, string schemaFolder)
|
||||
{
|
||||
AddressableAssetSettings settings = AddressableAssetSettingsDefaultObject.Settings;
|
||||
if (settings == null)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Error", "Cannot import schemas. No Addressables Settings file exists. \n\nOpen 'Window/Asset Management/Addressables/Groups' for more info.", "Ok");
|
||||
return;
|
||||
}
|
||||
|
||||
ImportSchemasInternal(settings, groupName, schemaFolder);
|
||||
}
|
||||
|
||||
void ImportGroupInternal(AddressableAssetSettings settings, string groupPath)
|
||||
{
|
||||
if (string.IsNullOrEmpty(groupPath) || Path.GetExtension(groupPath).ToLower() != ".asset" || !File.Exists(groupPath))
|
||||
{
|
||||
Debug.LogError($"Group at '{groupPath}' not a valid group asset. Group will not be imported.");
|
||||
return;
|
||||
}
|
||||
|
||||
AddressableAssetGroup oldGroup = AssetDatabase.LoadAssetAtPath<AddressableAssetGroup>(groupPath);
|
||||
if (oldGroup == null)
|
||||
{
|
||||
Debug.LogError($"Cannot load group asset at '{groupPath}'. Group will not be imported.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (settings.FindGroup(oldGroup.Name) != null)
|
||||
{
|
||||
Debug.LogError($"Settings already contains group '{oldGroup.Name}'. Group will not be imported.");
|
||||
return;
|
||||
}
|
||||
|
||||
string groupFileName = Path.GetFileName(groupPath);
|
||||
string newGroupPath = $"{settings.GroupFolder}/{groupFileName}";
|
||||
newGroupPath = newGroupPath.Replace("\\", "/");
|
||||
if (File.Exists(newGroupPath))
|
||||
{
|
||||
Debug.LogError($"File already exists at '{newGroupPath}'. Group will not be imported.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!AssetDatabase.CopyAsset(groupPath, newGroupPath))
|
||||
Debug.LogError("Failed to copy group asset. Importing group failed.");
|
||||
}
|
||||
|
||||
void ImportSchemasInternal(AddressableAssetSettings settings, string groupName, string schemaFolder)
|
||||
{
|
||||
if (string.IsNullOrEmpty(schemaFolder) || !Directory.Exists(schemaFolder))
|
||||
{
|
||||
Debug.LogError($"Schema folder path is not a valid folder '{schemaFolder}'. Schemas will not be imported.");
|
||||
return;
|
||||
}
|
||||
|
||||
AddressableAssetGroup group = settings.FindGroup(groupName);
|
||||
if (group == null)
|
||||
{
|
||||
Debug.LogError($"Settings does not contain group '{groupName}'. Schemas will not be imported.");
|
||||
return;
|
||||
}
|
||||
|
||||
string[] schemaPaths = Directory.GetFiles(schemaFolder);
|
||||
foreach (string unparsedPath in schemaPaths)
|
||||
{
|
||||
if (Path.GetExtension(unparsedPath).ToLower() != ".asset")
|
||||
continue;
|
||||
|
||||
string path = unparsedPath.Replace("\\", "/");
|
||||
AddressableAssetGroupSchema schema = AssetDatabase.LoadAssetAtPath<AddressableAssetGroupSchema>(path);
|
||||
if (schema == null)
|
||||
{
|
||||
Debug.LogError($"Cannot load schema asset at '{path}'. Schema will not be imported.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (schema is BundledAssetGroupSchema bundledSchema)
|
||||
{
|
||||
List<string> variableNames = schema.Group.Settings.profileSettings.GetVariableNames();
|
||||
SetBundledAssetGroupSchemaPaths(settings, bundledSchema.BuildPath, AddressableAssetSettings.kLocalBuildPath, "LocalBuildPath", variableNames);
|
||||
SetBundledAssetGroupSchemaPaths(settings, bundledSchema.LoadPath, AddressableAssetSettings.kLocalLoadPath, "LocalLoadPath", variableNames);
|
||||
}
|
||||
|
||||
group.AddSchema(schema);
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetBundledAssetGroupSchemaPaths(AddressableAssetSettings settings, ProfileValueReference pvr, string newVariableName, string oldVariableName, List<string> variableNames)
|
||||
{
|
||||
if (variableNames.Contains(newVariableName))
|
||||
pvr.SetVariableByName(settings, newVariableName);
|
||||
else if (variableNames.Contains(oldVariableName))
|
||||
pvr.SetVariableByName(settings, oldVariableName);
|
||||
else
|
||||
Debug.LogWarning("Default path variable " + newVariableName + " not found when initializing BundledAssetGroupSchema. Please manually set the path via the groups window.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 94d2183767d45b94e8fc22db85592b2b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4d8cdbd7e9728574590c65a6309c1b3b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"displayName": "Prefab Spawner",
|
||||
"description": "A basic script that instantiates and destroys a prefab AssetReference."
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
|
||||
/// <summary>
|
||||
/// A script that spawns and destroys a number of AssetReferences after a given delay.
|
||||
/// </summary>
|
||||
public class PrefabSpawnerSample : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// The prefab to spawn.
|
||||
/// </summary>
|
||||
public AssetReference SpawnablePrefab;
|
||||
|
||||
/// <summary>
|
||||
/// The time, in seconds, to delay before spawning prefabs.
|
||||
/// </summary>
|
||||
public float DelayBetweenSpawns = 2.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The time, in seconds, to delay before destroying the spawned prefabs.
|
||||
/// </summary>
|
||||
public float DealyBeforeDestroying = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The number of prefabs to spawn.
|
||||
/// </summary>
|
||||
public int NumberOfPrefabsToSpawn = 1;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
StartCoroutine(StartSpawner());
|
||||
}
|
||||
|
||||
IEnumerator StartSpawner()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
yield return new WaitForSeconds(DelayBetweenSpawns);
|
||||
StartCoroutine(SpawnTemporaryCube());
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator SpawnTemporaryCube()
|
||||
{
|
||||
List<AsyncOperationHandle<GameObject>> handles = new List<AsyncOperationHandle<GameObject>>();
|
||||
|
||||
for (int i = 0; i < NumberOfPrefabsToSpawn; i++)
|
||||
{
|
||||
//Instantiates a prefab with the address "Cube". If this isn't working make sure you have your Addressable Groups
|
||||
//window setup and a prefab with the address "Cube" exists.
|
||||
AsyncOperationHandle<GameObject> handle = SpawnablePrefab.InstantiateAsync();
|
||||
handles.Add(handle);
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(DealyBeforeDestroying);
|
||||
|
||||
//Release the AsyncOperationHandles which destroys the GameObject
|
||||
foreach (var handle in handles)
|
||||
Addressables.Release(handle);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d2e10a4bfa7e55d49b41ee109b1076a7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ba61d97f8b5643440bc89fb642a82021
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets.DynamicResourceLocators;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
using UnityEngine.TestTools;
|
||||
using Assert = NUnit.Framework.Assert;
|
||||
using UnityEngine.AddressableAssets;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEditor.AddressableAssets.Settings;
|
||||
using UnityEditor.AddressableAssets.Settings.GroupSchemas;
|
||||
#endif
|
||||
|
||||
namespace Addressables.SamplesTests
|
||||
{
|
||||
public abstract class SamplesTests : AddressablesTestFixture
|
||||
{
|
||||
string m_AssetReferenceObjectKey = nameof(m_AssetReferenceObjectKey);
|
||||
|
||||
#if UNITY_EDITOR
|
||||
internal override void Setup(AddressableAssetSettings settings, string tempAssetFolder)
|
||||
{
|
||||
AddressableAssetGroup assetReference = settings.CreateGroup("assetReferenceSamplesGroup", false, false, true,
|
||||
new List<AddressableAssetGroupSchema>(), typeof(BundledAssetGroupSchema));
|
||||
|
||||
GameObject go = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||||
AssetReferenceTestBehavior behavior = go.AddComponent<AssetReferenceTestBehavior>();
|
||||
|
||||
string hasBehaviorPath = tempAssetFolder + "/AssetReferenceBehavior.prefab";
|
||||
|
||||
string referencePath = tempAssetFolder + "/reference.prefab";
|
||||
string guid = CreatePrefab(referencePath);
|
||||
behavior.Reference = settings.CreateAssetReference(guid);
|
||||
behavior.AssetReferenceAddress = referencePath.Replace("\\", "/");
|
||||
|
||||
PrefabUtility.SaveAsPrefabAsset(go, hasBehaviorPath);
|
||||
settings.CreateOrMoveEntry(AssetDatabase.AssetPathToGUID(hasBehaviorPath), assetReference, false, false).address = m_AssetReferenceObjectKey;
|
||||
}
|
||||
#endif
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator Samples_GetAddressFromAssetReference_ReturnsCorrectAddress()
|
||||
{
|
||||
var savedImpl = UnityEngine.AddressableAssets.Addressables.m_AddressablesInstance;
|
||||
UnityEngine.AddressableAssets.Addressables.m_AddressablesInstance = m_Addressables;
|
||||
|
||||
AsyncOperationHandle assetReferenceHandle = m_Addressables.InstantiateAsync(m_AssetReferenceObjectKey);
|
||||
yield return assetReferenceHandle;
|
||||
Assert.IsNotNull(assetReferenceHandle.Result as GameObject);
|
||||
AssetReferenceTestBehavior behavior =
|
||||
(assetReferenceHandle.Result as GameObject).GetComponent<AssetReferenceTestBehavior>();
|
||||
|
||||
string returnedAddress = AddressablesUtility.GetAddressFromAssetReference(behavior.Reference);
|
||||
|
||||
Assert.AreEqual(behavior.AssetReferenceAddress, returnedAddress);
|
||||
|
||||
m_Addressables.Release(assetReferenceHandle);
|
||||
UnityEngine.AddressableAssets.Addressables.m_AddressablesInstance = savedImpl;
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
class SamplesTests_FastMode : SamplesTests
|
||||
{
|
||||
protected override TestBuildScriptMode BuildScriptMode
|
||||
{
|
||||
get { return TestBuildScriptMode.Fast; }
|
||||
}
|
||||
}
|
||||
|
||||
class SamplesTests_VirtualMode : SamplesTests
|
||||
{
|
||||
protected override TestBuildScriptMode BuildScriptMode
|
||||
{
|
||||
get { return TestBuildScriptMode.Virtual; }
|
||||
}
|
||||
}
|
||||
|
||||
class SamplesTests_PackedPlaymodeMode : SamplesTests
|
||||
{
|
||||
protected override TestBuildScriptMode BuildScriptMode
|
||||
{
|
||||
get { return TestBuildScriptMode.PackedPlaymode; }
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//Unable to run tests in standalone given how upm-ci handles Samples. May be possible with a different test setup than currently available.
|
||||
//[UnityPlatform(exclude = new[] { RuntimePlatform.WindowsEditor, RuntimePlatform.OSXEditor, RuntimePlatform.LinuxEditor })]
|
||||
//class SamplesTests_PackedMode : SamplesTests { protected override TestBuildScriptMode BuildScriptMode { get { return TestBuildScriptMode.Packed; } } }
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5efe6ffbacc3ffd4892844438cc7d814
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"name": "Unity.Addressables.Samples.Tests",
|
||||
"references": [
|
||||
"Unity.Addressables",
|
||||
"Unity.ResourceManager",
|
||||
"Unity.Addressables.Editor",
|
||||
"Unity.ScriptableBuildPipeline.Editor",
|
||||
"Unity.Addressables.Tests",
|
||||
"Unity.Addressables.SamplesFolder"
|
||||
],
|
||||
"optionalUnityReferences": [
|
||||
"TestAssemblies"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": true,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": false,
|
||||
"defineConstraints": [
|
||||
"UNITY_INCLUDE_TESTS",
|
||||
"UNITY_INCLUDE_TESTS"
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5b724fcc890f4bf42ba21c2e7b52918f
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"name": "Unity.Addressables.SamplesFolder",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"Unity.Addressables",
|
||||
"Unity.ResourceManager",
|
||||
"Unity.Addressables.Editor",
|
||||
"Unity.ScriptableBuildPipeline",
|
||||
"Unity.ScriptableBuildPipeline.Editor"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d6943e136388dab41a5efd55b9daeb35
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Loading…
Add table
Add a link
Reference in a new issue