void StateCheck() { if (PrefabStageUtility.GetCurrentPrefabStage() != null || prefabEdition) { switch (prefabType) { case PrefabAssetType.Regular: thisObjState = ObjectState.PrefabVariant; break; case PrefabAssetType.Variant: thisObjState = ObjectState.PrefabVariant; break; case PrefabAssetType.NotAPrefab: thisObjState = ObjectState.PrefabRoot; break; default: print("Unsopported type of prefab (" + prefabType + ") - " + gameObject.name); break; } } else { if (PrefabUtility.IsPartOfPrefabAsset(gameObject)) { switch (prefabType) { case PrefabAssetType.Regular: thisObjState = ObjectState.PrefabRoot; break; case PrefabAssetType.Variant: thisObjState = ObjectState.PrefabVariant; break; default: print("Unsopported type of prefab (" + prefabType + ") - " + gameObject.name); break; } } else { switch (prefabType) { case PrefabAssetType.Regular: thisObjState = ObjectState.PrefabInstance; break; case PrefabAssetType.Variant: thisObjState = ObjectState.PrefabInstance; break; case PrefabAssetType.NotAPrefab: thisObjState = ObjectState.StandAlone; break; default: print("Unsopported type of prefab (" + prefabType + ") - " + gameObject.name); break; } } } }
public IEnumerator NavMeshSurfacePrefabVariant_WhenFreshAndRebaked_ParentAssetUnchanged() { var theOriginalPrefab = AssetDatabase.LoadAssetAtPath <GameObject>(m_PrefabPath); AssetDatabase.OpenAsset(theOriginalPrefab); var theOriginalPrefabStage = PrefabStageUtility.GetCurrentPrefabStage(); var theOriginalPrefabSurface = theOriginalPrefabStage.prefabContentsRoot.GetComponent <NavMeshSurface>(); var theOriginalPrefabNavMeshData = theOriginalPrefabSurface.navMeshData; var theOriginalPrefabAssetPath = AssetDatabase.GetAssetPath(theOriginalPrefabSurface.navMeshData); Assert.IsTrue(theOriginalPrefabNavMeshData != null, "Original prefab must have some NavMeshData."); Assert.IsTrue(File.Exists(theOriginalPrefabAssetPath), "NavMeshData file must exist for the original prefab. ({0})", theOriginalPrefabAssetPath); var prefabVariant = AssetDatabase.LoadAssetAtPath <GameObject>(m_PrefabVariantPath); AssetDatabase.OpenAsset(prefabVariant); var prefabVariantStage = PrefabStageUtility.GetCurrentPrefabStage(); var prefabVariantSurface = prefabVariantStage.prefabContentsRoot.GetComponent <NavMeshSurface>(); var initialVariantNavMeshData = prefabVariantSurface.navMeshData; var initialVariantAssetPath = AssetDatabase.GetAssetPath(prefabVariantSurface.navMeshData); Assert.AreEqual(theOriginalPrefabNavMeshData, initialVariantNavMeshData, "Fresh variant must have the same NavMeshData as the original prefab."); Assert.IsTrue(initialVariantNavMeshData != null, "Prefab must have some NavMeshData."); Assert.IsTrue(File.Exists(initialVariantAssetPath), "NavMeshData file must exist. ({0})", initialVariantAssetPath); yield return(BakeNavMeshAsync(() => prefabVariantSurface, k_GrayArea)); Assert.IsTrue(initialVariantNavMeshData != null, "The initial NavMeshData (from original prefab) must still exist immediately after prefab variant re-bake."); Assert.IsTrue(File.Exists(initialVariantAssetPath), "The initial NavMeshData file (from original prefab) must exist after prefab variant re-bake. ({0})", initialVariantAssetPath); Assert.IsTrue(prefabVariantSurface.navMeshData != null, "NavMeshSurface must have NavMeshData after baking."); var unsavedRebakedNavMeshData = prefabVariantSurface.navMeshData; yield return(BakeNavMeshAsync(() => prefabVariantSurface, k_BrownArea)); Assert.IsTrue(unsavedRebakedNavMeshData == null, "An unsaved NavMeshData should not exist after a re-bake."); Assert.IsTrue(prefabVariantSurface.navMeshData != null, "NavMeshSurface must have NavMeshData after baking."); PrefabSavingUtil.SavePrefab(prefabVariantStage); var theNewVariantNavMeshData = prefabVariantSurface.navMeshData; var theNewVariantAssetPath = AssetDatabase.GetAssetPath(theNewVariantNavMeshData); Assert.IsTrue(File.Exists(theNewVariantAssetPath), "Variant's own NavMeshData exists in a file after saving. ({0})", theNewVariantAssetPath); Assert.IsTrue(File.Exists(theOriginalPrefabAssetPath), "NavMeshData file of the original prefab still exists after saving the variant. ({0})", theOriginalPrefabAssetPath); Assert.IsTrue(theOriginalPrefabNavMeshData != null, "Original prefab must still have NavMeshData."); StageUtility.GoToMainStage(); yield return(null); }
internal static void UpdateAllMockups() { //When building, the scene may open-close multiple times and brought back the mockup canvas, //which combined with bugs mentioned at https://github.com/5argon/NotchSolution/issues/11, //will fail the build. This `if` prevents mockup refresh while building. if (BuildPipeline.isBuildingPlayer) { return; } EnsureCanvasAndEventSetup(); //Make the editing environment contains an another copy of mockup canvas. var prefabStage = PrefabStageUtility.GetCurrentPrefabStage(); if (prefabStage != null) { EnsureCanvasAndEventSetup(prefabStage: prefabStage); } var settings = Settings.Instance; bool enableSimulation = settings.EnableSimulation; var selectedDevice = SimulationDatabase.ByIndex(Settings.Instance.ActiveConfiguration.DeviceIndex); bool landscape = Settings.Instance.ActiveConfiguration.Orientation == PreviewOrientation.LandscapeLeft || Settings.Instance.ActiveConfiguration.Orientation == PreviewOrientation.LandscapeRight; if (enableSimulation && selectedDevice != null) { var screen = selectedDevice.Screens.FirstOrDefault(); GameViewResolution.SetResolution(landscape ? screen.height : screen.width, landscape ? screen.width : screen.height, Settings.Instance.ActiveConfiguration.GameViewSize == GameViewSizePolicy.MatchAspectRatio); var name = selectedDevice.Meta.overlay; Sprite mockupSprite = null; if (!string.IsNullOrEmpty(name)) { var filePath = Path.Combine(NotchSimulatorUtility.DevicesFolder, name); mockupSprite = AssetDatabase.LoadAssetAtPath <Sprite>(filePath); if (mockupSprite == null) { if (System.IO.File.Exists(filePath)) { Texture2D tex = new Texture2D(1, 1); tex.LoadImage(System.IO.File.ReadAllBytes(filePath)); mockupSprite = Sprite.Create(tex, new Rect(0.0f, 0.0f, tex.width, tex.height), new Vector2(0.5f, 0.5f), 100.0f); } else { Debug.LogWarning($"No mockup image named {name} in {NotchSimulatorUtility.DevicesFolder} folder!"); } } } foreach (var mockup in AllMockupCanvases) { mockup.UpdateMockupSprite( sprite: mockupSprite, orientation: NotchSimulatorUtility.GetGameViewOrientation(), simulate: enableSimulation, flipped: settings.FlipOrientation, prefabModeOverlayColor: Settings.Instance.PrefabModeOverlayColor ); } } else { DestroyHiddenCanvas(); GameViewResolution.ClearResolution(); } }
public void OnDrawGizmos() { if (Event.current.type == EventType.Repaint) { if (this.line == null) { return; } if (!Application.isPlaying) { if (PrefabStageUtility.GetCurrentPrefabStage() != null && this.TrainHandler == null) { this.line.material = Board.Instance.EditorPreset.MaterialTrackError; return; } if (this.HandAtEnd != null && this.HandAtBeginning != null) { this.line.material = Board.Instance.EditorPreset.MaterialTrackValid; } else { this.line.material = Board.Instance.EditorPreset.MaterialTrackNotConnected; } } Vector3 offset1 = Vector3.up * 10; Vector3 offset2 = Vector3.up * 10 + Vector3.left * 100; // if we're not on a prefab and the track is a world track // if (((PrefabStageUtility.GetCurrentPrefabStage() != null && !this.IsWorldTrack) || (PrefabStageUtility.GetCurrentPrefabStage() == null && this.IsWorldTrack))) { // display beginning of track GUIContent contentBegin = new GUIContent(name + " START"); GUIStyle styleBegin = new GUIStyle(GUI.skin.box); styleBegin.alignment = TextAnchor.MiddleCenter; Vector2 sizeBegin = styleBegin.CalcSize(contentBegin); Vector3 posBegin = this.line.GetPosition(0); if (!this.IsWorldTrack) { this.TrainHandler.transform.TransformPoint(posBegin); } Handles.BeginGUI(); Vector2 pos2DBegin = HandleUtility.WorldToGUIPoint(posBegin) - Vector2.up * 30; GUI.Box(new Rect(pos2DBegin.x - (sizeBegin.x + 20) / 2.0f, pos2DBegin.y - 10, sizeBegin.x + 20, sizeBegin.y + 10), contentBegin, styleBegin); Handles.EndGUI(); // display end of track GUIContent contentEnd = new GUIContent(name + " END"); GUIStyle styleEnd = new GUIStyle(GUI.skin.box); styleEnd.alignment = TextAnchor.MiddleCenter; Vector2 sizeEnd = styleEnd.CalcSize(contentEnd); Vector3 posEnd = this.line.GetPosition(this.line.positionCount - 1); if (!this.IsWorldTrack) { this.TrainHandler.transform.TransformPoint(posEnd); } Handles.BeginGUI(); Vector2 pos2DEnd = HandleUtility.WorldToGUIPoint(posEnd) - Vector2.up * 30; GUI.Box(new Rect(pos2DEnd.x - (sizeEnd.x + 20) / 2.0f, pos2DEnd.y - 10, sizeEnd.x + 20, sizeEnd.y + 10), contentEnd, styleEnd); Handles.EndGUI(); //Handles.Label(this.line.GetPosition(0) + offset1, name + " START", new GUIStyle() { fontSize = 12, }); //Handles.Label(this.line.GetPosition(this.line.positionCount - 1) + offset2, name + " END", new GUIStyle() { fontSize = 12 }); } if (Application.isPlaying && PrefabStageUtility.GetCurrentPrefabStage() == null && this.IsWorldTrack) { // draw the number of train label GUIContent content = new GUIContent(this.CurrentCrossingTrains.Count.ToString()); GUIStyle style = new GUIStyle(GUI.skin.box); style.alignment = TextAnchor.MiddleCenter; Vector2 size = style.CalcSize(content); int position = this.line.positionCount / 2; Vector3 pos = this.line.GetPosition(position); if (!this.IsWorldTrack) { this.TrainHandler.transform.TransformPoint(pos); } if (this.line.positionCount == 2) { pos = (line.GetPosition(1) + line.GetPosition(0)) / 2; } Handles.BeginGUI(); Vector2 pos2D = HandleUtility.WorldToGUIPoint(pos) - Vector2.up * 30; GUI.Box(new Rect(pos2D.x - 10, pos2D.y - 10, 2.0f * size.x, size.y + 10), content, style); Handles.EndGUI(); } } }
public bool IsEditingAPrefabAsset() { var stage = PrefabStageUtility.GetCurrentPrefabStage(); return(stage != null && editSequence.director != null && stage.IsPartOfPrefabContents(editSequence.director.gameObject)); }
public void OnSceneGUI() { if (this._target.line == null) { return; } if (PrefabStageUtility.GetCurrentPrefabStage() != null && this._target.TrainHandler == null) { return; } if (PrefabStageUtility.GetCurrentPrefabStage() == null && !this._target.line.useWorldSpace) { return; } Vector3 offset1 = Vector3.up * 10; //get the position of the line point Vector3 positionStart = _target.line.GetPosition(0); Vector3 positionStop = _target.line.GetPosition(_target.line.positionCount - 1); //if the line is object space (!= worldspace) then we have to calculte the world space Vector3 calculatedWorldSpacePositionStart = Vector3.zero; Vector3 calculatedWorldSpacePositionStop = Vector3.zero; if (!this._target.line.useWorldSpace) { calculatedWorldSpacePositionStart = _target.TrainHandler.transform.TransformPoint(positionStart); calculatedWorldSpacePositionStop = _target.TrainHandler.transform.TransformPoint(positionStop); } if (_target.line.positionCount > 1) { Vector3 positionHandlePositionStart; Vector3 positionHandlePositionStop; if (_target.line.useWorldSpace) { positionHandlePositionStart = positionStart; positionHandlePositionStop = positionStop; } else { positionHandlePositionStart = calculatedWorldSpacePositionStart; positionHandlePositionStop = calculatedWorldSpacePositionStop; } //get the new world space position of the handle Vector3 newPositionHandlePositionStart = Handles.PositionHandle(positionHandlePositionStart, Quaternion.identity); Vector3 newPositionHandlePositionStop = Handles.PositionHandle(positionHandlePositionStop, Quaternion.identity); //if the line is object space (!= worldspace) then we have to calculte the object space to set the new position Vector3 newCalculatedObjectSpacePositionStart = Vector3.zero; Vector3 newCalculatedObjectSpacePositionStop = Vector3.zero; if (!this._target.line.useWorldSpace) { newCalculatedObjectSpacePositionStart = _target.TrainHandler.transform.InverseTransformPoint(newPositionHandlePositionStart); newCalculatedObjectSpacePositionStop = _target.TrainHandler.transform.InverseTransformPoint(newPositionHandlePositionStop); } Vector3 newPositionStart; Vector3 newPositionStop; if (_target.line.useWorldSpace) { newPositionStart = newPositionHandlePositionStart; newPositionStop = newPositionHandlePositionStop; } else { newPositionStart = newCalculatedObjectSpacePositionStart; newPositionStop = newCalculatedObjectSpacePositionStop; } HandleUtility.AddControl(0, 1); HandleUtility.AddControl(1, 1); Handles.color = Color.magenta; Handles.SphereHandleCap(0, positionHandlePositionStart, Quaternion.identity, Board.Instance.EditorPreset.TrackBallSize, EventType.Repaint); Handles.SphereHandleCap(1, positionHandlePositionStop, Quaternion.identity, Board.Instance.EditorPreset.TrackBallSize, EventType.Repaint); Vector3 diff = newPositionStop - _target.line.GetPosition(_target.line.positionCount - 2); if (newPositionStart != positionStart) { this._target.Disconnect(true); bool snapped = false; //detect if another handle is nearby ? if (this._target.TrainHandler != null) { if (this._target.TrainHandler.TrainHandlerType == TrainHandlerType.Card) { //if the trainhandler is a card, it means that we should stick to the hand of the card only ! foreach (Hand hand in this._target.TrainHandler.AllHands) { //if the the hand is not already occupied if (hand.TrainHandler != null) { float dist; dist = ((Vector2)hand.transform.position - (Vector2)newPositionHandlePositionStart).magnitude; if (dist < Board.Instance.EditorPreset.HandSnapDistance) { Undo.RecordObject(this._target, "TrackSnap change"); //Debug.Log(dist + " " + hand); this._target.ConnectToHand(hand, true, true); snapped = true; /*SerializedObject obj = new SerializedObject(this._target); * obj.FindProperty("_handAtBeginning").objectReferenceValue = hand; * obj.ApplyModifiedProperties(); * Undo.RecordObject(this._target, "Changing the component on myObject");*/ } } } } } else { //if there is not train handler, it means that we should stick to the hand of a box only ! foreach (Box box in Board.Instance.Boxes) { foreach (Hand hand in box.AllHands) { //if the the hand is not already occupied if (hand.TrainHandler != null) { float dist = ((Vector2)hand.transform.position - (Vector2)newPositionStart).magnitude; if (dist < Board.Instance.EditorPreset.HandSnapDistance) { Undo.RecordObject(this._target, "TrackSnap change"); //Debug.Log(dist + " " + hand); this._target.ConnectToHand(hand, true, true); snapped = true; } } } } } if (!snapped) { this._target.line.SetPosition(0, newPositionStart); } else { EditorUtility.SetDirty(this._target.gameObject); PrefabUtility.RecordPrefabInstancePropertyModifications(this._target); if (PrefabStageUtility.GetCurrentPrefabStage() == null) { //EditorSceneManager.MarkSceneDirty(this._target.gameObject.scene); //This used to happen automatically from SetDirty } } } if (newPositionStop != positionStop) { this._target.Disconnect(false); bool snapped = false; //detect if another handle is nearby ? if (this._target.TrainHandler != null) { if (this._target.TrainHandler.TrainHandlerType == TrainHandlerType.Card) { //if the trainhandler is a card, it means that we should stick to the hand of the card only ! foreach (Hand hand in this._target.TrainHandler.AllHands) { //if the the hand is not already occupied if (hand.TrainHandler != null) { float dist; dist = ((Vector2)hand.transform.position - (Vector2)newPositionHandlePositionStop).magnitude; if (dist < Board.Instance.EditorPreset.HandSnapDistance) { Undo.RecordObject(this._target, "TrackSnap change"); //Debug.Log(dist + " " + hand); this._target.ConnectToHand(hand, false, true); snapped = true; } } } } } else { //if there is not train handler, it means that we should stick to the hand of a box only ! foreach (Box box in Board.Instance.Boxes) { if (box != null) { foreach (Hand hand in box.AllHands) { //if the the hand is not already occupied if (hand.TrainHandler != null) { float dist = ((Vector2)hand.transform.position - (Vector2)newPositionStop).magnitude; if (dist < Board.Instance.EditorPreset.HandSnapDistance) { Undo.RecordObject(this._target, "TrackSnap change"); //Debug.Log(dist + " " + hand); this._target.ConnectToHand(hand, false, true); snapped = true; } } } } } } if (!snapped) { this._target.line.SetPosition(this._target.line.positionCount - 1, newPositionStop); } else { EditorUtility.SetDirty(this._target.gameObject); PrefabUtility.RecordPrefabInstancePropertyModifications(this._target); if (PrefabStageUtility.GetCurrentPrefabStage() == null) { //EditorSceneManager.MarkSceneDirty(this._target.gameObject.scene); //This used to happen automatically from SetDirty } } } } }
public static bool FindMissingReferencesInCurrentPrefabValidate() => PrefabStageUtility.GetCurrentPrefabStage() != null;
private static bool CanRemoveFromCurrentPrefab() { return(PrefabStageUtility.GetCurrentPrefabStage() != null); }
public static bool IsPrefabMode() { return(PrefabStageUtility.GetCurrentPrefabStage() != null); }
public static bool TryGetCurrentPrefabStage(out PrefabStage prefabStage) { prefabStage = PrefabStageUtility.GetCurrentPrefabStage(); return(prefabStage != null); }
public override void OnInspectorGUI() { serializedObject.Update(); var doReimport = false; GUILayout.Label("Import", EditorStyles.boldLabel); if (modelGroup.autoGenerated) { EditorGUILayout.HelpBox("This group was changed by brick building since import. You can only reimport the entire model.", MessageType.Info); } else { EditorGUILayout.LabelField("Number", modelGroup.number.ToString()); EditorGUILayout.LabelField("Name", modelGroup.groupName); EditorGUILayout.LabelField("Colliders", modelGroup.importSettings.colliders.ToString()); EditorGUILayout.LabelField("Connectivity", modelGroup.importSettings.connectivity.ToString()); EditorGUILayout.LabelField("Static", modelGroup.importSettings.isStatic.ToString()); EditorGUILayout.LabelField("Lightmapped", modelGroup.importSettings.lightmapped.ToString()); EditorGUILayout.LabelField("Randomized Rotations", modelGroup.importSettings.randomizeRotation.ToString()); EditorGUILayout.LabelField("LOD", modelGroup.importSettings.lod.ToString()); GUILayout.Space(16); // Check if part of prefab instance and prevent reimport. if (PrefabUtility.IsPartOfAnyPrefab(target)) { EditorGUILayout.HelpBox("You cannot reimport a prefab instance. Please perform reimporting on the prefab itself.", MessageType.Warning); } else { if (File.Exists(modelGroup.relativeFilePath) || File.Exists(modelGroup.absoluteFilePath)) { doReimport = GUILayout.Button("Reimport"); } else { EditorGUILayout.HelpBox("Could not find original file. Select model and reimport from a new file.", MessageType.Warning); } } } var doProcessing = false; GUILayout.Space(16); GUILayout.Label("Processing", EditorStyles.boldLabel); if (processedProp.boolValue) { EditorGUILayout.HelpBox("Already Processed", MessageType.Info); } else { EditorGUILayout.PropertyField(optimizationsProp); // Backface culling and geometry removal UI, and sorting UI. if (((ModelGroup.Optimizations)optimizationsProp.intValue & (ModelGroup.CameraBasedGeometryRemovalOptimizations | ModelGroup.Optimizations.SortFrontToBack)) != 0) { var geometryRemoval = ((ModelGroup.Optimizations)optimizationsProp.intValue & ModelGroup.CameraBasedGeometryRemovalOptimizations) != 0; var sorting = ((ModelGroup.Optimizations)optimizationsProp.intValue & ModelGroup.Optimizations.SortFrontToBack) != 0; var message = ""; if (geometryRemoval) { message += "Backface culling and geometry removal are based on all the specified views.\n"; } if (sorting) { message += "Front-to-back geometry sorting is based on the first specified view."; } EditorGUILayout.HelpBox(message, MessageType.Info); if (viewsProp.arraySize == 0 && Camera.main) { var warning = "No views have been specified.\n"; if (geometryRemoval) { warning += "View from current main camera will be used when doing backface culling and geometry removal.\n"; } if (sorting) { warning += "View from current main camera will be used when sorting geometry."; } EditorGUILayout.HelpBox(warning, MessageType.Warning); } else if (viewsProp.arraySize == 0) { if (geometryRemoval || sorting) { var error = "No views have been specified.\n"; if (geometryRemoval) { error += "Could not find main camera to use when doing backface culling and geometry removal.\n"; } if (sorting) { error += "Could not find main camera to use when sorting geometry."; } EditorGUILayout.HelpBox(error, MessageType.Error); } } if (otherGroupViews.Count > 0) { showOtherGroups = EditorGUILayout.Foldout(showOtherGroups, "Views From Other Groups", true); if (showOtherGroups) { foreach (var group in otherGroupViews.Keys) { if (GUILayout.Button("Add Views From " + group.parentName + " " + group.groupName)) { foreach (var groupView in otherGroupViews[group]) { AddView(groupView); } } } } } if (lightViews.Count > 0) { showLights = EditorGUILayout.Foldout(showLights, "Views From Lights", true); if (showLights) { foreach (var light in lightViews.Keys) { if (GUILayout.Button("Add View From " + light.name)) { AddView(lightViews[light]); } } } } if (cameraViews.Count > 0) { showCameras = EditorGUILayout.Foldout(showCameras, "Views From Cameras", true); if (showCameras) { foreach (var camera in cameraViews.Keys) { if (GUILayout.Button("Add View From " + camera.name)) { AddView(cameraViews[camera]); } } } } if (GUILayout.Button("Add Current Scene Views")) { foreach (var sceneView in SceneView.sceneViews) { var sceneViewCamera = ((SceneView)sceneView).camera; viewsProp.arraySize++; var newEntry = viewsProp.GetArrayElementAtIndex(viewsProp.arraySize - 1); newEntry.FindPropertyRelative("name").stringValue = sceneViewCamera.name; newEntry.FindPropertyRelative("perspective").boolValue = !sceneViewCamera.orthographic; newEntry.FindPropertyRelative("position").vector3Value = sceneViewCamera.transform.position; newEntry.FindPropertyRelative("rotation").quaternionValue = sceneViewCamera.transform.rotation; newEntry.FindPropertyRelative("size").floatValue = sceneViewCamera.orthographicSize; newEntry.FindPropertyRelative("fov").floatValue = sceneViewCamera.fieldOfView; newEntry.FindPropertyRelative("aspect").floatValue = sceneViewCamera.aspect; newEntry.FindPropertyRelative("minRange").floatValue = sceneViewCamera.nearClipPlane; newEntry.FindPropertyRelative("maxRange").floatValue = sceneViewCamera.farClipPlane; } } if (viewsProp.arraySize > 0) { EditorList.Show(viewsProp, EditorListOption.All);//, new GUIContent[] { new GUIContent("Z", "View From") }, new System.Action<SerializedProperty>[] { (p) => ViewFrom(p) }); } } GUILayout.Space(16); EditorGUILayout.PropertyField(randomizeNormalsProp, new GUIContent("Add Noise To Normals", "A small amount of noise adds visual detail.")); /* GUILayout.Space(16); * EditorGUILayout.PropertyField(imperfectionsProp); * * // Imperfections UI. * if (((ModelGroup.Imperfections)imperfectionsProp.intValue & ModelGroup.Imperfections.UVDegradation) == ModelGroup.Imperfections.UVDegradation) * { * EditorGUILayout.HelpBox("UV degradation has not been implemented yet.", MessageType.Warning); * } * if (((ModelGroup.Imperfections)imperfectionsProp.intValue & ModelGroup.Imperfections.Scratches) == ModelGroup.Imperfections.Scratches) * { * EditorGUILayout.HelpBox("Scratches have not been implemented yet.", MessageType.Warning); * }*/ GUILayout.Space(16); if (PrefabUtility.IsPartOfAnyPrefab(target)) { EditorGUILayout.HelpBox("You cannot process a prefab instance. Please perform processing on the prefab itself.", MessageType.Warning); } else { // Process button. doProcessing = GUILayout.Button("Process"); if (doProcessing) { Undo.RegisterFullObjectHierarchyUndo(modelGroup.gameObject, "Process"); processedProp.boolValue = true; } } } serializedObject.ApplyModifiedProperties(); if (doReimport) { // FIXME Issue with finding the correct group when multiple groups have same name and group number has changed! ImportModel.ReimportModelGroup(modelGroup); } if (doProcessing) { Vector2Int vertCount = Vector2Int.zero; Vector2Int triCount = Vector2Int.zero; Vector2Int meshCount = Vector2Int.zero; Vector2Int boxColliderCount = Vector2Int.zero; ModelProcessor.ProcessModelGroup(modelGroup, ref vertCount, ref triCount, ref meshCount, ref boxColliderCount); Debug.Log($"Process result (before/after):\nVerts {vertCount.x}/{vertCount.y}, tris {triCount.x}/{triCount.y}, meshes {meshCount.x}/{meshCount.y}, box colliders {boxColliderCount.x}/{boxColliderCount.y}"); var prefabStage = PrefabStageUtility.GetCurrentPrefabStage(); if (prefabStage != null) { EditorSceneManager.MarkSceneDirty(prefabStage.scene); } } }
public override void OnInspectorGUI() { var t = (AudioLinkAutoConfigurator)target; // if we are in SCENE VIEW - self-destruct if (PrefabStageUtility.GetCurrentPrefabStage() == null && valuesSet) { DestroyImmediate(t); return; } base.OnInspectorGUI(); if (PrefabStageUtility.GetCurrentPrefabStage() == null) { EditorGUILayout.LabelField("This script can be safely removed", new GUIStyle("helpBox")); } // if we are in PREFAB EDIT mode - we keep the configurator #if UDON if (PrefabStageUtility.GetCurrentPrefabStage() != null) { // if you somehow end up with an udon behaviour and other world-speicifc scripts inside the prefab // this button can clean it up before the publish if (GUILayout.Button("Clean up for prefab publishing")) { var uBtoRemove = t.gameObject.GetComponent <UdonBehaviour>(); if (uBtoRemove) { DestroyImmediate(uBtoRemove); } var spatialSource = t.audioSource.gameObject.GetComponent <VRCSpatialAudioSource>(); if (spatialSource) { DestroyImmediate(spatialSource); } var avpro = t.audioSource.gameObject.GetComponent <VRCAVProVideoSpeaker>(); if (avpro) { DestroyImmediate(avpro); } } } #endif // this gets the AudioLink MonoBehaviour in AVATAR projects and sets the important references var aL = t.gameObject.GetComponent <AudioLink>(); if (!aL) { return; } var sO = new SerializedObject(aL); // we look up all the properties that have to be set // this uses unity's SerializedProperty syntax var audioMaterial = sO.FindProperty("audioMaterial"); var audioMaterialInLeft = sO.FindProperty("audioMaterialInLeft"); var audioMaterialInRight = sO.FindProperty("audioMaterialInRight"); var audioTextureExport = sO.FindProperty("audioTextureExport"); var audioData2D = sO.FindProperty("audioData2D"); var audioSource = sO.FindProperty("audioSource"); var audioDataToggle = sO.FindProperty("audioDataToggle"); // once we get the properties, we can set them to saved values same way as we do for WORLD code audioMaterial.objectReferenceValue = t.audioMaterial; audioMaterialInLeft.objectReferenceValue = t.audioMaterialInLeft; audioMaterialInRight.objectReferenceValue = t.audioMaterialInRight; audioTextureExport.objectReferenceValue = t.audioTextureExport; audioData2D.objectReferenceValue = t.audioData2d; audioSource.objectReferenceValue = t.audioSource; audioDataToggle.boolValue = false; sO.ApplyModifiedProperties(); valuesSet = true; }
internal static void BeginToEditHeadColliders() { Init(); var root = GetPrefabRootVRM(); if (root == null) { return; } var head = FindByName("J_Bip_C_Head"); if (head == null) { throw new Exception("J_Bip_C_Head が見つかりません"); } var stage = PrefabStageUtility.GetCurrentPrefabStage(); if (stage == null) { return; } // 半透明の顔が既にある場合は表示 var dummyFace = FindByName("_DummyFace_"); if (dummyFace != null) { dummyFace.SetActive(true); } // 全メッシュを隠し、半透明の顔を作成 foreach (var cmp in root.GetComponentsInChildren <SkinnedMeshRenderer>(true)) { var obj = cmp.gameObject; var isFace = obj.name == "Face"; var isHair = obj.name.StartsWith("Hair"); var isBody = obj.name == "Body"; if (isFace && dummyFace == null) { // 顔を複製 dummyFace = Instantiate(obj); dummyFace.transform.parent = obj.transform.parent; dummyFace.name = "_DummyFace_"; dummyFace.hideFlags = HideFlags.DontSave; // 半透明化 var mesh = dummyFace.GetComponent <SkinnedMeshRenderer>(); var noopShader = Shader.Find("VRoidTuner/Noop"); for (var i = 0; i < mesh.materials.Length; i++) { var mat = mesh.materials[i]; if (mat.name.Contains("_Face_")) { var c = mat.GetColor("_Color"); c.a = 0.5f; mat.SetColor("_Color", c); mat.SetFloat("_BlendMode", (float)MToon.RenderMode.Transparent); MToon.Utils.ValidateBlendMode(mat, MToon.RenderMode.Transparent, true); } else { mat.shader = noopShader; } } } if (isFace || isHair || isBody) { obj.SetActive(false); } } var clds = FindByName("_Colliders_"); if (clds != null) { // 球を再表示 clds.SetActive(true); } else { var mat = AssetDatabase.LoadAssetAtPath <Material>("Assets/VRoidTuner/Materials/VRoidTunerGizmoMaterial.mat"); // 球を格納するための親を作成 clds = new GameObject("_Colliders_"); clds.transform.parent = head.transform; clds.hideFlags = HideFlags.DontSave; clds.transform.localPosition = new Vector3(); clds.transform.localScale = Vector3.one; int i = 0; var cgrp = head.GetComponent <VRMSpringBoneColliderGroup>(); if (cgrp == null) { throw new Exception("J_Bip_C_Head に VRMSpringBoneColliderGroup がアタッチされていません"); } foreach (var cld in cgrp.Colliders) { // 球を作成 var sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); sphere.transform.parent = clds.transform; sphere.hideFlags = HideFlags.DontSave; sphere.name = String.Format("Collider{0:000}", i); if (mat != null) { var mesh = sphere.GetComponent <MeshRenderer>(); mesh.material = mat; // mesh.material.color = Helper.GizmoColor(i); } var s = cld.Radius * 2; sphere.transform.localScale = new Vector3(s, s, s); sphere.transform.localPosition = cld.Offset; i++; } } Selection.activeGameObject = clds.GetComponentInChildren <MeshRenderer>().gameObject ?? clds; }
public static void UpdateOrderedSelection() { /* PreviousSelectionStack.Clear(); * PreviousSelectionStack.AddRange(Selection.objects);*/ if (Selection.objects.Length > 0) { PreviousSelectionStack.Clear(); PreviousSelectionStack.AddRange(Selection.objects); } if (Selection.objects == null) { SelectionStack.Clear(); return; } EditorUtility.ClearProgressBar(); if (!MonKeyInternalSettings.Instance || !MonKeyInternalSettings.Instance.UseSortedSelection) { return; } if (Selection.objects.Length > MonKeyInternalSettings.Instance.MaxSortedSelectionSize && MonKeyInternalSettings.Instance.ShowSortedSelectionWarning) { Debug.Log("MonKey Info: " + "You selected more objects than the limit set in settings for the maximum amount of ordered objects:" + " the selection's order won't be guaranteed. "); Debug.Log("...You can change that amount in the settings, but keep in mind that trying to " + "used ordered selection on large amount of objects will require some " + "calculation time."); Debug.Log("You can disable that warning in the settings as well."); SelectionStack.Clear(); SelectionStack.AddRange(Selection.objects); return; } if (Selection.objects.Length > 50) { EditorUtility.DisplayProgressBar("MonKey Is Updating Ordered Selection, Please Wait", "Making sure the selection is properly ordered. If this is getting too long, you can deactivate that ", 0.5f); } //if there is a current selection and it has only one object now or none, //then the selection can be considered changed and we can store the previous selection if (Selection.objects.Length <= 1) { if (SelectionStack.Count >= 1) { SelectionStack.Clear(); } if (Selection.objects.IsEmpty()) { CurrentSelectionCount = 0; LastGOSelected = null; } else { SelectionStack.AddRange(Selection.objects); CurrentSelectionCount = 1; if (Selection.objects[0] is GameObject) { LastGOSelected = (GameObject)Selection.objects[0]; } } } else { //in that case we need to check the differences and adjust the ordered selection accordingly if (Selection.objects.Length <= CurrentSelectionCount) { //if so, it means that some objects were removed, //we need to check which ones and remove them for (int j = SelectionStack.Count - 1; j >= 0; j--) { if (!Selection.objects.Contains(SelectionStack[j])) { SelectionStack.RemoveAt(j); CurrentSelectionCount--; } } } else { //then some objects were added, and must be sorted and added. //We first must find the objects that were added List <GameObject> newGOs = new List <GameObject>(); List <Object> newAssets = new List <Object>(); for (int j = 0; j < Selection.objects.Length; j++) { var obj = Selection.objects[j]; if (!SelectionStack.Contains(obj)) { var go = obj as GameObject; bool isPrefabStage = PrefabStageUtility.GetCurrentPrefabStage() != null; if (go && (go.scene.IsValid() || (isPrefabStage && PrefabStageUtility.GetCurrentPrefabStage().scene == go.scene))) { newGOs.Add(go); } else { newAssets.Add(obj); } } } CurrentSelectionCount += newGOs.Count + newAssets.Count; newAssets.Sort(new NamingUtilities.ObjectComparer()); List <GameObject> orderedObjects = new List <GameObject>(); Dictionary <GameObject, List <int> > orderIDs = new Dictionary <GameObject, List <int> >(orderedObjects.Count); List <int> idsOfLastSelected = new List <int>(); //now we need to determine the order for (int i = 0; i < newGOs.Count; i++) { var obj = newGOs[i]; orderIDs.Add(obj, new List <int>()); var parentTransform = obj.transform.parent; orderIDs[obj].Add(obj.transform.GetSiblingIndex()); if (parentTransform) { while (parentTransform) { if (orderIDs[obj].Count > 0) { orderIDs[obj].Insert(0, parentTransform.GetSiblingIndex()); } else { orderIDs[obj].Add(parentTransform.GetSiblingIndex()); } parentTransform = parentTransform.parent; } } } if (LastGOSelected) { var lastParentTransform = LastGOSelected.transform.parent; if (!lastParentTransform) { idsOfLastSelected.Add(LastGOSelected.transform.GetSiblingIndex()); } else { while (lastParentTransform) { idsOfLastSelected.Add(lastParentTransform.GetSiblingIndex()); lastParentTransform = lastParentTransform.parent; } } } //now that we have all the orders computed, we can order the objects for (int i = 0; i < newGOs.Count; i++) { if (orderedObjects.Count == 0) { orderedObjects.Add(newGOs[i]); } else { int insertID = -1; var newGo = newGOs[i]; var newIds = orderIDs[newGo]; for (int j = 0; j < orderedObjects.Count; j++) { var ids = orderIDs[orderedObjects[j]]; for (int k = 0; k < ids.Count; k++) { if (newIds.Count <= k) { break; } int newID = newIds[k]; if (ids[k] > newID) { //then we can insert before insertID = j; break; } if (ids[k] == newID) { //then we need to check further, or if there isn't left just add right after if (k == ids.Count - 1) { break; } if (newIds.Count == k + 1) { //this means it's the parent of the object insertID = j; break; } } else { // then we are after, and can break to compare to the next one break; } } if (insertID != -1) { break; } } if (insertID != -1 && insertID < orderedObjects.Count) { orderedObjects.Insert(insertID, newGOs[i]); } else { orderedObjects.Add(newGOs[i]); } } } bool top = false; for (int i = 0; i < idsOfLastSelected.Count; i++) { if (orderedObjects.Count == 0) { break; } var list = orderIDs[orderedObjects[0]]; if (list.Count <= i) { break; } if (idsOfLastSelected[i] < list[i]) { top = true; break; } if (idsOfLastSelected[i] > list[i]) { top = false; break; } } if (!top) { orderedObjects.Reverse(); } //now that we have our ordered game objects, we can get the last one , and add the assets, and be done! if (orderedObjects.Count > 0) { LastGOSelected = orderedObjects.Last(); } SelectionStack.AddRange(orderedObjects.Convert(_ => _ as Object)); SelectionStack.AddRange(newAssets); } } EditorUtility.ClearProgressBar(); }
private static void HierarchyWindowListElementOnGUI(int instanceID, Rect selectionRect) { if (EditorApplication.isPlayingOrWillChangePlaymode || !VCSettings.HierarchyIcons || !VCCommands.Active) { return; } var obj = EditorUtility.InstanceIDToObject(instanceID); if (obj == null) { string sceneAssetPath = SceneManagerUtilities.GetSceneAssetPathFromHandle(instanceID); if (!string.IsNullOrEmpty(sceneAssetPath)) { VCUtility.RequestStatus(sceneAssetPath, VCSettings.HierarchyReflectionMode); DrawIcon(selectionRect, IconUtils.rubyIcon, sceneAssetPath, null, -20f); } } else { var currentPrefabStage = PrefabStageUtility.GetCurrentPrefabStage(); if (currentPrefabStage != null) { var go = obj as GameObject; if (go) { if (PrefabStageUtility.GetCurrentPrefabStage().prefabContentsRoot == go) { DrawIcon(selectionRect, IconUtils.squareIcon, PrefabStageUtility.GetCurrentPrefabStage().assetPath, PrefabStageUtility.GetCurrentPrefabStage().prefabContentsRoot, 0f); } } } } }
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) { // Skip if all imported and deleted assets are addressables configurations. var isConfigurationPass = (importedAssets.Length > 0 && importedAssets.All(x => x.StartsWith("Assets/AddressableAssetsData"))) && (deletedAssets.Length > 0 && deletedAssets.All(x => x.StartsWith("Assets/AddressableAssetsData"))); if (isConfigurationPass) { return; } var settings = AddressableAssetSettingsDefaultObject.Settings; if (settings == null) { Debug.LogWarningFormat("[Addressables] settings file not found.\nPlease go to Menu/Window/Asset Management/Addressables, then click 'Create Addressables Settings' button."); return; } var importSettings = AddressableImportSettings.Instance; if (importSettings == null) { Debug.LogWarningFormat("[AddressableImporter] import settings file not found.\nPlease go to Assets/AddressableAssetsData folder, right click in the project window and choose 'Create > Addressable Assets > Import Settings'."); return; } if (importSettings.rules == null || importSettings.rules.Count == 0) { return; } var dirty = false; // Apply import rules. var prefabStage = PrefabStageUtility.GetCurrentPrefabStage(); foreach (var importedAsset in importedAssets) { if (prefabStage == null || prefabStage.prefabAssetPath != importedAsset) // Ignore current editing prefab asset. { dirty |= ApplyImportRule(importedAsset, null, settings, importSettings); } } for (var i = 0; i < movedAssets.Length; i++) { var movedAsset = movedAssets[i]; var movedFromAssetPath = movedFromAssetPaths[i]; if (prefabStage == null || prefabStage.prefabAssetPath != movedAsset) // Ignore current editing prefab asset. { dirty |= ApplyImportRule(movedAsset, movedFromAssetPath, settings, importSettings); } } foreach (var deletedAsset in deletedAssets) { if (TryGetMatchedRule(deletedAsset, importSettings, out var matchedRule)) { var guid = AssetDatabase.AssetPathToGUID(deletedAsset); if (!string.IsNullOrEmpty(guid) && settings.RemoveAssetEntry(guid)) { dirty = true; Debug.LogFormat("[AddressableImporter] Entry removed for {0}", deletedAsset); } } } if (dirty) { AssetDatabase.SaveAssets(); } }
public virtual void SetUpSheet() { Infos = new SpriteData(); Infos.List = new List <List <List <SpriteInfo> > >(); for (int i = 0; i < spriteList.Count; i++) { Infos.List.Add(new List <List <SpriteInfo> >()); var path = AssetDatabase.GetAssetPath(spriteList[i]) .Substring(17); //Substring(17) To remove the "Assets/Resources/" Sprite[] spriteSheetSprites = Resources.LoadAll <Sprite>(path.Remove(path.Length - 4)); if (spriteSheetSprites.Length > 1) { var p = AssetDatabase.GetAssetPath(spriteList[i]); int extensionIndex = p.LastIndexOf("."); p = p.Substring(0, extensionIndex) + ".json"; string json = System.IO.File.ReadAllText(p); Logger.Log(json.ToString()); spriteJson = JsonConvert.DeserializeObject <SpriteJson>(json); int c = 0; int cone = 0; for (int J = 0; J < spriteJson.Number_Of_Variants; J++) { Infos.List[i].Add(new List <SpriteInfo>()); } foreach (var SP in spriteSheetSprites) { var info = new SpriteInfo(); info.sprite = SP; if (spriteJson.Delays.Count > 0) { info.waitTime = spriteJson.Delays[c][cone]; } Infos.List[i][c].Add(info); if (c >= (spriteJson.Number_Of_Variants - 1)) { c = 0; cone++; } else { c++; } } } else { var info = new SpriteInfo() { sprite = spriteSheetSprites[0], waitTime = 0 }; Infos.List[i].Add(new List <SpriteInfo>()); Infos.List[i][0].Add(info); } } Infos.SerializeT(); var IA = this.GetComponent <ItemAttributes>(); if (IA != null) { IA.spriteDataHandler = this; } var prefabStage = PrefabStageUtility.GetCurrentPrefabStage(); if (prefabStage != null) { EditorSceneManager.MarkSceneDirty(prefabStage.scene); Logger.Log("Setup Complete", Category.SpriteHandler); } }
/// <summary> /// MagicaClothの共有データをサブアセットとしてプレハブに保存する /// またすでに不要なサブアセットは削除する /// </summary> /// <param name="prefab"></param> /// <param name="target"></param> /// <param name="prefabPath"></param> static void PrefabUpdate(GameObject prefab, GameObject target, string prefabPath) { //Debug.Log("PrefabUpdate()"); //Debug.Log("prefab name:" + prefab.name); //Debug.Log("prefab id:" + prefab.GetInstanceID()); //Debug.Log("target name:" + target.name); //Debug.Log("target id:" + target.GetInstanceID()); //Debug.Log("prefab path:" + prefabPath); //Debug.Log("IsPersistent:" + EditorUtility.IsPersistent(prefab)); //Debug.Log("AssetDatabase.Contains:" + AssetDatabase.Contains(prefab)); //Debug.Log("IsPartOfModelPrefab:" + PrefabUtility.IsPartOfModelPrefab(prefab)); //Debug.Log("IsPartOfPrefabThatCanBeAppliedTo:" + PrefabUtility.IsPartOfPrefabThatCanBeAppliedTo(prefab)); //Debug.Log("IsPartOfImmutablePrefab:" + PrefabUtility.IsPartOfImmutablePrefab(prefab)); // 編集不可のプレハブならば保存できないため処理を行わない if (PrefabUtility.IsPartOfImmutablePrefab(prefab)) { return; } AssetDatabase.StartAssetEditing(); // 不要な共有データを削除するためのリスト bool change = false; List <ShareDataObject> removeDatas = new List <ShareDataObject>(); // 現在アセットとして保存されているすべてのShareDataObjectサブアセットを削除対象としてリスト化する UnityEngine.Object[] subassets = AssetDatabase.LoadAllAssetRepresentationsAtPath(prefabPath); if (subassets != null) { foreach (var obj in subassets) { // ShareDataObjectのみ ShareDataObject sdata = obj as ShareDataObject; if (sdata) { //Debug.Log("sub asset:" + obj.name + " type:" + obj + " test:" + AssetDatabase.IsSubAsset(sdata)); // 削除対象として一旦追加 removeDatas.Add(sdata); } } } // プレハブ元の共有オブジェクトをサブアセットとして保存する List <ShareDataObject> saveDatas = new List <ShareDataObject>(); var shareDataInterfaces = target.GetComponentsInChildren <IShareDataObject>(true); if (shareDataInterfaces != null) { foreach (var sdataInterface in shareDataInterfaces) { List <ShareDataObject> shareDatas = sdataInterface.GetAllShareDataObject(); if (shareDatas != null) { foreach (var sdata in shareDatas) { if (sdata) { //Debug.Log("share data->" + sdata.name + " prefab?:" + AssetDatabase.Contains(sdata)); //Debug.Log("share data path:" + AssetDatabase.GetAssetPath(sdata)); if (AssetDatabase.Contains(sdata) == false) { // サブアセットとして共有データを追加 //Debug.Log("save sub asset:" + sdata.name); AssetDatabase.AddObjectToAsset(sdata, prefab); change = true; } else if (prefabPath != AssetDatabase.GetAssetPath(sdata)) { // 保存先プレハブが変更されている //Debug.Log("Change prefab!!"); // 共有データのクローンを作成(別データとする) var newdata = sdataInterface.DuplicateShareDataObject(sdata); if (newdata != null) { //Debug.Log("save new data! ->" + newdata); AssetDatabase.AddObjectToAsset(newdata, prefab); change = true; } } removeDatas.Remove(sdata); } } } } } // 不要な共有データは削除する foreach (var sdata in removeDatas) { //Debug.Log("Remove sub asset:" + sdata.name); UnityEngine.Object.DestroyImmediate(sdata, true); change = true; } AssetDatabase.StopAssetEditing(); // 変更を全体に反映 if (change) { //Debug.Log("save!"); // どうもこの手順を踏まないと保存した共有データが正しくアタッチされない if (PrefabStageUtility.GetCurrentPrefabStage() != null) { PrefabUtility.SaveAsPrefabAsset(target, prefabPath); } else { PrefabUtility.SaveAsPrefabAssetAndConnect(target, prefabPath, InteractionMode.AutomatedAction); } } }
public static void Button(UnityEngine.Object target, MethodInfo methodInfo) { bool visible = ButtonUtility.IsVisible(target, methodInfo); if (!visible) { return; } if (methodInfo.GetParameters().All(p => p.IsOptional)) { ButtonAttribute buttonAttribute = (ButtonAttribute)methodInfo.GetCustomAttributes(typeof(ButtonAttribute), true)[0]; string buttonText = string.IsNullOrEmpty(buttonAttribute.Text) ? ObjectNames.NicifyVariableName(methodInfo.Name) : buttonAttribute.Text; bool buttonEnabled = ButtonUtility.IsEnabled(target, methodInfo); EButtonEnableMode mode = buttonAttribute.SelectedEnableMode; buttonEnabled &= mode == EButtonEnableMode.Always || mode == EButtonEnableMode.Editor && !Application.isPlaying || mode == EButtonEnableMode.Playmode && Application.isPlaying; bool methodIsCoroutine = methodInfo.ReturnType == typeof(IEnumerator); if (methodIsCoroutine) { buttonEnabled &= (Application.isPlaying ? true : false); } EditorGUI.BeginDisabledGroup(!buttonEnabled); if (GUILayout.Button(buttonText)) { object[] defaultParams = methodInfo.GetParameters().Select(p => p.DefaultValue).ToArray(); IEnumerator methodResult = methodInfo.Invoke(target, defaultParams) as IEnumerator; if (!Application.isPlaying) { // Set target object and scene dirty to serialize changes to disk EditorUtility.SetDirty(target); PrefabStage stage = PrefabStageUtility.GetCurrentPrefabStage(); if (stage != null) { // Prefab mode EditorSceneManager.MarkSceneDirty(stage.scene); } else { // Normal scene EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene()); } } else if (methodResult != null && target is MonoBehaviour behaviour) { behaviour.StartCoroutine(methodResult); } } EditorGUI.EndDisabledGroup(); } else { string warning = typeof(ButtonAttribute).Name + " works only on methods with no parameters"; HelpBox_Layout(warning, MessageType.Warning, context: target, logToConsole: true); } }
/// <summary> /// Draws the contents of a scriptable inline inside a foldout. Depending on if there's an actual scriptable /// linked, the values will be greyed out or editable in case the scriptable is created inside the serialized object. /// </summary> static public bool DrawScriptableFoldout <T>(SerializedProperty scriptable, string description, bool isExpanded) where T : ScriptableObject { isExpanded = EditorGUILayout.Foldout(isExpanded, description, true, MixedRealityStylesUtility.BoldFoldoutStyle); if (isExpanded) { using (new EditorGUI.IndentLevelScope()) { if (scriptable.objectReferenceValue == null) { // If there's no scriptable linked we're creating a local instance that allows to store a // local version of the scriptable in the serialized object owning the scriptable property. scriptable.objectReferenceValue = ScriptableObject.CreateInstance <T>(); } // We have currently 5 different states to display to the user: // 1. the scriptable is local to the object instance // 2. the scriptable is a linked nested scriptable inside of the currently displayed prefab // 3. the scriptable is a linked nested scriptable inside of another prefab // 4. the scriptable is a shared standalone asset // 5. the scriptable slot is empty but inside of a prefab asset which needs special handling as // prefabs can only display linked or nested scriptables. // Depending on the type of link we show the user the scriptable configuration either: // case 1 &2: editable inlined // case 3 & 4: greyed out readonly // case 5: only show the link // case 5 -> can't create and/or store the local scriptable above - show link bool isStoredAsset = (scriptable.objectReferenceValue == null) ? false : AssetDatabase.Contains(scriptable.objectReferenceValue); bool isEmptyInStagedPrefab = !isStoredAsset && ((Component)scriptable.serializedObject.targetObject).gameObject.scene.path == ""; if (scriptable.objectReferenceValue == null || isEmptyInStagedPrefab) { EditorGUILayout.HelpBox("No scriptable " + scriptable.displayName + " linked to this prefab. Prefabs can't store " + "local versions of scriptables and need to be linked to a scriptable asset.", MessageType.Warning); EditorGUILayout.PropertyField(scriptable, new GUIContent(scriptable.displayName + " (Empty): ")); } else { bool isNestedInCurrentPrefab = false; var prefabStage = PrefabStageUtility.GetCurrentPrefabStage(); if (prefabStage != null) { var instancePath = AssetDatabase.GetAssetPath(scriptable.objectReferenceValue); isNestedInCurrentPrefab = (instancePath != "" && instancePath == prefabStage.prefabAssetPath); } if (isStoredAsset && !isNestedInCurrentPrefab) { // case 3 & 4 - greyed out drawer bool isMainAsset = AssetDatabase.IsMainAsset(scriptable.objectReferenceValue); var sharedAssetPath = AssetDatabase.GetAssetPath(scriptable.objectReferenceValue); if (isMainAsset) { EditorGUILayout.HelpBox("Editing a shared " + scriptable.displayName + ", located at " + sharedAssetPath, MessageType.Warning); } else { EditorGUILayout.HelpBox("Editing a nested " + scriptable.displayName + ", located inside of " + sharedAssetPath, MessageType.Warning); } EditorGUILayout.PropertyField(scriptable, new GUIContent(scriptable.displayName + " (Shared asset): ")); // In case there's a shared scriptable linked we're disabling the inlined scriptable properties // (this will render them grayed out) so users won't accidentally modify the shared scriptable. GUI.enabled = false; DrawScriptableSubEditor(scriptable); GUI.enabled = true; } else { // case 1 & 2 - inline editable drawer if (isNestedInCurrentPrefab) { EditorGUILayout.HelpBox("Editing a nested version of " + scriptable.displayName + ".", MessageType.Info); } else { EditorGUILayout.HelpBox("Editing a local version of " + scriptable.displayName + ".", MessageType.Info); } EditorGUILayout.PropertyField(scriptable, new GUIContent(scriptable.displayName + " (local): ")); DrawScriptableSubEditor(scriptable); } } } } return(isExpanded); }
public Object GetSelection(bool openInProject) { string extension = Path.GetExtension(pathInfo.assetPath); switch (extension) { case ".unity": if (openInProject) { // it is not possible to open a scene object in the project. return(null); } Scene currentScene = EditorSceneManager.GetActiveScene(); if (currentScene.path != pathInfo.assetPath) { bool shouldContinue = SceneUtil.SaveDirtyScenes(); if (!shouldContinue) { return(null); } currentScene = EditorSceneManager.OpenScene(pathInfo.assetPath, OpenSceneMode.Single); } #if UNITY_2018_3_OR_NEWER PrefabStage currentPrefabStage = PrefabStageUtility.GetCurrentPrefabStage(); if (currentPrefabStage != null) { StageUtility.GoToMainStage(); } #endif return(pathInfo.objID.searchForObjectInScene(currentScene)); case ".prefab": #if UNITY_2018_3_OR_NEWER if (openInProject) { GameObject root = AssetDatabase.LoadAssetAtPath <GameObject>(pathInfo.assetPath); return(pathInfo.objID.localPath.GetObject(root)); } else { // is the prefab open in the stage? PrefabStage stage = PrefabStageUtility.GetCurrentPrefabStage(); GameObject root = null; if (stage == null || stage.assetPath != pathInfo.assetPath) { // this is not the currently open path. open the latest. root = AssetDatabase.LoadAssetAtPath <GameObject>(pathInfo.assetPath); AssetDatabase.OpenAsset(root); } else { root = stage.prefabContentsRoot; } return(pathInfo.objID.searchForObjectInScene()); } #else // This case is pretty straightforward. Just select the object. return(EditorUtility.InstanceIDToObject(pathInfo.gameObjectID)); #endif case ".controller": EditorApplication.ExecuteMenuItem("Window/Animator"); // now get the animator to display it. string assetPath = AssetDatabase.GetAssetPath(pathInfo.gameObjectID); UnityEngine.Object assetObj = AssetDatabase.LoadAssetAtPath(assetPath, typeof(UnityEngine.Object)); //set it as the selection. Selection.activeObject = assetObj; //wait until inspectors are updated and now we can set the // selection to the internal object. EditorApplication.delayCall += () => { Selection.activeInstanceID = pathInfo.gameObjectID; }; return(assetObj); default: return(EditorUtility.InstanceIDToObject(pathInfo.gameObjectID)); } }
private void LateUpdate() { #if UNITY_EDITOR // We don't run in "prefab scenes", i.e. when editing a prefab. Bail out if prefab scene is detected. if (PrefabStageUtility.GetCurrentPrefabStage() != null) { return; } #endif if (OceanRenderer.Instance == null || !ShowEffect()) { _rend.enabled = false; return; } // Pass true in last arg for a crap reason - in edit mode LateUpdate can be called very frequently, and the height sampler mistakenly thinks // this is erroneous and complains. _sampleWaterHeight.Init(transform.position, 0f, true); _sampleWaterHeight.Sample(out var waterHeight); float heightOffset = transform.position.y - waterHeight; // Disable skirt when camera not close to water. In the first few frames collision may not be avail, in that case no choice // but to assume enabled. In the future this could detect if camera is far enough under water, render a simple quad to avoid // finding the intersection line. _rend.enabled = heightOffset < _maxHeightAboveWater; if (_rend.enabled) { // Only execute when playing to stop CopyPropertiesFromMaterial from corrupting and breaking the material. if (_copyParamsEachFrame && Application.isPlaying) { _rend.sharedMaterial.CopyPropertiesFromMaterial(OceanRenderer.Instance.OceanMaterial); } // Assign lod0 shape - trivial but bound every frame because lod transform comes from here if (_mpb == null) { _mpb = new PropertyWrapperMPB(); } _rend.GetPropertyBlock(_mpb.materialPropertyBlock); // Underwater rendering uses displacements for intersecting the waves with the near plane, and ocean depth/shadows for ScatterColour() _mpb.SetInt(LodDataMgr.sp_LD_SliceIndex, 0); OceanRenderer.Instance._lodDataAnimWaves.BindResultData(_mpb); if (OceanRenderer.Instance._lodDataSeaDepths != null) { OceanRenderer.Instance._lodDataSeaDepths.BindResultData(_mpb); } else { LodDataMgrSeaFloorDepth.BindNull(_mpb); } if (OceanRenderer.Instance._lodDataShadow != null) { OceanRenderer.Instance._lodDataShadow.BindResultData(_mpb); } else { LodDataMgrShadow.BindNull(_mpb); } _mpb.SetFloat(sp_HeightOffset, heightOffset); _mpb.SetVector(OceanChunkRenderer.sp_InstanceData, new Vector3(OceanRenderer.Instance.ViewerAltitudeLevelAlpha, 0f, 0f)); _rend.SetPropertyBlock(_mpb.materialPropertyBlock); } }
void OnGUI() { if (itemStyle == null) { itemStyle = new GUIStyle(GUI.skin.GetStyle("Tag MenuItem")); } EditorGUILayout.BeginHorizontal(); //package list start------ EditorGUILayout.BeginHorizontal(); GUILayout.Space(5); EditorGUILayout.BeginVertical(); GUILayout.Space(10); EditorGUILayout.LabelField("Packages", (GUIStyle)"OL Title", GUILayout.Width(300)); GUILayout.Space(5); EditorGUILayout.BeginHorizontal(); GUILayout.Space(4); scrollPos1 = EditorGUILayout.BeginScrollView(scrollPos1, (GUIStyle)"CN Box", GUILayout.Height(300), GUILayout.Width(300)); EditorToolSet.LoadPackages(); List <UIPackage> pkgs = UIPackage.GetPackages(); int cnt = pkgs.Count; if (cnt == 0) { selectedPackage = -1; selectedPackageName = null; } else { for (int i = 0; i < cnt; i++) { EditorGUILayout.BeginHorizontal(); if (GUILayout.Toggle(selectedPackageName == pkgs[i].name, pkgs[i].name, itemStyle, GUILayout.ExpandWidth(true))) { selectedPackage = i; selectedPackageName = pkgs[i].name; } EditorGUILayout.EndHorizontal(); } } EditorGUILayout.EndScrollView(); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); //package list end------ //component list start------ EditorGUILayout.BeginHorizontal(); GUILayout.Space(5); EditorGUILayout.BeginVertical(); GUILayout.Space(10); EditorGUILayout.LabelField("Components", (GUIStyle)"OL Title", GUILayout.Width(220)); GUILayout.Space(5); EditorGUILayout.BeginHorizontal(); GUILayout.Space(4); scrollPos2 = EditorGUILayout.BeginScrollView(scrollPos2, (GUIStyle)"CN Box", GUILayout.Height(300), GUILayout.Width(220)); if (selectedPackage >= 0) { List <PackageItem> items = pkgs[selectedPackage].GetItems(); int i = 0; foreach (PackageItem pi in items) { if (pi.type == PackageItemType.Component && pi.exported) { EditorGUILayout.BeginHorizontal(); if (GUILayout.Toggle(selectedComponentName == pi.name, pi.name, itemStyle, GUILayout.ExpandWidth(true))) { selectedComponentName = pi.name; } i++; EditorGUILayout.EndHorizontal(); } } } EditorGUILayout.EndScrollView(); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); //component list end------ GUILayout.Space(10); EditorGUILayout.EndHorizontal(); GUILayout.Space(20); //buttons start--- EditorGUILayout.BeginHorizontal(); GUILayout.Space(180); if (GUILayout.Button("Refresh", GUILayout.Width(100))) { EditorToolSet.ReloadPackages(); } GUILayout.Space(20); if (GUILayout.Button("OK", GUILayout.Width(100)) && selectedPackage >= 0) { UIPackage selectedPkg = pkgs[selectedPackage]; string tmp = selectedPkg.assetPath.ToLower(); string packagePath; int pos = tmp.LastIndexOf("/resources/"); if (pos != -1) { packagePath = selectedPkg.assetPath.Substring(pos + 11); } else { pos = tmp.IndexOf("resources/"); if (pos == 0) { packagePath = selectedPkg.assetPath.Substring(pos + 10); } else { packagePath = selectedPkg.assetPath; } } if (Selection.activeGameObject != null) { #if UNITY_2018_3_OR_NEWER bool isPrefab = PrefabUtility.GetPrefabAssetType(Selection.activeGameObject) != PrefabAssetType.NotAPrefab; #else bool isPrefab = PrefabUtility.GetPrefabType(Selection.activeGameObject) == PrefabType.Prefab; #endif Selection.activeGameObject.SendMessage("OnUpdateSource", new object[] { selectedPkg.name, packagePath, selectedComponentName, !isPrefab }, SendMessageOptions.DontRequireReceiver); } #if UNITY_2018_3_OR_NEWER PrefabStage prefabStage = PrefabStageUtility.GetCurrentPrefabStage(); if (prefabStage != null) { EditorSceneManager.MarkSceneDirty(prefabStage.scene); } else { ApplyChange(); } #else ApplyChange(); #endif this.Close(); } EditorGUILayout.EndHorizontal(); }
/// <summary> /// 在场景中搜索任务目标 /// </summary> private static void SearchTaskTarget(TaskGameObject taskGameObject) { if (taskGameObject.GUID == "<None>") { return; } if (taskGameObject.AgentEntity != null) { return; } PrefabStage prefabStage = PrefabStageUtility.GetCurrentPrefabStage(); if (prefabStage != null) { taskGameObject.AgentEntity = prefabStage.prefabContentsRoot.FindChildren(taskGameObject.Path); if (taskGameObject.AgentEntity == null) { TaskTarget[] targets = prefabStage.prefabContentsRoot.GetComponentsInChildren <TaskTarget>(true); foreach (TaskTarget target in targets) { if (taskGameObject.GUID == target.GUID) { taskGameObject.AgentEntity = target.gameObject; taskGameObject.Path = target.transform.FullName(); taskGameObject.Path = taskGameObject.Path.Substring(taskGameObject.Path.IndexOf("/") + 1); break; } } } } else { taskGameObject.AgentEntity = GameObject.Find(taskGameObject.Path); if (taskGameObject.AgentEntity == null) { TaskTarget[] targets = UnityEngine.Object.FindObjectsOfType <TaskTarget>(); foreach (TaskTarget target in targets) { if (taskGameObject.GUID == target.GUID) { taskGameObject.AgentEntity = target.gameObject; taskGameObject.Path = target.transform.FullName(); break; } } } } if (taskGameObject.AgentEntity != null) { TaskTarget target = taskGameObject.AgentEntity.GetComponent <TaskTarget>(); if (!target) { target = taskGameObject.AgentEntity.AddComponent <TaskTarget>(); target.GUID = taskGameObject.GUID; EditorUtility.SetDirty(taskGameObject.AgentEntity); } } }
public static void SaveOpenPrefabStage() { if (PrefabStageUtility.GetCurrentPrefabStage() == null) { return; } typeof(PrefabStage).GetMethod("SavePrefab", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.Invoke(PrefabStageUtility.GetCurrentPrefabStage(), null); }
public static PrefabProperties GetPrefabProperties(GameObject gameObject) { PrefabProperties p = new PrefabProperties(); p.IsPartOfPrefabAsset = PrefabUtility.IsPartOfPrefabAsset(gameObject); if (!p.IsPartOfPrefabAsset) { p.IsPartOfPrefabAsset = !string.IsNullOrEmpty(AssetDatabase.GetAssetPath(gameObject)); } GameObject nerestInstanceRoot = p.NearestInstanceRoot = PrefabUtility.GetNearestPrefabInstanceRoot(gameObject); p.IsPartOfInstance = (nerestInstanceRoot != null); p.IsInstanceRoot = (gameObject == nerestInstanceRoot); if (p.IsPartOfPrefabAsset) { p.PrefabAssetRoot = gameObject.transform.root.gameObject; p.IsAssetRoot = (gameObject == p.PrefabAssetRoot); } var editorPrefabStage = PrefabStageUtility.GetCurrentPrefabStage(); if (editorPrefabStage != null) { if (p.IsPartOfPrefabAsset == false) { p.IsPartOfStage = true; } if (p.IsPartOfStage && gameObject.transform.parent == null) { p.IsStageRoot = true; } } if (p.IsRootOfAnyPrefab) { if (p.IsStageRoot) { p.Path = editorPrefabStage.prefabAssetPath; } else if (p.IsInstanceRoot) { p.Path = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(gameObject); } else if (p.IsAssetRoot) { p.Path = AssetDatabase.GetAssetPath(gameObject); } } else { if (p.IsPartOfStage) { p.Path = editorPrefabStage.prefabAssetPath; } else if (p.IsPartOfInstance) { p.Path = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(p.NearestInstanceRoot); } else if (p.IsPartOfPrefabAsset) { p.Path = AssetDatabase.GetAssetPath(gameObject.transform.root.gameObject); } } return(p); }
public IEnumerator NavMeshSurfacePrefabVariant_WhenCustomizedAndRebaked_OldAssetDiscardedAndParentAssetUnchanged() { var prefabVariant = AssetDatabase.LoadAssetAtPath <GameObject>(m_PrefabVariantPath); var theOriginalPrefabPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(prefabVariant); var theOriginalPrefab = AssetDatabase.LoadAssetAtPath <GameObject>(theOriginalPrefabPath); AssetDatabase.OpenAsset(theOriginalPrefab); var theOriginalPrefabStage = PrefabStageUtility.GetCurrentPrefabStage(); var theOriginalPrefabSurface = theOriginalPrefabStage.prefabContentsRoot.GetComponent <NavMeshSurface>(); var theOriginalPrefabNavMeshData = theOriginalPrefabSurface.navMeshData; var theOriginalPrefabAssetPath = AssetDatabase.GetAssetPath(theOriginalPrefabSurface.navMeshData); Assert.IsTrue(theOriginalPrefabNavMeshData != null, "Original prefab must have some NavMeshData."); Assert.IsTrue(File.Exists(theOriginalPrefabAssetPath), "NavMeshData file must exist for the original prefab. ({0})", theOriginalPrefabAssetPath); AssetDatabase.OpenAsset(prefabVariant); var prefabVariantStage = PrefabStageUtility.GetCurrentPrefabStage(); var prefabVariantSurface = prefabVariantStage.prefabContentsRoot.GetComponent <NavMeshSurface>(); yield return(BakeNavMeshAsync(() => prefabVariantSurface, k_GrayArea)); PrefabSavingUtil.SavePrefab(prefabVariantStage); var modifiedVariantNavMeshData = prefabVariantSurface.navMeshData; var modifiedVariantAssetPath = AssetDatabase.GetAssetPath(prefabVariantSurface.navMeshData); Assert.IsTrue(modifiedVariantNavMeshData != null, "Prefab must have some NavMeshData."); Assert.IsTrue(File.Exists(modifiedVariantAssetPath), "NavMeshData file for modifier variant must exist. ({0})", modifiedVariantAssetPath); Assert.AreNotEqual(theOriginalPrefabNavMeshData, modifiedVariantNavMeshData, "Modified variant must have a NavMeshData different than that of the original prefab."); yield return(BakeNavMeshAsync(() => prefabVariantSurface, k_OrangeArea)); Assert.IsTrue(modifiedVariantNavMeshData != null, "The initial NavMeshData of a modified variant must still exist immediately after prefab variant re-bake."); Assert.IsTrue(File.Exists(modifiedVariantAssetPath), "The initial NavMeshData file of a modified variant must exist after prefab variant re-bake. ({0})", modifiedVariantAssetPath); Assert.IsTrue(prefabVariantSurface.navMeshData != null, "NavMeshSurface must have NavMeshData after baking."); var unsavedRebakedNavMeshData = prefabVariantSurface.navMeshData; yield return(BakeNavMeshAsync(() => prefabVariantSurface, k_RedArea)); Assert.IsTrue(unsavedRebakedNavMeshData == null, "An unsaved NavMeshData should not exist after a re-bake."); Assert.IsTrue(prefabVariantSurface.navMeshData != null, "NavMeshSurface must have NavMeshData after baking."); PrefabSavingUtil.SavePrefab(prefabVariantStage); var theNewVariantNavMeshData = prefabVariantSurface.navMeshData; var theNewVariantAssetPath = AssetDatabase.GetAssetPath(theNewVariantNavMeshData); Assert.IsTrue(modifiedVariantNavMeshData == null, "Initial NavMeshData of the modified variant must no longer exist after saving the variant."); // ReSharper disable once HeuristicUnreachableCode - modifiedVariantNavMeshData is affected by BakeNavMeshAsync() Assert.IsFalse(File.Exists(modifiedVariantAssetPath), "Initial NavMeshData file of the modified and saved variant must no longer exist after saving the variant. ({0})", modifiedVariantAssetPath); Assert.IsTrue(File.Exists(theNewVariantAssetPath), "Variant's own NavMeshData exists in a file after saving. ({0})", theNewVariantAssetPath); Assert.IsTrue(File.Exists(theOriginalPrefabAssetPath), "NavMeshData file of the original prefab still exists after saving the variant. ({0})", theOriginalPrefabAssetPath); Assert.AreNotEqual(theOriginalPrefabNavMeshData, theNewVariantNavMeshData, "Re-baked modified variant must have a NavMeshData different than that of the original prefab."); StageUtility.GoToMainStage(); yield return(null); }
public void refreshCache(IWindow window) { if (window == null) { return; } // if(!ready) return; this.window = window; _cache = new Dictionary <Component, HashSet <HashValue> >(); folderCache = new Dictionary <string, HashSet <Component> >(); prefabDependencies = new Dictionary <GameObject, HashSet <string> >(); ready = false; List <GameObject> listRootGO = null; #if SUPPORT_NESTED_PREFAB if (PrefabStageUtility.GetCurrentPrefabStage() != null) { GameObject rootPrefab = PrefabStageUtility.GetCurrentPrefabStage().prefabContentsRoot; if (rootPrefab != null) { listRootGO = new List <GameObject> { rootPrefab }; } } #else #endif if (listRootGO == null) { listGO = FR2_Unity.getAllObjsInCurScene().ToList(); } else { listGO = new List <GameObject>(); foreach (GameObject item in listRootGO) { listGO.AddRange(FR2_Unity.getAllChild(item, true)); } } total = listGO.Count; current = 0; // Debug.Log("refresh cache total " + total); EditorApplication.update -= OnUpdate; EditorApplication.update += OnUpdate; // foreach (var item in FR2_Helper.getAllObjsInCurScene()) // { // // Debug.Log("object in scene: " + item.name); // Component[] components = item.GetComponents<Component>(); // foreach (var com in components) // { // if(com == null) continue; // SerializedObject serialized = new SerializedObject(com); // SerializedProperty it = serialized.GetIterator().Copy(); // while (it.NextVisible(true)) // { // if (it.propertyType != SerializedPropertyType.ObjectReference) continue; // if (it.objectReferenceValue == null) continue; // if(!_cache.ContainsKey(com)) _cache.Add(com, new HashSet<SerializedProperty>()); // if(!_cache[com].Contains(it)) // _cache[com].Add(it.Copy()); // } // } // } Dirty = false; }
// Drive state from OnEnable and OnDisable? OnEnable on RegisterLodDataInput seems to get called on script reload void OnEnable() { // We don't run in "prefab scenes", i.e. when editing a prefab. Bail out if prefab scene is detected. #if UNITY_EDITOR if (PrefabStageUtility.GetCurrentPrefabStage() != null) { return; } #endif if (!_primaryLight && _searchForPrimaryLightOnStartup) { _primaryLight = RenderSettings.sun; } if (!VerifyRequirements()) { enabled = false; return; } #if UNITY_EDITOR if (EditorApplication.isPlaying && !Validate(this, ValidatedHelper.DebugLog)) { enabled = false; return; } #endif Instance = this; Scale = Mathf.Clamp(Scale, _minScale, _maxScale); _lodTransform = new LodTransform(); _lodTransform.InitLODData(_lodCount); // Resolution is 4 tiles across. var baseMeshDensity = _lodDataResolution * 0.25f / _geometryDownSampleFactor; // 0.4f is the "best" value when base mesh density is 8. Scaling down from there produces results similar to // hand crafted values which looked good when the ocean is flat. _lodAlphaBlackPointFade = 0.4f / (baseMeshDensity / 8f); // We could calculate this in the shader, but we can save two subtractions this way. _lodAlphaBlackPointWhitePointFade = 1f - _lodAlphaBlackPointFade - _lodAlphaBlackPointFade; Root = OceanBuilder.GenerateMesh(this, _oceanChunkRenderers, _lodDataResolution, _geometryDownSampleFactor, _lodCount); CreateDestroySubSystems(); _commandbufferBuilder = new BuildCommandBuffer(); InitViewpoint(); if (_attachDebugGUI && GetComponent <OceanDebugGUI>() == null) { gameObject.AddComponent <OceanDebugGUI>().hideFlags = HideFlags.DontSave; } #if UNITY_EDITOR EditorApplication.update -= EditorUpdate; EditorApplication.update += EditorUpdate; #endif foreach (var lodData in _lodDatas) { lodData.OnEnable(); } _canSkipCulling = false; }
public void GenerateIcon() { Dictionary <Renderer, int> dicRenderers = new Dictionary <Renderer, int>(); if (renderers.Count == 0) { foreach (Renderer renderer in (renderers.Count == 0 ? new List <Renderer>(this.transform.root.GetComponentsInChildren <Renderer>()) : renderers)) { dicRenderers.Add(renderer, renderer.gameObject.layer); renderer.gameObject.layer = tempLayer; } } Camera cam = new GameObject().AddComponent <Camera>(); cam.transform.SetParent(this.transform); cam.orthographic = true; cam.targetTexture = RenderTexture.GetTemporary(iconResolution, iconResolution, 16); cam.clearFlags = CameraClearFlags.Color; cam.stereoTargetEye = StereoTargetEyeMask.None; cam.orthographicSize = size / 2; cam.cullingMask = 1 << tempLayer; cam.enabled = false; cam.transform.position = this.transform.position + (this.transform.forward * -1); cam.transform.rotation = this.transform.rotation; Light camLight = cam.gameObject.AddComponent <Light>(); camLight.transform.SetParent(cam.transform); camLight.type = LightType.Directional; camLight.enabled = true; string iconPath = null; if (PrefabStageUtility.GetCurrentPrefabStage() != null) { // Prefab editor iconPath = PrefabStageUtility.GetCurrentPrefabStage().prefabAssetPath; cam.scene = PrefabStageUtility.GetCurrentPrefabStage().scene; } else if (PrefabUtility.GetNearestPrefabInstanceRoot(this)) { // Prefab in scene iconPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(this); } else { // Not a prefab Debug.LogError("Unable to create an icon file if the object is not a prefab!"); } cam.Render(); RenderTexture orgActiveRenderTexture = RenderTexture.active; RenderTexture.active = cam.targetTexture; generatedIcon = new Texture2D(cam.targetTexture.width, cam.targetTexture.height, TextureFormat.ARGB32, false); generatedIcon.ReadPixels(new Rect(0, 0, cam.targetTexture.width, cam.targetTexture.height), 0, 0); generatedIcon.Apply(false); RenderTexture.active = orgActiveRenderTexture; // Clean up after ourselves cam.targetTexture = null; RenderTexture.ReleaseTemporary(cam.targetTexture); foreach (KeyValuePair <Renderer, int> renderer in dicRenderers) { renderer.Key.gameObject.layer = renderer.Value; } DestroyImmediate(cam.gameObject); if (iconPath != null) { byte[] bytes = generatedIcon.EncodeToPNG(); string path = iconPath.Replace(".prefab", ".png"); System.IO.File.WriteAllBytes(path, bytes); AssetDatabase.Refresh(); generatedIcon = AssetDatabase.LoadAssetAtPath <Texture2D>(path); TextureImporter textureImporter = (TextureImporter)TextureImporter.GetAtPath(path); textureImporter.alphaIsTransparency = true; EditorUtility.SetDirty(textureImporter); textureImporter.SaveAndReimport(); Debug.Log("Icon generated : " + path); AddressableAssetSettings settings = AddressableAssetSettingsDefaultObject.Settings; if (settings != null) { string guid = AssetDatabase.AssetPathToGUID(path); AddressableAssetEntry entry = settings.FindAssetEntry(guid); if (entry == null) { Debug.Log("Added icon to addressable"); entry = settings.CreateOrMoveEntry(guid, settings.DefaultGroup); settings.SetDirty(AddressableAssetSettings.ModificationEvent.EntryAdded, entry, true, false); } string prefabGuid = AssetDatabase.AssetPathToGUID(iconPath); AddressableAssetEntry prefabEntry = settings.FindAssetEntry(prefabGuid); if (prefabEntry != null) { entry.SetAddress(prefabEntry.address + ".Icon", false); } } else { Debug.LogError("Could not find AddressableAssetSettings, cannot set the icon to addressable"); return; } } }