void ConnectLiveLink(MessageEventArgs args)
        {
            LiveLinkMsg.LogReceived("ConnectLiveLink");

            int player = args.playerId;
            var buildConfigurationGuid = args.Receive <Hash128>();

            //@TODO: Implement this properly
            //system.World.GetExistingSystem<EditorSubSceneLiveLinkSystem>().CleanupAllScenes();

            //@TODO: How does this work with multiple connections?
            LiveLinkAssetBundleBuildSystem.instance.ClearTrackedAssets();
            if (_Connections.TryGetValue(player, out var connection))
            {
                connection.Dispose();
            }

            var newConnection = new LiveLinkConnection(buildConfigurationGuid);

            _Connections[player] = newConnection;
            using (var scenes = newConnection.GetInitialScenes(player, Allocator.Temp))
                m_Connection.SendArray(LiveLinkMsg.EditorResponseConnectLiveLink, scenes, player);

            TimeBasedCallbackInvoker.SetCallback(DetectSceneChanges);
            EditorUpdateUtility.EditModeQueuePlayerLoopUpdate();

            LiveLinkPlayerConnected?.Invoke(player, newConnection._BuildConfigurationGUID);
        }
예제 #2
0
        void ConnectLiveLink(MessageEventArgs args)
        {
            LiveLinkMsg.LogReceived("ConnectLiveLink");

            int player        = args.playerId;
            var buildSettings = args.Receive <Hash128>();

            //@TODO: Implement this properly
            //system.World.GetExistingSystem<EditorSubSceneLiveLinkSystem>().CleanupAllScenes();

            //@TODO: How does this work with multiple connections?
            LiveLinkAssetBundleBuildSystem.instance.ClearUsedAssetsTargetHash();
            if (_Connections.TryGetValue(player, out var connection))
            {
                connection.Dispose();
            }

            var newConnection = new LiveLinkConnection(buildSettings);

            _Connections[player] = newConnection;

            TimeBasedCallbackInvoker.SetCallback(DetectSceneChanges);
            EditorUpdateUtility.EditModeQueuePlayerLoopUpdate();

            LiveLinkPlayerConnected?.Invoke(player, newConnection._BuildSettingsGUID);
        }
예제 #3
0
        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 SendAssetBundleTargetHash(NativeArray <ResolvedAssetID> resolvedAssets, int playerId)
        {
            foreach (var asset in resolvedAssets)
            {
                LiveLinkMsg.LogSend($"AssetBundleTargetHash response {asset.GUID} | {asset.TargetHash} to playerId: {playerId}");
            }

            EditorConnection.instance.SendArray(LiveLinkMsg.ResponseAssetBundleTargetHash, resolvedAssets, playerId);

            foreach (var asset in resolvedAssets)
            {
                _UsedAssetsTargetHash[asset.GUID] = asset.TargetHash;
            }

            TimeBasedCallbackInvoker.SetCallback(DetectChangedAssets);
        }
        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);
            }
        }
        void DetectSceneChanges()
        {
            if (_Connections.Count == 0)
            {
                TimeBasedCallbackInvoker.ClearCallback(DetectSceneChanges);
                LiveLinkAssetBundleBuildSystem.instance.ClearTrackedAssets();
                return;
            }

            foreach (var c in _Connections)
            {
                var connection = c.Value;
                if (!connection._IsEnabled)
                {
                    continue;
                }

                try
                {
                    connection.Update(_ChangeSets, _LoadScenes, _UnloadScenes, LiveLinkMode.LiveConvertStandalonePlayer);

                    // Load scenes that are not being edited live
                    SendLoadScenes(_LoadScenes.AsArray(), c.Key);
                    // Unload scenes that are no longer being edited / need to be reloaded etc
                    SendUnloadScenes(_UnloadScenes.AsArray(), c.Key);

                    // Apply changes to scenes that are being edited
                    foreach (var change in _ChangeSets)
                    {
                        SendChangeSet(change, c.Key);
                        change.Dispose();
                    }
                }
                finally
                {
                    _ChangeSets.Clear();
                    _UnloadScenes.Clear();
                    _LoadScenes.Clear();
                }
            }
        }
        public void RequestSubSceneTargetHash(MessageEventArgs args)
        {
            using (var subScenes = args.ReceiveArray <SubSceneGUID>())
            {
                var resolvedScenes = new HashSet <ResolvedSubSceneID>();
                foreach (var subScene in subScenes)
                {
                    LiveLinkMsg.LogInfo($"RequestSubSceneTargetHash => {subScene.Guid}, {subScene.BuildConfigurationGuid}");

                    var targetHash = EntityScenesPaths.GetSubSceneArtifactHash(subScene.Guid, subScene.BuildConfigurationGuid, UnityEditor.Experimental.AssetDatabaseExperimental.ImportSyncMode.Queue);
                    _UsedSubSceneTargetHash[subScene] = targetHash;
                    if (targetHash.IsValid)
                    {
                        resolvedScenes.Add(new ResolvedSubSceneID {
                            SubSceneGUID = subScene, TargetHash = 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);
            }
        }
예제 #8
0
        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);
                }
            }
        }