using System; using System.Collections.Generic; using System.IO; using System.Linq; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.TestTools; using UnityEngine.SceneManagement; using UnityEditor; using EditorSceneManagement = UnityEditor.SceneManagement; namespace UnityEditor.TestTools.Graphics { /// /// Test framework prebuild step to collect reference images for the current test run and prepare them for use in the /// player. /// Will also build Lightmaps for specially labelled scenes. /// public class SetupGraphicsTestCases { static string bakeLabel = "TestRunnerBake"; private static bool IsBuildingForEditorPlaymode { get { var playmodeLauncher = typeof(RequirePlatformSupportAttribute).Assembly.GetType( "UnityEditor.TestTools.TestRunner.PlaymodeLauncher"); var isRunningField = playmodeLauncher.GetField("IsRunning"); return (bool)isRunningField.GetValue(null); } } public void Setup() { Setup(EditorGraphicsTestCaseProvider.ReferenceImagesRoot); } public void Setup(string rootImageTemplatePath) { ColorSpace colorSpace; BuildTarget buildPlatform; RuntimePlatform runtimePlatform; GraphicsDeviceType[] graphicsDevices; // Figure out if we're preparing to run in Editor playmode, or if we're building to run outside the Editor if (IsBuildingForEditorPlaymode) { colorSpace = QualitySettings.activeColorSpace; buildPlatform = BuildTarget.NoTarget; runtimePlatform = Application.platform; graphicsDevices = new[] {SystemInfo.graphicsDeviceType}; } else { buildPlatform = EditorUserBuildSettings.activeBuildTarget; runtimePlatform = Utils.BuildTargetToRuntimePlatform(buildPlatform); colorSpace = PlayerSettings.colorSpace; graphicsDevices = PlayerSettings.GetGraphicsAPIs(buildPlatform); } var bundleBuilds = new List(); foreach (var api in graphicsDevices) { var images = EditorGraphicsTestCaseProvider.CollectReferenceImagePathsFor(rootImageTemplatePath, colorSpace, runtimePlatform, api); Utils.SetupReferenceImageImportSettings(images.Values); if (buildPlatform == BuildTarget.NoTarget) continue; bundleBuilds.Add(new AssetBundleBuild { assetBundleName = string.Format("referenceimages-{0}-{1}-{2}", colorSpace, runtimePlatform, api), addressableNames = images.Keys.ToArray(), assetNames = images.Values.ToArray() }); } if (bundleBuilds.Count > 0) { if (!Directory.Exists("Assets/StreamingAssets")) Directory.CreateDirectory("Assets/StreamingAssets"); foreach (var bundle in bundleBuilds) { BuildPipeline.BuildAssetBundles("Assets/StreamingAssets", new [] { bundle }, BuildAssetBundleOptions.None, buildPlatform); } } // For each scene in the build settings, force build of the lightmaps if it has "DoLightmap" label. // Note that in the PreBuildSetup stage, TestRunner has already created a new scene with its testing monobehaviours Scene trScene = EditorSceneManagement.EditorSceneManager.GetSceneAt(0); foreach( EditorBuildSettingsScene scene in EditorBuildSettings.scenes) { SceneAsset sceneAsset = AssetDatabase.LoadAssetAtPath(scene.path); var labels = new System.Collections.Generic.List(AssetDatabase.GetLabels(sceneAsset)); if ( labels.Contains(bakeLabel) ) { EditorSceneManagement.EditorSceneManager.OpenScene(scene.path, EditorSceneManagement.OpenSceneMode.Additive); Scene currentScene = EditorSceneManagement.EditorSceneManager.GetSceneAt(1); EditorSceneManagement.EditorSceneManager.SetActiveScene(currentScene); Lightmapping.giWorkflowMode = Lightmapping.GIWorkflowMode.OnDemand; Lightmapping.Bake(); EditorSceneManagement.EditorSceneManager.SaveScene( currentScene ); EditorSceneManagement.EditorSceneManager.SetActiveScene(trScene); EditorSceneManagement.EditorSceneManager.CloseScene(currentScene, true); } } if (!IsBuildingForEditorPlaymode) new CreateSceneListFileFromBuildSettings().Setup(); } static string lightmapDataGitIgnore = @"Lightmap-*_comp* LightingData.* ReflectionProbe-*"; [MenuItem("Assets/Tests/Toggle Scene for Bake")] public static void LabelSceneForBake() { UnityEngine.Object[] sceneAssets = Selection.GetFiltered(typeof(SceneAsset), SelectionMode.DeepAssets); EditorSceneManagement.EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo(); EditorSceneManagement.SceneSetup[] previousSceneSetup = EditorSceneManagement.EditorSceneManager.GetSceneManagerSetup(); foreach (UnityEngine.Object sceneAsset in sceneAssets) { List labels = new System.Collections.Generic.List(AssetDatabase.GetLabels(sceneAsset)); string scenePath = AssetDatabase.GetAssetPath(sceneAsset); string gitIgnorePath = Path.Combine( Path.Combine( Application.dataPath.Substring(0, Application.dataPath.Length-6), scenePath.Substring(0, scenePath.Length-6) ) , ".gitignore" ); if (labels.Contains(bakeLabel)) { labels.Remove(bakeLabel); File.Delete(gitIgnorePath); } else { labels.Add(bakeLabel); string sceneLightingDataFolder = Path.Combine( Path.GetDirectoryName(scenePath), Path.GetFileNameWithoutExtension(scenePath) ); if ( !AssetDatabase.IsValidFolder(sceneLightingDataFolder) ) AssetDatabase.CreateFolder( Path.GetDirectoryName(scenePath), Path.GetFileNameWithoutExtension(scenePath) ); File.WriteAllText(gitIgnorePath, lightmapDataGitIgnore); EditorSceneManagement.EditorSceneManager.OpenScene(scenePath, EditorSceneManagement.OpenSceneMode.Single); EditorSceneManagement.EditorSceneManager.SetActiveScene( EditorSceneManagement.EditorSceneManager.GetSceneAt(0) ); Lightmapping.giWorkflowMode = Lightmapping.GIWorkflowMode.OnDemand; EditorSceneManagement.EditorSceneManager.SaveScene( EditorSceneManagement.EditorSceneManager.GetSceneAt(0) ); } AssetDatabase.SetLabels( sceneAsset, labels.ToArray() ); } AssetDatabase.Refresh(); if (previousSceneSetup.Length == 0) EditorSceneManagement.EditorSceneManager.NewScene(EditorSceneManagement.NewSceneSetup.DefaultGameObjects, EditorSceneManagement.NewSceneMode.Single); else EditorSceneManagement.EditorSceneManager.RestoreSceneManagerSetup(previousSceneSetup); } [MenuItem("Assets/Tests/Toggle Scene for Bake", true)] public static bool LabelSceneForBake_Test() { return IsSceneAssetSelected(); } public static bool IsSceneAssetSelected() { UnityEngine.Object[] sceneAssets = Selection.GetFiltered(typeof(SceneAsset), SelectionMode.DeepAssets); return sceneAssets.Length != 0; } } }