public static void StartEditWidget(GWidget widget) { EditorSceneManager.UnloadSceneAsync(EditorSceneManager.GetActiveScene()); EditorSceneManager.NewSceneCreatedCallback fun = (UnityEngine.SceneManagement.Scene scene, NewSceneSetup setup, NewSceneMode mode) => { EditorSceneManager.SetActiveScene(scene); //创建canvas GameObject canvasObj = new GameObject("Canvas"); Canvas canvas = canvasObj.AddComponent <Canvas>(); canvas.renderMode = RenderMode.ScreenSpaceOverlay; new GameObject("EventSystem").AddComponent <UnityEngine.EventSystems.EventSystem>(); //遮挡背景 //GameObject bkgObj = new GameObject("background"); //bkgObj.transform.SetParent(canvas.transform,false); //Image image = bkgObj.AddComponent<Image>(); //image.rectTransform.sizeDelta = Vector2.zero; //image.rectTransform.anchorMin = Vector2.zero; //image.rectTransform.anchorMax = Vector2.one; //image.rectTransform.anchoredPosition = Vector2.zero; //image.color = Color.black; //将要编辑的组件放进来 GameObject obj = (GameObject)PrefabUtility.InstantiatePrefab(widget.gameObject, scene); obj.transform.SetParent(canvasObj.transform, false); obj.SetActive(true); Selection.activeObject = obj; }; EditorSceneManager.newSceneCreated += fun; EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Additive); EditorSceneManager.newSceneCreated -= fun; }
static string GetScriptString(GPrefabInstance firstTarget) { string script = ""; GFrame frame = firstTarget.GetComponentInParent <GFrame>(); if (frame) { //script += "findPath = \"" + GUtility.GetPath(frame.transform, firstTarget.transform) + "\";\n"; script += "trans = frame.Find(\"" + GUtility.GetPath(frame.transform, firstTarget.transform) + "\");\n"; } GWidget prefab = firstTarget.prefab; for (int i = 0; i < prefab.exportToScriptInfos.Count; i++) { GExportToScriptInfo property = prefab.exportToScriptInfos[i]; string path = GUtility.GetPath(firstTarget.transform, property.target.transform); if (path.StartsWith("/")) { path = path.Substring(1); } script += "trans.Find(\"" + path + "\")."; script += "GetComponent <" + property.type + "> ();"; script += "//" + property.rename + "\n"; } return(script); }
//编辑模式下绑定测试动作 public void BindTestEvent(GWidget preview) { //return; for (int i = 0; i < preview.eventInfos.Count; i++) { string[] component_event = preview.eventInfos[i].eventName.Split('.'); if (component_event.Length == 2) { GTestAction action = GetAction(preview.eventInfos[i].eventName, false); if (action != null) { preview.eventInfos[i].actionType = action.actionType; preview.eventInfos[i].targetA = action.targetA; preview.eventInfos[i].targetB = action.targetB; Component c = preview.eventInfos[i].sender.GetComponent(component_event[0]); if (c is Button) { if (component_event[1] == "onClick") { (c as Button).onClick.AddListener(preview.eventInfos[i].Execute); } } } } } }
//将编辑过的属性值应用到控件上 public void UpdatePreviewValues(GWidget widget) { //return; for (int i = 0; i < widget.propertyInfos.Count; i++) { string[] cn = widget.propertyInfos[i].propertyName.Split('.'); object target = null; PropertyInfo pi = null; if (cn.Length == 2) { target = widget.propertyInfos[i].target.GetComponent(cn[0]); pi = target.GetType().GetProperty(cn[1]); } else if (cn.Length == 1) { target = widget.propertyInfos[i].target; pi = target.GetType().GetProperty(cn[0]); } if (pi != null) { string key = widget.propertyInfos[i].propertyName; if (widget.propertyInfos[i].target != widget.gameObject) //如果属性的目标不是prefab根节点的话,要在key上携带目标节点的名称 { key = widget.propertyInfos[i].target.name + "." + key; } object val = GetValue(key, pi.PropertyType, pi.GetValue(target, null)); pi.SetValue(target, val, null); } } }
static string GetScriptString2(GPrefabInstance firstTarget) { string script = ""; GFrame frame = firstTarget.GetComponentInParent <GFrame>(); if (frame) { script += "相对于Frame的路径:\n"; script += " \"" + GUtility.GetPath(frame.transform, firstTarget.transform) + "\"\t//" + GetTypes(firstTarget.prefab.transform) + "\n"; } script += "\n"; GWidget prefab = firstTarget.prefab; script += "内部结构:\n"; script += GetTreeString(prefab.transform, " "); return(script); }
//编辑模式的实例化 public void Instantiate() { if (!Application.isPlaying) { for (int i = 0; i < transform.childCount; i++) { Transform child = transform.GetChild(i); if (child.gameObject.name == "__preview__") { DestroyImmediate(child.gameObject); } } if (prefab) { Transform[] trans = new Transform[transform.childCount]; for (int i = 0; i < transform.childCount; i++) { trans[i] = transform.GetChild(i); } preview = GameObject.Instantiate <GWidget>(prefab, transform, false); preview.name = "__preview__"; preview.gameObject.SetActive(true); preview.transform.SetAsFirstSibling(); (preview.transform as RectTransform).anchoredPosition = Vector2.zero; (preview.transform as RectTransform).anchorMin = Vector2.zero; (preview.transform as RectTransform).anchorMax = Vector2.one; (preview.transform as RectTransform).sizeDelta = Vector2.zero; SetNodeFlag(preview.transform, HideFlags.DontSave | HideFlags.HideInHierarchy | HideFlags.NotEditable); UpdatePreviewValues(preview); if (preview.containerPanel) { preview.containerPanel.gameObject.AddComponent <PrefabLayoutSync>().shadow = transform as RectTransform; } } } }
public void OnEnable() { widget = target as GWidget; if (!Application.isPlaying) { if (widget.GetComponentInParent <GFrame>()) { if (widget.name != "__preview__") { Object parentObject = PrefabUtility.GetPrefabParent(widget); if (parentObject) { string path = AssetDatabase.GetAssetPath(parentObject); GWidget prefab = AssetDatabase.LoadAssetAtPath <GWidget>(path); if (prefab) { //add prefab instance GameObject obj = new GameObject(widget.name); obj.AddComponent <RectTransform>(); GPrefabInstance gpi = obj.AddComponent <GPrefabInstance>(); gpi.prefab = prefab; obj.transform.SetParent(widget.transform.parent, false); obj.transform.SetSiblingIndex(widget.transform.GetSiblingIndex()); gpi.Instantiate(); GameObject.DestroyImmediate(widget.gameObject); } } } } } propertyList = InitExportPropertyList(); eventList = InitExportEventList(); exportToScriptList = InitExportToScriptList(); }
public override void OnInspectorGUI() { serializedObject.Update(); //检查能否同时编辑 bool canMultipleEdit = true; if (serializedObject.isEditingMultipleObjects) { for (int i = 1; i < allTargets.Length; i++) { if (allTargets[i].prefab != firstTarget.prefab) //只有全部是相同的prefab才能同时编辑 { canMultipleEdit = false; } } } if (!canMultipleEdit) { GUILayout.Label("只能同时编辑相同prefab的项"); return; } //Prefab替换功能 EditorGUI.BeginChangeCheck(); EditorGUILayout.BeginHorizontal(); GWidget newPrefab = (GWidget)EditorGUILayout.ObjectField("prefab", firstTarget.prefab, typeof(GWidget), false); bool reload = GUILayout.Button("Reload", GUILayout.Width(60)); if (EditorGUI.EndChangeCheck() || reload) { for (int i = 0; i < allTargets.Length; i++) { if (allTargets[i].preview) { GameObject.DestroyImmediate(allTargets[i].preview.gameObject); allTargets[i].preview = null; } allTargets[i].prefab = newPrefab; allTargets[i].Instantiate(); } } if (GUILayout.Button("Edit", GUILayout.Width(50))) { GWidgetInspector.StartEditWidget(firstTarget.prefab); } EditorGUILayout.EndHorizontal(); //base.OnInspectorGUI(); if (firstTarget.gameObject.scene.name != null) { GWidget prefab = firstTarget.prefab; //属性设置 bool bChangeAnyOne = false; for (int i = 0; i < prefab.propertyInfos.Count; i++) { string propertyName = prefab.propertyInfos[i].propertyName; string key = propertyName; if (prefab.propertyInfos[i].target != prefab.gameObject) //如果属性的目标不是prefab根节点的话,要在key上携带目标节点的名称 { key = prefab.propertyInfos[i].target.name + "." + key; } PropertyInfo pi = null; string[] cn = propertyName.Split('.'); string label = prefab.propertyInfos[i].rename; object defaultValue = null; if (cn.Length == 2) { if (label == "") { label = propertyName; } MonoBehaviour mb = (MonoBehaviour)prefab.propertyInfos[i].target.GetComponent(cn[0]); pi = mb.GetType().GetProperty(cn[1]); defaultValue = pi.GetValue(mb, null); } else if (cn.Length == 1) { pi = prefab.propertyInfos[i].target.GetType().GetProperty(cn[0]); defaultValue = pi.GetValue(prefab.propertyInfos[i].target, null); } if (pi != null) { if (hasMultipleDifferentValues(allTargets, key, pi.PropertyType, defaultValue)) { EditorGUI.showMixedValue = true; } EditorGUI.BeginChangeCheck(); object oldValue = firstTarget.GetValue(key, pi.PropertyType, defaultValue); object newValue = null; if (pi.PropertyType == typeof(bool)) { newValue = EditorGUILayout.Toggle(label, (bool)oldValue); } else if (pi.PropertyType == typeof(string)) { GUILayout.BeginHorizontal(); GUILayout.Label(label, GUILayout.Width(100)); newValue = EditorGUILayout.TextArea((string)oldValue); GUILayout.EndHorizontal(); } else if (pi.PropertyType == typeof(Sprite)) { newValue = EditorGUILayout.ObjectField(label, (Object)oldValue, typeof(Sprite), false); } else if (pi.PropertyType.IsEnum) { newValue = EditorGUILayout.EnumPopup(label, (System.Enum)oldValue); } else if (pi.PropertyType == typeof(GameObject)) { newValue = EditorGUILayout.ObjectField(label, (Object)oldValue, typeof(GameObject), false); } else if (pi.PropertyType == typeof(int)) { newValue = EditorGUILayout.IntField(label, (int)oldValue); } else if (pi.PropertyType == typeof(float)) { newValue = EditorGUILayout.FloatField(label, (float)oldValue); } else if (pi.PropertyType == typeof(Vector2)) { newValue = EditorGUILayout.Vector2Field(label, (Vector2)oldValue); } else if (pi.PropertyType == typeof(Vector3)) { newValue = EditorGUILayout.Vector3Field(label, (Vector3)oldValue); } else if (pi.PropertyType == typeof(string[])) { List <Dropdown.OptionData> opts = oldValue == null ? (new List <Dropdown.OptionData>()) : (List <Dropdown.OptionData>)oldValue; string s = string.Join("\n", (from opt in opts select opt.text).ToArray()); s = EditorGUILayout.TextArea(s, GUILayout.Height(100)); newValue = s == ""?new List <Dropdown.OptionData>():new List <Dropdown.OptionData>(from t in s.Split('\n') select new Dropdown.OptionData(t)); } EditorGUI.showMixedValue = false; if (EditorGUI.EndChangeCheck()) { bChangeAnyOne = true; for (int t = 0; t < allTargets.Length; t++) { allTargets[t].SetValue(key, newValue); } } } } if (bChangeAnyOne) { for (int t = 0; t < allTargets.Length; t++) { allTargets[t].UpdatePreviewValues(allTargets[t].preview); EditorUtility.SetDirty(allTargets[t]); } } if (!serializedObject.isEditingMultipleObjects) { //事件绑定 for (int i = 0; i < prefab.eventInfos.Count; i++) { string[] cn = prefab.eventInfos[i].eventName.Split('.'); if (cn.Length == 2) { string label = prefab.eventInfos[i].rename; GUILayout.BeginHorizontal(); GUILayout.Label(label); GTestAction action = firstTarget.GetAction(prefab.eventInfos[i].eventName, true); if (action != null) { action.actionType = (GExportEventInfo.ActionType)EditorGUILayout.EnumPopup(action.actionType); if (GExportEventInfo.GetTargetNum(action.actionType) == 1) { GUILayout.Label("target:"); action.targetA = (GameObject)EditorGUILayout.ObjectField(action.targetA, typeof(GameObject), true); } else if (GExportEventInfo.GetTargetNum(action.actionType) == 2) { GUILayout.Label("A:"); action.targetA = (GameObject)EditorGUILayout.ObjectField(action.targetA, typeof(GameObject), true); GUILayout.Label("B:"); action.targetB = (GameObject)EditorGUILayout.ObjectField(action.targetB, typeof(GameObject), true); } } GUILayout.EndHorizontal(); } } } } if (!serializedObject.isEditingMultipleObjects) { EditorGUILayout.Space(); EditorGUILayout.TextArea(GetScriptString2(firstTarget)); } }
void ReplaceNode(Transform node, bool debug) { for (int i = 0; i < node.transform.childCount; i++) { ReplaceNode(node.transform.GetChild(0), debug); //每次都处理第一个,因为处理过的会放到最后 } GPrefabInstance loader = node.GetComponent <GPrefabInstance>(); if (loader && loader.prefab) { //实例化 GWidget widget = Instantiate <GWidget>(loader.prefab); targetRedirect[loader.gameObject.GetInstanceID()] = widget.gameObject; widgets.Add(widget); loaders.Add(loader); widget.name = loader.name; widget.transform.SetParent(node.parent, false); //设置大小和位置 (widget.transform as RectTransform).anchorMin = (loader.transform as RectTransform).anchorMin; (widget.transform as RectTransform).anchorMax = (loader.transform as RectTransform).anchorMax; (widget.transform as RectTransform).anchoredPosition = (loader.transform as RectTransform).anchoredPosition; (widget.transform as RectTransform).sizeDelta = (loader.transform as RectTransform).sizeDelta; //更新属性 loader.UpdatePreviewValues(widget); loader.BindTestEvent(widget); if (widget.containerPanel != null) { if (widget.isDynamicContainer && widget.containerPanel.transform.childCount == 1) //如果是动态添加的容器(如邮件列表),并且有一个模板元素 { GDynamicContainer dynamicContainer = widget.containerPanel.GetComponent <GDynamicContainer>(); if (dynamicContainer) { loader.transform.GetChild(0).gameObject.SetActive(false);//第0个元素为模板,隐藏起来 if (debug) { dynamicContainer.AddTestElements();//debug模式下显示一些内容元素 } } } else { while (loader.transform.childCount > 0) { Transform child = loader.transform.GetChild(0); child.SetParent(widget.containerPanel, false);//普通静态容器,将子节点放到容器节点下 } } } else { while (loader.transform.childCount > 0) { loader.transform.GetChild(0).SetParent(widget.transform, false);//非容器,将子节点放到widget节点下 } } widget.gameObject.SetActive(loader.gameObject.activeSelf); Destroy(widget); //将loader从源节点移除 loader.transform.SetParent(null); } else { node.SetAsLastSibling(); } }