void RequestAssetBundleTargetHash(MessageEventArgs args) { //@TODO: should be based on connection / BuildSetting var buildTarget = EditorUserBuildSettings.activeBuildTarget; using (var assets = args.ReceiveArray <GUID>()) { var resolvedAssets = new HashSet <ResolvedAssetID>(); foreach (var asset in assets) { LiveLinkMsg.LogReceived($"AssetBundleTargetHash request => {asset}"); var targetHash = LiveLinkBuildPipeline.CalculateTargetHash(asset, buildTarget); resolvedAssets.Add(new ResolvedAssetID { GUID = asset, TargetHash = targetHash }); LiveLinkBuildPipeline.CalculateTargetDependencies(asset, buildTarget, out ResolvedAssetID[] dependencies); resolvedAssets.UnionWith(dependencies); } var resolved = new NativeArray <ResolvedAssetID>(resolvedAssets.Count, Allocator.Temp); int j = 0; foreach (var id in resolvedAssets) { resolved[j++] = id; } SendAssetBundleTargetHash(resolved, args.playerId); } }
public static Hash128 GetHash(string guid, BuildTarget target) { LiveLinkBuildPipeline.RemapBuildInAssetGuid(ref guid); // TODO: GetArtifactHash needs to take BuildTarget so we can get Artifacts for other than the ActiveBuildTarget return(AssetDatabaseExperimental.GetArtifactHash(guid, typeof(LiveLinkBuildImporter), AssetDatabaseExperimental.ImportSyncMode.Block)); }
internal static Hash128 GetHash(string guid, BuildTarget target, ImportMode importMode) { LiveLinkBuildPipeline.RemapBuildInAssetGuid(ref guid); AssetBundleTypeCache.RegisterMonoScripts(); // TODO: GetArtifactHash needs to take BuildTarget so we can get Artifacts for other than the ActiveBuildTarget return(AssetDatabaseCompatibility.GetArtifactHash(guid, typeof(LiveLinkBuildImporter), importMode)); }
public static Hash128 GetHash(string guid, BuildTarget target, AssetDatabaseExperimental.ImportSyncMode syncMode) { LiveLinkBuildPipeline.RemapBuildInAssetGuid(ref guid); AssetBundleTypeCache.RegisterMonoScripts(); // TODO: GetArtifactHash needs to take BuildTarget so we can get Artifacts for other than the ActiveBuildTarget return(AssetDatabaseExperimental.GetArtifactHash(guid, typeof(LiveLinkBuildImporter), syncMode)); }
void RequestAssetTargetHash(MessageEventArgs args) { //@TODO: should be based on connection / BuildSetting var buildTarget = EditorUserBuildSettings.activeBuildTarget; // Array of Asset GUIDs the player is requesting the asset hash of using (var assets = args.ReceiveArray <GUID>()) { // Set of ready to send (all valid target hashes) assets var resolvedAssets = new HashSet <ResolvedAssetID>(); foreach (var asset in assets) { LiveLinkMsg.LogReceived($"AssetBundleTargetHash request => {asset} | {AssetDatabase.GUIDToAssetPath(asset.ToString())}"); // For each Asset- queue calculating target hash and add to tracked assets Unity.Entities.Hash128 targetHash = LiveLinkBuildPipeline.CalculateTargetHash(asset, buildTarget, ImportMode.Asynchronous); m_TrackedAssets[asset] = targetHash; resolvedAssets.Add(new ResolvedAssetID { GUID = asset, TargetHash = targetHash }); // If asset hash is valid (meaning import is ready) then also do the same for dependencies if (targetHash.IsValid) { LiveLinkBuildPipeline.CalculateTargetDependencies(targetHash, buildTarget, out ResolvedAssetID[] dependencies, ImportMode.Asynchronous, asset); foreach (var dependency in dependencies) { m_TrackedAssets[dependency.GUID] = dependency.TargetHash; resolvedAssets.Add(new ResolvedAssetID { GUID = dependency.GUID, TargetHash = dependency.TargetHash }); } } } // Callback to re-send tracked assets when their targethash changes if (m_TrackedAssets.Count > 0) { TimeBasedCallbackInvoker.SetCallback(DetectChangedAssets); } // No assets? Send nothing and set no callback if (resolvedAssets.Count == 0) { return; } var resolved = new NativeArray <ResolvedAssetID>(resolvedAssets.Count, Allocator.Temp); int j = 0; foreach (var id in resolvedAssets) { resolved[j++] = id; } SendAssetTargetHash(resolved, args.playerId); } }
void DetectChangedAssets() { if (_UsedAssetsTargetHash.Count == 0) { TimeBasedCallbackInvoker.ClearCallback(DetectChangedAssets); return; } var changedAssets = new NativeList <ResolvedAssetID>(Allocator.Temp); var buildTarget = EditorUserBuildSettings.activeBuildTarget; foreach (var asset in _UsedAssetsTargetHash) { //@TODO: Artifact hash API should give error message when used on V1 pipeline (currently does not). var targetHash = LiveLinkBuildPipeline.CalculateTargetHash(asset.Key, buildTarget); if (asset.Value != targetHash) { var path = AssetDatabase.GUIDToAssetPath(asset.Key.ToString()); LiveLinkMsg.LogInfo("Detected asset change: " + path); changedAssets.Add(new ResolvedAssetID { GUID = asset.Key, TargetHash = targetHash }); LiveLinkBuildPipeline.CalculateTargetDependencies(asset.Key, buildTarget, out ResolvedAssetID[] dependencies); foreach (var dependency in dependencies) { if (_UsedAssetsTargetHash.ContainsKey(dependency.GUID)) { continue; } // New Dependency var dependencyHash = LiveLinkBuildPipeline.CalculateTargetHash(dependency.GUID, buildTarget); changedAssets.Add(new ResolvedAssetID { GUID = dependency.GUID, TargetHash = dependencyHash }); } } } if (changedAssets.Length != 0) { SendAssetBundleTargetHash(changedAssets, 0); } }
//@TODO: The asset pipeline should be building & cache the asset bundle public string BuildAssetBundleIfNotCached(GUID guid, out Hash128 targetHash) { //@TODO Get build target from player requesting it... var buildTarget = EditorUserBuildSettings.activeBuildTarget; targetHash = LiveLinkBuildPipeline.CalculateTargetHash(guid, buildTarget); // TODO: Move caching into LiveLinkBuildPipeline var cachePath = ResolveCachePath(targetHash); if (File.Exists(cachePath)) { return(cachePath); } if (!Directory.Exists(cachePath)) { Directory.CreateDirectory(Path.GetDirectoryName(cachePath)); } // Debug.Log($"Building {guid} fresh"); // Patching only works if the ObjectManifest comes from the same GUID every time. // So we can't delete this file. Optimally we would control the build pipeline // to make it always be at a specific local identifier in file var manifest = ScriptableObject.CreateInstance <AssetObjectManifest>(); AssetObjectManifestBuilder.BuildManifest(guid, manifest); UnityEditorInternal.InternalEditorUtility.SaveToSerializedFileAndForget(new[] { manifest }, AssetObjectManifestPath, true); var didSucceed = LiveLinkBuildPipeline.BuildAssetBundle(guid, $"{cachePath}", EditorUserBuildSettings.activeBuildTarget); if (!didSucceed) { Debug.LogError($"Failed to build asset bundle: '{guid}'"); return(null); } return(cachePath); }
void RequestSubSceneTargetHash(MessageEventArgs args) { //@TODO: should be based on connection / BuildSetting var buildTarget = EditorUserBuildSettings.activeBuildTarget; using (var subScenes = args.ReceiveArray <SubSceneGUID>()) { var resolvedScenes = new HashSet <ResolvedSubSceneID>(); var assetDependencies = new HashSet <ResolvedAssetID>(); foreach (var subScene in subScenes) { LiveLinkMsg.LogInfo($"RequestSubSceneTargetHash => {subScene.Guid}, {subScene.BuildConfigurationGuid}"); var targetHash = EntityScenesPaths.GetSubSceneArtifactHash(subScene.Guid, subScene.BuildConfigurationGuid, ImportMode.Asynchronous); m_TrackedSubScenes[subScene] = targetHash; if (targetHash.IsValid) { resolvedScenes.Add(new ResolvedSubSceneID { SubSceneGUID = subScene, TargetHash = targetHash }); var sceneDependencies = LiveLinkBuildPipeline.GetSubSceneDependencies(targetHash); foreach (var sceneDependency in sceneDependencies) { assetDependencies.Add(sceneDependency); m_TrackedAssets[sceneDependency.GUID] = sceneDependency.TargetHash; if (sceneDependency.TargetHash.IsValid) { LiveLinkBuildPipeline.CalculateTargetDependencies(sceneDependency.TargetHash, buildTarget, out ResolvedAssetID[] dependencies, ImportMode.Asynchronous, sceneDependency.GUID); foreach (var dependency in dependencies) { m_TrackedAssets[dependency.GUID] = dependency.TargetHash; assetDependencies.Add(new ResolvedAssetID { GUID = dependency.GUID, TargetHash = dependency.TargetHash }); } } } } } TimeBasedCallbackInvoker.SetCallback(DetectChangedAssets); if (resolvedScenes.Count == 0) { return; } var resolved = new NativeArray <ResolvedSubSceneID>(resolvedScenes.Count, Allocator.Temp); int i = 0; foreach (var id in resolvedScenes) { resolved[i++] = id; } SendSubSceneTargetHash(resolved, args.playerId); if (assetDependencies.Count > 0) { var resolvedAssets = new NativeArray <ResolvedAssetID>(assetDependencies.Count, Allocator.Temp); int assetIndex = 0; foreach (var asset in assetDependencies) { resolvedAssets[assetIndex++] = asset; } SendAssetTargetHash(resolvedAssets, args.playerId); } } }