void OnCatalogLoaded(AsyncOperationHandle <ContentCatalogData> op) { var ccd = op.Result; m_ProviderInterface.ResourceManager.Release(op); Addressables.LogFormat("Addressables - Content catalog load result = {0}.", ccd); if (ccd != null) { ccd.location = m_ProviderInterface.Location; ccd.localHash = m_LocalHashValue; if (!string.IsNullOrEmpty(m_RemoteHashValue) && !string.IsNullOrEmpty(m_LocalDataPath)) { var dir = Path.GetDirectoryName(m_LocalDataPath); if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir)) { Directory.CreateDirectory(dir); } var localCachePath = m_LocalDataPath; Addressables.LogFormat("Addressables - Saving cached content catalog to {0}.", localCachePath); File.WriteAllText(localCachePath, JsonUtility.ToJson(ccd)); File.WriteAllText(localCachePath.Replace(".json", ".hash"), m_RemoteHashValue); ccd.localHash = m_RemoteHashValue; } } m_ProviderInterface.Complete(ccd, ccd != null, null); }
protected override void Execute() { Addressables.LogFormat("Addressables - runtime data operation completed with status = {0}, result = {1}.", m_rtdOp.Status, m_rtdOp.Result); if (m_rtdOp.Result == null) { Addressables.LogWarningFormat("Addressables - Unable to load runtime data at location {0}.", m_rtdOp); Complete(Result, false, string.Format("Addressables - Unable to load runtime data at location {0}.", m_rtdOp)); return; } var rtd = m_rtdOp.Result; m_Addressables.Release(m_rtdOp); if (rtd.CertificateHandlerType != null) { m_Addressables.ResourceManager.CertificateHandlerInstance = Activator.CreateInstance(rtd.CertificateHandlerType) as CertificateHandler; } #if UNITY_EDITOR if (UnityEditor.EditorUserBuildSettings.activeBuildTarget.ToString() != rtd.BuildTarget) { Addressables.LogErrorFormat("Addressables - runtime data was built with a different build target. Expected {0}, but data was built with {1}. Certain assets may not load correctly including shaders. You can rebuild player content via the Addressables window.", UnityEditor.EditorUserBuildSettings.activeBuildTarget, rtd.BuildTarget); } #endif if (!rtd.LogResourceManagerExceptions) { ResourceManager.ExceptionHandler = null; } if (!rtd.ProfileEvents) { m_Diagnostics.Dispose(); m_Diagnostics = null; } // DiagnosticEventCollector.ResourceManagerProfilerEventsEnabled = rtd.ProfileEvents; Addressables.Log("Addressables - loading initialization objects."); ContentCatalogProvider ccp = m_Addressables.ResourceManager.ResourceProviders .FirstOrDefault(rp => rp.GetType() == typeof(ContentCatalogProvider)) as ContentCatalogProvider; if (ccp != null) { ccp.DisableCatalogUpdateOnStart = rtd.DisableCatalogUpdateOnStartup; } var locMap = new ResourceLocationMap("CatalogLocator", rtd.CatalogLocations); m_Addressables.AddResourceLocator(locMap); IList <IResourceLocation> catalogs; if (!locMap.Locate(ResourceManagerRuntimeData.kCatalogAddress, typeof(ContentCatalogData), out catalogs)) { Addressables.LogWarningFormat( "Addressables - Unable to find any catalog locations in the runtime data."); m_Addressables.RemoveResourceLocator(locMap); Complete(Result, false, "Addressables - Unable to find any catalog locations in the runtime data."); } else { Addressables.LogFormat("Addressables - loading content catalogs, {0} found.", catalogs.Count); LoadContentCatalogInternal(catalogs, 0, locMap); } }
void LoadOpComplete(AsyncOperationHandle <IResourceLocator> op, IList <IResourceLocation> catalogs, ResourceLocationMap locMap, int index) { if (op.Result != null) { m_Addressables.RemoveResourceLocator(locMap); Result = op.Result; Complete(Result, true, string.Empty); m_Addressables.Release(op); Addressables.Log("Addressables - initialization complete."); } else { Addressables.LogFormat("Addressables - failed to load content catalog from {0}.", op); if (index + 1 >= catalogs.Count) { Addressables.LogWarningFormat("Addressables - initialization failed.", op); m_Addressables.RemoveResourceLocator(locMap); Complete(Result, false, op.OperationException != null ? op.OperationException.Message : "LoadContentCatalogInternal"); m_Addressables.Release(op); } else { m_loadCatalogOp = LoadContentCatalogInternal(catalogs, index + 1, locMap); m_Addressables.Release(op); } } }
//Attempts to load each catalog in order, stopping at first success. void LoadContentCatalogInternal(IList <IResourceLocation> catalogs, int index, ResourceLocationMap locMap) { Addressables.LogFormat("Addressables - loading content catalog from {0}.", catalogs[index].InternalId); LoadContentCatalog(catalogs[index], m_ProviderSuffix).Completed += op => { if (op.Result != null) { m_Addressables.RemoveResourceLocator(locMap); Result = op.Result; Complete(Result, true, string.Empty); m_Addressables.Release(op); Addressables.Log("Addressables - initialization complete."); } else { Addressables.LogFormat("Addressables - failed to load content catalog from {0}.", op); if (index + 1 >= catalogs.Count) { Addressables.LogWarningFormat("Addressables - initialization failed.", op); m_Addressables.RemoveResourceLocator(locMap); Complete(Result, false, op.OperationException != null ? op.OperationException.Message : "LoadContentCatalogInternal"); m_Addressables.Release(op); } else { LoadContentCatalogInternal(catalogs, index + 1, locMap); m_Addressables.Release(op); } } }; }
protected override void Execute() { var rtd = m_RtdOp.Result; List <AsyncOperationHandle> initOperations = new List <AsyncOperationHandle>(); foreach (var i in rtd.InitializationObjects) { if (i.ObjectType.Value == null) { Addressables.LogFormat("Invalid initialization object type {0}.", i.ObjectType); continue; } try { var o = i.GetAsyncInitHandle(m_Addressables.ResourceManager); initOperations.Add(o); Addressables.LogFormat("Initialization object {0} created instance {1}.", i, o); } catch (Exception ex) { Addressables.LogErrorFormat("Exception thrown during initialization of object {0}: {1}", i, ex.ToString()); } } m_DepOp = m_Addressables.ResourceManager.CreateGenericGroupOperation(initOperations, true); m_DepOp.Completed += (obj) => { bool success = obj.Status == AsyncOperationStatus.Succeeded; Complete(true, success, success ? "" : $"{obj.DebugName} failed initialization."); m_Addressables.Release(m_DepOp); }; }
//Attempts to load each catalog in order, stopping at first success. internal AsyncOperationHandle <IResourceLocator> LoadContentCatalogInternal(IList <IResourceLocation> catalogs, int index, ResourceLocationMap locMap, IResourceLocation remoteHashLocation) { Addressables.LogFormat("Addressables - loading content catalog from {0}.", m_Addressables.ResourceManager.TransformInternalId(catalogs[index])); var loadOp = LoadContentCatalog(catalogs[index], m_ProviderSuffix, remoteHashLocation); if (loadOp.IsDone) { LoadOpComplete(loadOp, catalogs, locMap, index, remoteHashLocation); } else { loadOp.Completed += op => { LoadOpComplete(op, catalogs, locMap, index, remoteHashLocation); } }; return(loadOp); } void LoadOpComplete(AsyncOperationHandle <IResourceLocator> op, IList <IResourceLocation> catalogs, ResourceLocationMap locMap, int index, IResourceLocation remoteHashLocation) { if (op.Result != null) { m_Addressables.RemoveResourceLocator(locMap); Result = op.Result; Complete(Result, true, string.Empty); m_Addressables.Release(op); Addressables.Log("Addressables - initialization complete."); } else { Addressables.LogFormat("Addressables - failed to load content catalog from {0}.", op); if (index + 1 >= catalogs.Count) { Addressables.LogWarningFormat("Addressables - initialization failed.", op); m_Addressables.RemoveResourceLocator(locMap); if (op.OperationException != null) { Complete(Result, false, op.OperationException); } else { Complete(Result, false, "LoadContentCatalogInternal"); } m_Addressables.Release(op); } else { m_loadCatalogOp = LoadContentCatalogInternal(catalogs, index + 1, locMap, remoteHashLocation); m_Addressables.Release(op); } } } }
public void Start(ProvideHandle providerInterface, bool disableCatalogUpdateOnStart) { m_ProviderInterface = providerInterface; m_LocalDataPath = null; m_RemoteHashValue = null; List <object> deps = new List <object>(); // TODO: garbage. need to pass actual count and reuse the list m_ProviderInterface.GetDependencies(deps); string idToLoad = DetermineIdToLoad(m_ProviderInterface.Location, deps, disableCatalogUpdateOnStart); Addressables.LogFormat("Addressables - Using content catalog from {0}.", idToLoad); providerInterface.ResourceManager.ProvideResource <ContentCatalogData>(new ResourceLocationBase(idToLoad, idToLoad, typeof(JsonAssetProvider).FullName, typeof(ContentCatalogData))).Completed += OnCatalogLoaded; }
protected override void Execute() { var rtd = m_RtdOp.Result; if (rtd == null) { Addressables.LogError("RuntimeData is null. Please ensure you have built the correct Player Content."); Complete(true, true, ""); return; } string buildLogsPath = m_Addressables.ResolveInternalId(PlayerPrefs.GetString(Addressables.kAddressablesRuntimeBuildLogPath)); if (LogRuntimeWarnings(buildLogsPath)) { File.Delete(buildLogsPath); } List <AsyncOperationHandle> initOperations = new List <AsyncOperationHandle>(); foreach (var i in rtd.InitializationObjects) { if (i.ObjectType.Value == null) { Addressables.LogFormat("Invalid initialization object type {0}.", i.ObjectType); continue; } try { var o = i.GetAsyncInitHandle(m_Addressables.ResourceManager); initOperations.Add(o); Addressables.LogFormat("Initialization object {0} created instance {1}.", i, o); } catch (Exception ex) { Addressables.LogErrorFormat("Exception thrown during initialization of object {0}: {1}", i, ex.ToString()); } } m_DepOp = m_Addressables.ResourceManager.CreateGenericGroupOperation(initOperations, true); m_DepOp.Completed += (obj) => { bool success = obj.Status == AsyncOperationStatus.Succeeded; Complete(true, success, success ? "" : $"{obj.DebugName}, status={obj.Status}, result={obj.Result} failed initialization."); m_Addressables.Release(m_DepOp); }; }
//Attempts to load each catalog in order, stopping at first success. AsyncOperationHandle <IResourceLocator> LoadContentCatalogInternal(IList <IResourceLocation> catalogs, int index, ResourceLocationMap locMap) { Addressables.LogFormat("Addressables - loading content catalog from {0}.", m_Addressables.ResourceManager.TransformInternalId(catalogs[index])); var loadOp = LoadContentCatalog(catalogs[index], m_ProviderSuffix); if (loadOp.IsDone) { LoadOpComplete(loadOp, catalogs, locMap, index); } else { loadOp.Completed += op => LoadOpComplete(op, catalogs, locMap, index); } return(loadOp); }
public void Start(ProvideHandle providerInterface, bool disableCatalogUpdateOnStart, bool isLocalCatalogInBundle) { m_ProviderInterface = providerInterface; m_LocalDataPath = null; m_RemoteHashValue = null; List <object> deps = new List <object>(); // TODO: garbage. need to pass actual count and reuse the list m_ProviderInterface.GetDependencies(deps); string idToLoad = DetermineIdToLoad(m_ProviderInterface.Location, deps, disableCatalogUpdateOnStart); Addressables.LogFormat("Addressables - Using content catalog from {0}.", idToLoad); bool isLocalCatalog = idToLoad.Equals(GetTransformedInternalId(m_ProviderInterface.Location)); LoadCatalog(idToLoad, isLocalCatalogInBundle, isLocalCatalog); }
internal string DetermineIdToLoad(IResourceLocation location, IList <object> dependencyObjects, bool disableCatalogUpdateOnStart = false) { //default to load actual local source catalog string idToLoad = GetTransformedInternalId(location); if (dependencyObjects != null && location.Dependencies != null && dependencyObjects.Count == (int)DependencyHashIndex.Count && location.Dependencies.Count == (int)DependencyHashIndex.Count) { var remoteHash = dependencyObjects[(int)DependencyHashIndex.Remote] as string; m_LocalHashValue = dependencyObjects[(int)DependencyHashIndex.Cache] as string; Addressables.LogFormat("Addressables - ContentCatalogProvider CachedHash = {0}, RemoteHash = {1}.", m_LocalHashValue, remoteHash); if (string.IsNullOrEmpty(remoteHash)) //offline { if (!string.IsNullOrEmpty(m_LocalHashValue)) //cache exists { idToLoad = GetTransformedInternalId(location.Dependencies[(int)DependencyHashIndex.Cache]).Replace(".hash", ".json"); } } else //online { if (remoteHash == m_LocalHashValue) //cache of remote is good { idToLoad = GetTransformedInternalId(location.Dependencies[(int)DependencyHashIndex.Cache]).Replace(".hash", ".json"); } else //remote is different than cache, or no cache { if (disableCatalogUpdateOnStart) { m_LocalHashValue = Hash128.Compute(idToLoad).ToString(); } else { idToLoad = GetTransformedInternalId(location.Dependencies[(int)DependencyHashIndex.Remote]).Replace(".hash", ".json"); m_LocalDataPath = GetTransformedInternalId(location.Dependencies[(int)DependencyHashIndex.Cache]).Replace(".hash", ".json"); } m_RemoteHashValue = remoteHash; } } } return(idToLoad); }
public void Start(ProvideHandle providerInterface, bool disableCatalogUpdateOnStart, bool isLocalCatalogInBundle) { m_ProviderInterface = providerInterface; m_LocalDataPath = null; m_RemoteHashValue = null; List <object> deps = new List <object>(); // TODO: garbage. need to pass actual count and reuse the list m_ProviderInterface.GetDependencies(deps); string idToLoad = DetermineIdToLoad(m_ProviderInterface.Location, deps, disableCatalogUpdateOnStart); Addressables.LogFormat("Addressables - Using content catalog from {0}.", idToLoad); bool isLocalCatalog = idToLoad.Equals(GetTransformedInternalId(m_ProviderInterface.Location)); if (isLocalCatalogInBundle && isLocalCatalog) { try { var bc = new BundledCatalog(idToLoad); bc.OnLoaded += ccd => { m_ContentCatalogData = ccd; OnCatalogLoaded(ccd); }; bc.LoadCatalogFromBundleAsync(); } catch (Exception ex) { m_ProviderInterface.Complete <ContentCatalogData>(null, false, ex); } } else { IResourceLocation location = new ResourceLocationBase(idToLoad, idToLoad, typeof(JsonAssetProvider).FullName, typeof(ContentCatalogData)); providerInterface.ResourceManager.ProvideResource <ContentCatalogData>(location).Completed += op => { m_ContentCatalogData = op.Result; m_ProviderInterface.ResourceManager.Release(op); OnCatalogLoaded(m_ContentCatalogData); }; } }
static void LoadProvider(AddressablesImpl addressables, ObjectInitializationData providerData, string providerSuffix) { //don't add providers that have the same id... var indexOfExistingProvider = -1; var newProviderId = string.IsNullOrEmpty(providerSuffix) ? providerData.Id : (providerData.Id + providerSuffix); for (int i = 0; i < addressables.ResourceManager.ResourceProviders.Count; i++) { var rp = addressables.ResourceManager.ResourceProviders[i]; if (rp.ProviderId == newProviderId) { indexOfExistingProvider = i; break; } } //if not re-initializing, just use the old provider if (indexOfExistingProvider >= 0 && string.IsNullOrEmpty(providerSuffix)) { return; } var provider = providerData.CreateInstance <IResourceProvider>(newProviderId); if (provider != null) { if (indexOfExistingProvider < 0 || !string.IsNullOrEmpty(providerSuffix)) { Addressables.LogFormat("Addressables - added provider {0} with id {1}.", provider, provider.ProviderId); addressables.ResourceManager.ResourceProviders.Add(provider); } else { Addressables.LogFormat("Addressables - replacing provider {0} at index {1}.", provider, indexOfExistingProvider); addressables.ResourceManager.ResourceProviders[indexOfExistingProvider] = provider; } } else { Addressables.LogWarningFormat("Addressables - Unable to load resource provider from {0}.", providerData); } }
static internal bool CheckForNewEntry(ref string assetName, AddressableAssetSettings aaSettings, string guid, string checkToForceAddressable) { var entry = aaSettings.FindAssetEntry(guid); if (entry != null) { assetName = entry.address; } else { var path = AssetDatabase.GUIDToAssetPath(guid); if (!string.IsNullOrEmpty(path)) { if (!aaSettings.IsAssetPathInAddressableDirectory(path, out assetName)) { assetName = path; if (!string.IsNullOrEmpty(checkToForceAddressable)) { var newEntry = aaSettings.CreateOrMoveEntry(guid, aaSettings.DefaultGroup); Addressables.LogFormat("Created AddressableAsset {0} in group {1}.", newEntry.address, aaSettings.DefaultGroup.Name); } else { if (!File.Exists(path)) { assetName = "Missing File!"; } else { return(true); } } } } else { assetName = "Missing File!"; } } return(false); }
public void Start(ProvideHandle providerInterface, bool disableCatalogUpdateOnStart, bool isLocalCatalogInBundle) { m_ProviderInterface = providerInterface; m_DisableCatalogUpdateOnStart = disableCatalogUpdateOnStart; m_IsLocalCatalogInBundle = isLocalCatalogInBundle; m_ProviderInterface.SetWaitForCompletionCallback(WaitForCompletionCallback); m_LocalDataPath = null; m_RemoteHashValue = null; List <object> deps = new List <object>(); // TODO: garbage. need to pass actual count and reuse the list m_ProviderInterface.GetDependencies(deps); string idToLoad = DetermineIdToLoad(m_ProviderInterface.Location, deps, disableCatalogUpdateOnStart); Addressables.LogFormat("Addressables - Using content catalog from {0}.", idToLoad); bool loadCatalogFromLocalBundle = isLocalCatalogInBundle && CanLoadCatalogFromBundle(idToLoad, m_ProviderInterface.Location); LoadCatalog(idToLoad, loadCatalogFromLocalBundle); }
void OnCatalogLoaded(AsyncOperationHandle <ContentCatalogData> op) { var ccd = op.Result; m_RM.Release(op); Addressables.LogFormat("Addressables - Content catalog load result = {0}.", ccd); // ResourceManagerEventCollector.PostEvent(ResourceManagerEventCollector.EventType.LoadAsyncCompletion, m_ProviderInterface.Location, Time.frameCount - m_StartFrame); m_ProviderInterface.Complete(ccd, ccd != null, null); if (ccd != null && !string.IsNullOrEmpty(m_HashValue) && !string.IsNullOrEmpty(m_LocalDataPath)) { var dir = Path.GetDirectoryName(m_LocalDataPath); if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir)) { Directory.CreateDirectory(dir); } var localCachePath = m_LocalDataPath; Addressables.LogFormat("Addressables - Saving cached content catalog to {0}.", localCachePath); File.WriteAllText(localCachePath, JsonUtility.ToJson(ccd)); File.WriteAllText(localCachePath.Replace(".json", ".hash"), m_HashValue); } }
internal string DetermineIdToLoad(IResourceLocation location, IList <object> dependencyObjects) { //default to load actual local source catalog string idToLoad = location.InternalId; if (dependencyObjects != null && location.Dependencies != null && dependencyObjects.Count == (int)DependencyHashIndex.Count && location.Dependencies.Count == (int)DependencyHashIndex.Count) { var remoteHash = dependencyObjects[(int)DependencyHashIndex.Remote] as string; var cachedHash = dependencyObjects[(int)DependencyHashIndex.Cache] as string; Addressables.LogFormat("Addressables - ContentCatalogProvider CachedHash = {0}, RemoteHash = {1}.", cachedHash, remoteHash); if (string.IsNullOrEmpty(remoteHash)) //offline { if (!string.IsNullOrEmpty(cachedHash)) //cache exists { idToLoad = location.Dependencies[(int)DependencyHashIndex.Cache].InternalId.Replace(".hash", ".json"); } } else //online { if (remoteHash == cachedHash) //cache of remote is good { idToLoad = location.Dependencies[(int)DependencyHashIndex.Cache].InternalId.Replace(".hash", ".json"); } else //remote is different than cache, or no cache { idToLoad = location.Dependencies[(int)DependencyHashIndex.Remote].InternalId.Replace(".hash", ".json"); m_LocalDataPath = location.Dependencies[(int)DependencyHashIndex.Cache].InternalId.Replace(".hash", ".json"); m_HashValue = remoteHash; } } } return(idToLoad); }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { if (property == null || label == null) { Debug.LogError("Error rendering drawer for AssetReference property."); return; } string labelText = label.text; m_AssetRefObject = property.GetActualObjectForSerializedProperty <AssetReference>(fieldInfo, ref labelText); if (labelText != label.text || string.IsNullOrEmpty(label.text)) { label = new GUIContent(labelText, label.tooltip); } if (m_AssetRefObject == null) { return; } EditorGUI.BeginProperty(position, label, property); GatherFilters(property); string guid = m_AssetRefObject.AssetGUID; var aaSettings = AddressableAssetSettingsDefaultObject.Settings; var checkToForceAddressable = string.Empty; if (!string.IsNullOrEmpty(newGuid) && newGuidPropertyPath == property.propertyPath) { if (newGuid == noAssetString) { SetObject(property, null, out guid); newGuid = string.Empty; } else { if (SetObject(property, AssetDatabase.LoadAssetAtPath <Object>(AssetDatabase.GUIDToAssetPath(newGuid)), out guid)) { checkToForceAddressable = newGuid; } newGuid = string.Empty; } } bool isNotAddressable = false; m_AssetName = noAssetString; if (aaSettings != null && !string.IsNullOrEmpty(guid)) { var entry = aaSettings.FindAssetEntry(guid); if (entry != null) { m_AssetName = entry.address; } else { var path = AssetDatabase.GUIDToAssetPath(guid); if (!string.IsNullOrEmpty(path)) { var dir = Path.GetDirectoryName(path); bool foundAddr = false; while (!string.IsNullOrEmpty(dir)) { var dirEntry = aaSettings.FindAssetEntry(AssetDatabase.AssetPathToGUID(dir)); if (dirEntry != null) { foundAddr = true; m_AssetName = dirEntry.address + path.Remove(0, dir.Length); break; } dir = Path.GetDirectoryName(dir); } if (!foundAddr) { m_AssetName = path; if (!string.IsNullOrEmpty(checkToForceAddressable)) { var newEntry = aaSettings.CreateOrMoveEntry(guid, aaSettings.DefaultGroup); Addressables.LogFormat("Created AddressableAsset {0} in group {1}.", newEntry.address, aaSettings.DefaultGroup.Name); } else { if (!File.Exists(path)) { m_AssetName = "Missing File!"; } else { isNotAddressable = true; } } } } else { m_AssetName = "Missing File!"; } } } assetDropDownRect = EditorGUI.PrefixLabel(position, label); var nameToUse = m_AssetName; if (isNotAddressable) { nameToUse = "Not Addressable - " + nameToUse; } if (m_AssetRefObject.editorAsset != null) { var subAssets = new List <Object>(); subAssets.Add(null); var assetPath = AssetDatabase.GUIDToAssetPath(m_AssetRefObject.AssetGUID); subAssets.AddRange(AssetDatabase.LoadAllAssetRepresentationsAtPath(assetPath)); var mainType = AssetDatabase.GetMainAssetTypeAtPath(assetPath); if (mainType == typeof(SpriteAtlas)) { var atlas = AssetDatabase.LoadAssetAtPath <SpriteAtlas>(assetPath); var sprites = new Sprite[atlas.spriteCount]; atlas.GetSprites(sprites); subAssets.AddRange(sprites); } if (subAssets.Count > 1) { assetDropDownRect = DrawSubAssetsControl(property, subAssets); } } bool isDragging = Event.current.type == EventType.DragUpdated && position.Contains(Event.current.mousePosition); bool isDropping = Event.current.type == EventType.DragPerform && position.Contains(Event.current.mousePosition); DrawControl(property, isDragging, isDropping, nameToUse, isNotAddressable, guid); HandleDragAndDrop(property, isDragging, isDropping, guid); EditorGUI.EndProperty(); }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { if (property == null || label == null) { Debug.LogError("Error rendering drawer for AssetReference property."); return; } string labelText = label.text; m_AssetRefObject = property.GetActualObjectForSerializedProperty <AssetReference>(fieldInfo, ref labelText); label.text = labelText; if (m_AssetRefObject == null) { return; } EditorGUI.BeginProperty(position, label, property); GatherFilters(property); string guid = m_AssetRefObject.AssetGUID; var aaSettings = AddressableAssetSettingsDefaultObject.Settings; var checkToForceAddressable = string.Empty; if (!string.IsNullOrEmpty(newGuid) && newGuidPropertyPath == property.propertyPath) { if (newGuid == noAssetString) { SetObject(property, null, out guid); newGuid = string.Empty; } else { if (SetObject(property, AssetDatabase.LoadAssetAtPath <Object>(AssetDatabase.GUIDToAssetPath(newGuid)), out guid)) { checkToForceAddressable = newGuid; } newGuid = string.Empty; } } bool isNotAddressable = false; m_AssetName = noAssetString; Texture2D icon = null; if (aaSettings != null && !string.IsNullOrEmpty(guid)) { var entry = aaSettings.FindAssetEntry(guid); if (entry != null) { m_AssetName = entry.address; icon = AssetDatabase.GetCachedIcon(entry.AssetPath) as Texture2D; } else { var path = AssetDatabase.GUIDToAssetPath(guid); if (!string.IsNullOrEmpty(path)) { var dir = Path.GetDirectoryName(path); bool foundAddr = false; while (!string.IsNullOrEmpty(dir)) { var dirEntry = aaSettings.FindAssetEntry(AssetDatabase.AssetPathToGUID(dir)); if (dirEntry != null) { foundAddr = true; m_AssetName = dirEntry.address + path.Remove(0, dir.Length); break; } dir = Path.GetDirectoryName(dir); } if (!foundAddr) { m_AssetName = path; if (!string.IsNullOrEmpty(checkToForceAddressable)) { var newEntry = aaSettings.CreateOrMoveEntry(guid, aaSettings.DefaultGroup); Addressables.LogFormat("Created AddressableAsset {0} in group {1}.", newEntry.address, aaSettings.DefaultGroup.Name); } else { if (!File.Exists(path)) { m_AssetName = "Missing File!"; } else { isNotAddressable = true; } } } icon = AssetDatabase.GetCachedIcon(path) as Texture2D; } else { m_AssetName = "Missing File!"; } } } assetDropDownRect = EditorGUI.PrefixLabel(position, label); var nameToUse = m_AssetName; if (isNotAddressable) { nameToUse = "Not Addressable - " + nameToUse; } if (m_AssetRefObject.editorAsset != null) { var subAssets = new List <Object>(); subAssets.Add(null); var assetPath = AssetDatabase.GUIDToAssetPath(m_AssetRefObject.AssetGUID); subAssets.AddRange(AssetDatabase.LoadAllAssetRepresentationsAtPath(assetPath)); var mainType = AssetDatabase.GetMainAssetTypeAtPath(assetPath); if (mainType == typeof(SpriteAtlas)) { var atlas = AssetDatabase.LoadAssetAtPath <SpriteAtlas>(assetPath); var sprites = new Sprite[atlas.spriteCount]; atlas.GetSprites(sprites); subAssets.AddRange(sprites); } if (subAssets.Count > 1) { assetDropDownRect = new Rect(assetDropDownRect.position, new Vector2(assetDropDownRect.width / 2, assetDropDownRect.height)); var objRect = new Rect(assetDropDownRect.xMax, assetDropDownRect.y, assetDropDownRect.width, assetDropDownRect.height); var objNames = new string[subAssets.Count]; var selIndex = 0; for (int i = 0; i < subAssets.Count; i++) { var s = subAssets[i]; var objName = s == null ? "<none>" : s.name; if (objName.EndsWith("(Clone)")) { objName = objName.Replace("(Clone)", ""); } objNames[i] = objName; if (m_AssetRefObject.SubObjectName == objName) { selIndex = i; } } //TODO: handle large amounts of sprites with a custom popup var newIndex = EditorGUI.Popup(objRect, selIndex, objNames); if (newIndex != selIndex) { Undo.RecordObject(property.serializedObject.targetObject, "Assign Asset Reference Sub Object"); var success = m_AssetRefObject.SetEditorSubObject(subAssets[newIndex]); if (success) { EditorUtility.SetDirty(property.serializedObject.targetObject); var comp = property.serializedObject.targetObject as Component; if (comp != null && comp.gameObject != null && comp.gameObject.activeInHierarchy) { EditorSceneManager.MarkSceneDirty(comp.gameObject.scene); } } } } } if (EditorGUI.DropdownButton(assetDropDownRect, new GUIContent(nameToUse, icon, m_AssetName), FocusType.Keyboard)) { newGuidPropertyPath = property.propertyPath; var nonAddressedOption = isNotAddressable ? m_AssetName : string.Empty; PopupWindow.Show(assetDropDownRect, new AssetReferencePopup(this, guid, nonAddressedOption)); } //During the drag, doing a light check on asset validity. The in-depth check happens during a drop, and should include a log if it fails. var rejectedDrag = false; if (Event.current.type == EventType.DragUpdated && position.Contains(Event.current.mousePosition)) { if (aaSettings == null) { rejectedDrag = true; } else { var aaEntries = DragAndDrop.GetGenericData("AssetEntryTreeViewItem") as List <AssetEntryTreeViewItem>; if (aaEntries != null) { if (aaEntries.Count != 1) { rejectedDrag = true; } else { if (aaEntries[0] == null || aaEntries[0].entry == null || aaEntries[0].entry.IsInResources || !ValidateAsset(aaEntries[0].entry.AssetPath)) { rejectedDrag = true; } } } else { if (DragAndDrop.paths.Length != 1) { rejectedDrag = true; } else { if (!ValidateAsset(DragAndDrop.paths[0])) { rejectedDrag = true; } } } } DragAndDrop.visualMode = rejectedDrag ? DragAndDropVisualMode.Rejected : DragAndDropVisualMode.Copy; } if (!rejectedDrag && Event.current.type == EventType.DragPerform && position.Contains(Event.current.mousePosition)) { var aaEntries = DragAndDrop.GetGenericData("AssetEntryTreeViewItem") as List <AssetEntryTreeViewItem>; if (aaEntries != null) { if (aaEntries.Count == 1) { var item = aaEntries[0]; if (item.entry != null) { if (item.entry.IsInResources) { Addressables.LogWarning("Cannot use an AssetReference on an asset in Resources. Move asset out of Resources first."); } else { SetObject(property, item.entry.TargetAsset, out guid); } } } } else { if (DragAndDrop.paths != null && DragAndDrop.paths.Length == 1) { var path = DragAndDrop.paths[0]; if (AddressableAssetUtility.IsInResources(path)) { Addressables.LogWarning("Cannot use an AssetReference on an asset in Resources. Move asset out of Resources first. "); } else if (!AddressableAssetUtility.IsPathValidForEntry(path)) { Addressables.LogWarning("Dragged asset is not valid as an Asset Reference. " + path); } else { Object obj; if (DragAndDrop.objectReferences != null && DragAndDrop.objectReferences.Length == 1) { obj = DragAndDrop.objectReferences[0]; } else { obj = AssetDatabase.LoadAssetAtPath <Object>(path); } if (SetObject(property, obj, out guid)) { aaSettings = AddressableAssetSettingsDefaultObject.GetSettings(true); var entry = aaSettings.FindAssetEntry(guid); if (entry == null && !string.IsNullOrEmpty(guid)) { aaSettings.CreateOrMoveEntry(guid, aaSettings.DefaultGroup); newGuid = guid; } } } } } } EditorGUI.EndProperty(); }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { if (property == null || label == null) { Debug.LogError("Error rendering drawer for AssetReference property."); return; } string labelText = label.text; m_AssetRefObject = property.GetActualObjectForSerializedProperty <AssetReference>(fieldInfo, ref labelText); label.text = labelText; if (m_AssetRefObject == null) { return; } EditorGUI.BeginProperty(position, label, property); GatherFilters(property); string guid = m_AssetRefObject.RuntimeKey.ToString(); var aaSettings = AddressableAssetSettingsDefaultObject.Settings; var checkToForceAddressable = string.Empty; if (!string.IsNullOrEmpty(newGuid) && newGuidPropertyPath == property.propertyPath) { if (newGuid == noAssetString) { SetObject(property, null, out guid); newGuid = string.Empty; } else { if (SetObject(property, AssetDatabase.LoadAssetAtPath <Object>(AssetDatabase.GUIDToAssetPath(newGuid)), out guid)) { checkToForceAddressable = newGuid; } newGuid = string.Empty; } } bool isNotAddressable = false; m_AssetName = noAssetString; Texture2D icon = null; if (aaSettings != null && !string.IsNullOrEmpty(guid)) { var entry = aaSettings.FindAssetEntry(guid); if (entry != null) { m_AssetName = entry.address; icon = AssetDatabase.GetCachedIcon(entry.AssetPath) as Texture2D; } else { var path = AssetDatabase.GUIDToAssetPath(guid); if (!string.IsNullOrEmpty(path)) { var dir = Path.GetDirectoryName(path); bool foundAddr = false; while (!string.IsNullOrEmpty(dir)) { var dirEntry = aaSettings.FindAssetEntry(AssetDatabase.AssetPathToGUID(dir)); if (dirEntry != null) { foundAddr = true; m_AssetName = dirEntry.address + path.Remove(0, dir.Length); break; } dir = Path.GetDirectoryName(dir); } if (!foundAddr) { m_AssetName = path; if (!string.IsNullOrEmpty(checkToForceAddressable)) { var newEntry = aaSettings.CreateOrMoveEntry(guid, aaSettings.DefaultGroup); Addressables.LogFormat("Created AddressableAsset {0} in group {1}.", newEntry.address, aaSettings.DefaultGroup.Name); } else { if (!File.Exists(path)) { m_AssetName = "Missing File!"; } else { isNotAddressable = true; } } } icon = AssetDatabase.GetCachedIcon(path) as Texture2D; } else { m_AssetName = "Missing File!"; } } } smallPos = EditorGUI.PrefixLabel(position, label); var nameToUse = m_AssetName; if (isNotAddressable) { nameToUse = "Not Addressable - " + nameToUse; } if (EditorGUI.DropdownButton(smallPos, new GUIContent(nameToUse, icon, m_AssetName), FocusType.Keyboard)) { newGuidPropertyPath = property.propertyPath; var nonAddressedOption = isNotAddressable ? m_AssetName : string.Empty; PopupWindow.Show(smallPos, new AssetReferencePopup(this, guid, nonAddressedOption)); } //During the drag, doing a light check on asset validity. The in-depth check happens during a drop, and should include a log if it fails. var rejectedDrag = false; if (Event.current.type == EventType.DragUpdated && position.Contains(Event.current.mousePosition)) { if (aaSettings == null) { rejectedDrag = true; } else { var aaEntries = DragAndDrop.GetGenericData("AssetEntryTreeViewItem") as List <AssetEntryTreeViewItem>; if (aaEntries != null) { if (aaEntries.Count != 1) { rejectedDrag = true; } else { if (aaEntries[0] != null && aaEntries[0].entry != null && aaEntries[0].entry.IsInResources) { rejectedDrag = true; } } } else { if (DragAndDrop.paths.Length != 1) { rejectedDrag = true; } } } DragAndDrop.visualMode = rejectedDrag ? DragAndDropVisualMode.Rejected : DragAndDropVisualMode.Copy; } if (!rejectedDrag && Event.current.type == EventType.DragPerform && position.Contains(Event.current.mousePosition)) { var aaEntries = DragAndDrop.GetGenericData("AssetEntryTreeViewItem") as List <AssetEntryTreeViewItem>; if (aaEntries != null) { if (aaEntries.Count == 1) { var item = aaEntries[0]; if (item.entry != null) { if (item.entry.IsInResources) { Addressables.LogWarning("Cannot use an AssetReference on an asset in Resources. Move asset out of Resources first."); } else { SetObject(property, AssetDatabase.LoadAssetAtPath <Object>(item.entry.AssetPath), out guid); } } } } else { if (DragAndDrop.paths != null && DragAndDrop.paths.Length == 1) { var path = DragAndDrop.paths[0]; if (AddressableAssetUtility.IsInResources(path)) { Addressables.LogWarning("Cannot use an AssetReference on an asset in Resources. Move asset out of Resources first. "); } else if (!AddressableAssetUtility.IsPathValidForEntry(path)) { Addressables.LogWarning("Dragged asset is not valid as an Asset Reference. " + path); } else { Object obj; if (DragAndDrop.objectReferences != null && DragAndDrop.objectReferences.Length == 1) { obj = DragAndDrop.objectReferences[0]; } else { obj = AssetDatabase.LoadAssetAtPath <Object>(path); } if (SetObject(property, obj, out guid)) { aaSettings = AddressableAssetSettingsDefaultObject.GetSettings(true); var entry = aaSettings.FindAssetEntry(guid); if (entry == null && !string.IsNullOrEmpty(guid)) { aaSettings.CreateOrMoveEntry(guid, aaSettings.DefaultGroup); newGuid = guid; } } } } } } EditorGUI.EndProperty(); }
protected override void Execute() { Addressables.LogFormat("Addressables - runtime data operation completed with status = {0}, result = {1}.", m_rtdOp.Status, m_rtdOp.Result); if (m_rtdOp.Result == null) { Addressables.LogWarningFormat("Addressables - Unable to load runtime data at location {0}.", m_rtdOp); Complete(m_Result, false, string.Format("Addressables - Unable to load runtime data at location {0}.", m_rtdOp)); return; } var rtd = m_rtdOp.Result; m_Addressables.Release(m_rtdOp); if (rtd.CertificateHandlerType != null) { m_Addressables.ResourceManager.CertificateHandlerInstance = Activator.CreateInstance(rtd.CertificateHandlerType) as CertificateHandler; } #if UNITY_EDITOR if (UnityEditor.EditorUserBuildSettings.activeBuildTarget.ToString() != rtd.BuildTarget) { Addressables.LogErrorFormat("Addressables - runtime data was built with a different build target. Expected {0}, but data was built with {1}. Certain assets may not load correctly including shaders. You can rebuild player content via the Addressable Assets window.", UnityEditor.EditorUserBuildSettings.activeBuildTarget, rtd.BuildTarget); } #endif if (!rtd.LogResourceManagerExceptions) { ResourceManager.ExceptionHandler = null; } if (!rtd.ProfileEvents) { m_Diagnostics.Dispose(); m_Diagnostics = null; } // DiagnosticEventCollector.ResourceManagerProfilerEventsEnabled = rtd.ProfileEvents; Addressables.Log("Addressables - loading initialization objects."); foreach (var i in rtd.InitializationObjects) { if (i.ObjectType.Value == null) { Addressables.LogFormat("Invalid initialization object type {0}.", i.ObjectType); continue; } try { var o = i.CreateInstance <object>(); Addressables.LogFormat("Initialization object {0} created instance {1}.", i, o); } catch (Exception ex) { Addressables.LogErrorFormat("Exception thrown during initialization of object {0}: {1}", i, ex.ToString()); } } var locMap = new ResourceLocationMap(rtd.CatalogLocations); m_Addressables.ResourceLocators.Add(locMap); IList <IResourceLocation> catalogs; if (!locMap.Locate(ResourceManagerRuntimeData.kCatalogAddress, typeof(ContentCatalogData), out catalogs)) { Addressables.LogWarningFormat("Addressables - Unable to find any catalog locations in the runtime data."); m_Addressables.ResourceLocators.Remove(locMap); Complete(m_Result, false, "Addressables - Unable to find any catalog locations in the runtime data."); } else { Addressables.LogFormat("Addressables - loading content catalogs, {0} found.", catalogs.Count); LoadContentCatalogInternal(catalogs, 0, locMap); } }
public void OnGUI() { if (AddressableAssetSettingsDefaultObject.Settings == null) { GUILayout.Space(50); if (GUILayout.Button("Create Addressables Settings")) { m_GroupEditor = null; AddressableAssetSettingsDefaultObject.Settings = AddressableAssetSettings.Create(AddressableAssetSettingsDefaultObject.kDefaultConfigFolder, AddressableAssetSettingsDefaultObject.kDefaultConfigAssetName, true, true); } if (GUILayout.Button("Import Addressables Settings")) { m_GroupEditor = null; var path = EditorUtility.OpenFilePanel("Addressables Settings Object", AddressableAssetSettingsDefaultObject.kDefaultConfigFolder, "asset"); if (!string.IsNullOrEmpty(path)) { var i = path.ToLower().IndexOf("/assets/"); if (i > 0) { path = path.Substring(i + 1); Addressables.LogFormat("Loading Addressables Settings from {0}", path); var obj = AssetDatabase.LoadAssetAtPath <AddressableAssetSettings>(path); if (obj != null) { AddressableAssetSettingsDefaultObject.Settings = obj; } else { Debug.LogWarning("Unable to load asset settings from: " + path + "\nPlease ensure the location included in the project directory." ); } } } } GUILayout.Space(20); GUILayout.BeginHorizontal(); GUILayout.Space(50); UnityEngine.GUI.skin.label.wordWrap = true; GUILayout.Label("Click the \"Create\" or \"Import\" button above or simply drag an asset into this window to start using Addressables. Once you begin, the Addressables system will save some assets to your project to keep up with its data"); GUILayout.Space(50); GUILayout.EndHorizontal(); switch (Event.current.type) { case EventType.DragPerform: DragAndDrop.visualMode = DragAndDropVisualMode.Copy; foreach (var path in DragAndDrop.paths) { if (AddressableAssetUtility.IsPathValidForEntry(path)) { var guid = AssetDatabase.AssetPathToGUID(path); if (!string.IsNullOrEmpty(guid)) { if (AddressableAssetSettingsDefaultObject.Settings == null) { AddressableAssetSettingsDefaultObject.Settings = AddressableAssetSettings.Create(AddressableAssetSettingsDefaultObject.kDefaultConfigFolder, AddressableAssetSettingsDefaultObject.kDefaultConfigAssetName, true, true); } Undo.RecordObject(AddressableAssetSettingsDefaultObject.Settings, "AddressableAssetSettings"); AddressableAssetSettingsDefaultObject.Settings.CreateOrMoveEntry(guid, AddressableAssetSettingsDefaultObject.Settings.DefaultGroup); } } } break; case EventType.DragUpdated: case EventType.DragExited: DragAndDrop.visualMode = DragAndDropVisualMode.Copy; break; } } else { Rect contentRect = new Rect(0, 0, position.width, position.height); if (m_GroupEditor == null) { m_GroupEditor = new AddressableAssetsSettingsGroupEditor(this); m_GroupEditor.OnEnable(); } if (m_GroupEditor.OnGUI(contentRect)) { Repaint(); } } }
protected override void Execute() { Addressables.LogFormat("Addressables - runtime data operation completed with status = {0}, result = {1}.", m_rtdOp.Status, m_rtdOp.Result); if (m_rtdOp.Result == null) { Addressables.LogWarningFormat("Addressables - Unable to load runtime data at location {0}.", m_rtdOp); Complete(Result, false, string.Format("Addressables - Unable to load runtime data at location {0}.", m_rtdOp)); return; } Addressables.LogFormat("Initializing Addressables version {0}.", m_rtdOp.Result.AddressablesVersion); var rtd = m_rtdOp.Result; m_Addressables.ResourceManager.postProfilerEvents = rtd.ProfileEvents; WebRequestQueue.SetMaxConcurrentRequests(rtd.MaxConcurrentWebRequests); m_Addressables.CatalogRequestsTimeout = rtd.CatalogRequestsTimeout; foreach (var catalogLocation in rtd.CatalogLocations) { if (catalogLocation.Data != null && catalogLocation.Data is ProviderLoadRequestOptions loadData) { loadData.WebRequestTimeout = rtd.CatalogRequestsTimeout; } } m_Addressables.Release(m_rtdOp); if (rtd.CertificateHandlerType != null) { m_Addressables.ResourceManager.CertificateHandlerInstance = Activator.CreateInstance(rtd.CertificateHandlerType) as CertificateHandler; } #if UNITY_EDITOR if (UnityEditor.EditorUserBuildSettings.activeBuildTarget.ToString() != rtd.BuildTarget) { Addressables.LogErrorFormat("Addressables - runtime data was built with a different build target. Expected {0}, but data was built with {1}. Certain assets may not load correctly including shaders. You can rebuild player content via the Addressables window.", UnityEditor.EditorUserBuildSettings.activeBuildTarget, rtd.BuildTarget); } #endif if (!rtd.LogResourceManagerExceptions) { ResourceManager.ExceptionHandler = null; } if (!rtd.ProfileEvents) { m_Diagnostics.Dispose(); m_Diagnostics = null; m_Addressables.ResourceManager.ClearDiagnosticCallbacks(); } Addressables.Log("Addressables - loading initialization objects."); ContentCatalogProvider ccp = m_Addressables.ResourceManager.ResourceProviders .FirstOrDefault(rp => rp.GetType() == typeof(ContentCatalogProvider)) as ContentCatalogProvider; if (ccp != null) { ccp.DisableCatalogUpdateOnStart = rtd.DisableCatalogUpdateOnStartup; ccp.IsLocalCatalogInBundle = rtd.IsLocalCatalogInBundle; } var locMap = new ResourceLocationMap("CatalogLocator", rtd.CatalogLocations); m_Addressables.AddResourceLocator(locMap); IList <IResourceLocation> catalogs; if (!locMap.Locate(ResourceManagerRuntimeData.kCatalogAddress, typeof(ContentCatalogData), out catalogs)) { Addressables.LogWarningFormat( "Addressables - Unable to find any catalog locations in the runtime data."); m_Addressables.RemoveResourceLocator(locMap); Complete(Result, false, "Addressables - Unable to find any catalog locations in the runtime data."); } else { Addressables.LogFormat("Addressables - loading content catalogs, {0} found.", catalogs.Count); IResourceLocation remoteHashLocation = null; if (catalogs[0].Dependencies.Count == 2 && rtd.DisableCatalogUpdateOnStartup) { remoteHashLocation = catalogs[0].Dependencies[(int)ContentCatalogProvider.DependencyHashIndex.Remote]; catalogs[0].Dependencies[(int)ContentCatalogProvider.DependencyHashIndex.Remote] = catalogs[0].Dependencies[(int)ContentCatalogProvider.DependencyHashIndex.Cache]; } m_loadCatalogOp = LoadContentCatalogInternal(catalogs, 0, locMap, remoteHashLocation); } }