├── .gitignore
├── Assets
├── PrefabEditor.meta
└── PrefabEditor
│ ├── Editor.meta
│ └── Editor
│ ├── PrefabEditor.cs
│ └── PrefabEditor.cs.meta
├── Medias
└── screen.gif
├── ProjectSettings
├── AudioManager.asset
├── ClusterInputManager.asset
├── DynamicsManager.asset
├── EditorBuildSettings.asset
├── EditorSettings.asset
├── GraphicsSettings.asset
├── InputManager.asset
├── NavMeshAreas.asset
├── NetworkManager.asset
├── Physics2DSettings.asset
├── ProjectSettings.asset
├── ProjectVersion.txt
├── QualitySettings.asset
├── TagManager.asset
├── TimeManager.asset
└── UnityConnectSettings.asset
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | [Ll]ibrary/
2 | [Tt]emp/
3 | [Oo]bj/
4 | [Bb]uild/
5 | [Bb]uilds/
6 | Assets/AssetStoreTools*
7 |
8 | # Autogenerated VS/MD solution and project files
9 | ExportedObj/
10 | *.csproj
11 | *.unityproj
12 | *.sln
13 | *.suo
14 | *.tmp
15 | *.user
16 | *.userprefs
17 | *.pidb
18 | *.booproj
19 | *.svd
20 |
21 |
22 | # Unity3D generated meta files
23 | *.pidb.meta
24 |
25 | # Unity3D Generated File On Crash Reports
26 | sysinfo.txt
27 |
28 | # Builds
29 | *.apk
30 | *.unitypackage
31 |
--------------------------------------------------------------------------------
/Assets/PrefabEditor.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 31d16bb0473474a6089892c31518d4b8
3 | folderAsset: yes
4 | timeCreated: 1494663727
5 | licenseType: Free
6 | DefaultImporter:
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Assets/PrefabEditor/Editor.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 152ccf9e646e549c48269091f4073587
3 | folderAsset: yes
4 | timeCreated: 1494663731
5 | licenseType: Free
6 | DefaultImporter:
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Assets/PrefabEditor/Editor/PrefabEditor.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Linq;
3 |
4 | using UnityEngine;
5 | using UnityEditor;
6 | using UnityEditor.SceneManagement;
7 |
8 | ///
9 | ///
10 | [InitializeOnLoad]
11 | public class PrefabEditorAssetProcessor : UnityEditor.AssetModificationProcessor
12 | {
13 | ///
14 | /// Path of tmp PrefabEditor scene
15 | ///
16 | private static string mTmpScenePath;
17 |
18 | ///
19 | /// ctor call when unity editor start
20 | ///
21 | static PrefabEditorAssetProcessor()
22 | {
23 | SceneView.onSceneGUIDelegate += OnGUIScene;
24 | EditorApplication.update = OnUpdateEditor;
25 | mTmpScenePath = Path.Combine(GetDirectoryName(), "PrefabTmpScene.unity");
26 |
27 | // On windows editor, final path must be converted into UNIX format
28 | // to match with AssetDatabase.GetAssetPath and OnWillSaveAssets param
29 | #if UNITY_EDITOR_WIN
30 | mTmpScenePath = mTmpScenePath.Replace('\\', '/');
31 | #endif
32 | }
33 |
34 | ///
35 | /// Get path of PrefabEditor directory
36 | ///
37 | /// PrefabEditor path
38 | private static string GetDirectoryName()
39 | {
40 | var monoscript = MonoScript.FromScriptableObject(PrefabEditor.Instance);
41 | return Path.GetDirectoryName(AssetDatabase.GetAssetPath(monoscript));
42 | }
43 |
44 | ///
45 | /// Call during editor update
46 | ///
47 | private static void OnUpdateEditor()
48 | {
49 | // Remove tmp scene if prefab editor is close
50 | if (File.Exists(mTmpScenePath) && PrefabEditor.Instance.prefabInstance == null)
51 | {
52 | File.Delete(mTmpScenePath);
53 | AssetDatabase.Refresh();
54 | }
55 | }
56 |
57 | ///
58 | /// Call by the editor when user double click on any asset
59 | ///
60 | ///
61 | ///
62 | ///
63 | [UnityEditor.Callbacks.OnOpenAssetAttribute(1)]
64 | public static bool OpenPrefabEditorCallback(int instanceID, int line)
65 | {
66 | string assetPath = AssetDatabase.GetAssetPath(instanceID);
67 | var fileInfo = new FileInfo(assetPath);
68 | if (fileInfo.Extension == ".prefab")
69 | {
70 | OpenPrefabEditor(assetPath);
71 | return true;
72 | }
73 | return false;
74 | }
75 |
76 | ///
77 | /// Draw GUI on SceneView
78 | ///
79 | ///
80 | private static void OnGUIScene(SceneView sceneView)
81 | {
82 | if (PrefabEditor.Instance.prefabInstance == null)
83 | {
84 | return;
85 | }
86 |
87 | GUIStyle style = new GUIStyle();
88 | style.fontSize = 20;
89 | style.normal.textColor = new Color(0,0,0,0.5f);
90 | style.alignment = TextAnchor.UpperLeft;
91 | style.fontStyle = FontStyle.Bold;
92 | style.margin = new RectOffset(15, 0, 0, 0);
93 |
94 | Handles.BeginGUI();
95 | GUILayout.Label("Prefab Editor", style);
96 | if (!string.IsNullOrEmpty(PrefabEditor.Instance.previousScenePath))
97 | {
98 | if (GUILayout.Button("Back to previous scene", GUILayout.Width(175)))
99 | {
100 | if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
101 | {
102 | EditorSceneManager.OpenScene(PrefabEditor.Instance.previousScenePath, OpenSceneMode.Single);
103 | }
104 | }
105 | }
106 | Handles.EndGUI();
107 | }
108 |
109 | ///
110 | /// This is called by Unity when it is about to write serialized assets or scene files to disk.
111 | ///
112 | ///
113 | private static string[] OnWillSaveAssets(string[] paths)
114 | {
115 | if (paths.Contains(mTmpScenePath) && PrefabEditor.Instance.prefabInstance != null)
116 | {
117 | PrefabUtility.ReplacePrefab(
118 | PrefabEditor.Instance.prefabInstance,
119 | PrefabEditor.Instance.prefabRoot,
120 | ReplacePrefabOptions.ConnectToPrefab);
121 | }
122 | return paths;
123 | }
124 |
125 | ///
126 | /// Open prefab editor
127 | ///
128 | /// Path of prefab file in assets directory
129 | public static void OpenPrefabEditor(string assetPath)
130 | {
131 | // Load object at path
132 | var prefab = AssetDatabase.LoadAssetAtPath(assetPath, typeof(GameObject)) as GameObject;
133 |
134 | // Quit if load failed
135 | if (!prefab)
136 | {
137 | return;
138 | }
139 |
140 | // Quit if object is not a prefab
141 | if (PrefabUtility.GetPrefabType(prefab) != PrefabType.Prefab)
142 | {
143 | return;
144 | }
145 |
146 | // Quit if editor is in playmode
147 | if (EditorApplication.isPlaying)
148 | {
149 | EditorWindow.focusedWindow.ShowNotification(new GUIContent("Can't open prefab editor in playmode"));
150 | return;
151 | }
152 |
153 | // Save currently open scene
154 | if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
155 | {
156 | return;
157 | }
158 |
159 | //Save current scene path
160 | PrefabEditor.Instance.previousScenePath = EditorSceneManager.GetActiveScene().path;
161 |
162 | //Create new empty scene
163 | EditorSceneManager.NewScene(NewSceneSetup.EmptyScene);
164 |
165 | //Save this new scene
166 | EditorSceneManager.SaveScene(EditorSceneManager.GetActiveScene(), mTmpScenePath);
167 |
168 | PrefabEditor.Instance.prefabRoot = prefab;
169 |
170 | //Instantiate the prefab and select it
171 | var prefabInstance = PrefabUtility.InstantiatePrefab(PrefabEditor.Instance.prefabRoot) as GameObject;
172 | PrefabEditor.Instance.prefabInstance = prefabInstance;
173 |
174 | if (prefab.GetComponentInChildren())
175 | {
176 | var canvas = new GameObject("Canvas");
177 | canvas.AddComponent