Example #1
0
    /// <summary>
    /// Do some actions to GameObject hierachy.
    /// </summary>
    /// <param name="sbLog">The log.</param>
    /// <param name="go">The gameobject.</param>
    /// <param name="tab">The tab.</param>
    /// <param name="op">The operation.</param>
    public static void TraverseGameObject(StringBuilder sbLog, GameObject go, int tab, TraverseOp op)
    {
        for (var t = 0; t < tab; t++)
        {
            sbLog.Append("    ");
        }
        sbLog.AppendFormat("{0}", go.name);

        bool hasChecked = false;
        bool hasReplaced = false;
        bool hasError = false;

        // disconnect prefab instance !!
        if ((op == TraverseOp.CopyMonoBehaviour || op == TraverseOp.RemoveOldBehaviour) 
            && PrefabUtility.GetPrefabType(go) == PrefabType.PrefabInstance)
        {
            PrefabUtility.DisconnectPrefabInstance(go);
        }

        // action!
        switch (op)
        {
            case TraverseOp.CopyMonoBehaviour:
                {
					bool bReplaced = JSSerializerEditor.CopyGameObject(go);
                    if (bReplaced && !hasReplaced)
                    {
                        hasReplaced = true;
                        sbLog.Append(" (REPLACED)");
                    }
                }
                break;
            case TraverseOp.RemoveOldBehaviour:
                {
                    JSSerializerEditor.RemoveOtherMonoBehaviours(go);
                }
                break;
            case TraverseOp.Analyze:
                {
                    var coms = go.GetComponents(typeof(MonoBehaviour));

                    // Calculate MonoBehaviour's Count
                    // Only check scripts that has JsType attribute
                    Dictionary<Type, int> dictMono = new Dictionary<Type, int>();
                    for (var c = 0; c < coms.Length; c++)
                    {
                        MonoBehaviour mb = (MonoBehaviour)coms[c];
						if (mb == null)
						{
							Debug.LogError("Null MonoBehaviour found, gameObject name: " + go.name);
							continue;
						}

                        if (JSSerializerEditor.WillTypeBeTranslatedToJavaScript(mb.GetType()))
                        {
                            if (!dictMono.ContainsKey(mb.GetType()))
                                dictMono.Add(mb.GetType(), 1);
                            else
                                dictMono[mb.GetType()]++;
                        }
                    }
                    foreach (var t in dictMono)
                    {
                        if (!hasChecked)
                        {
                            hasChecked = true;
                            sbLog.Append(" (CHECKED)");
                        }

                        if (t.Value > 1)
                        {
                            if (!hasError) { hasError = true;  sbLog.Append(" ERROR: "); }
                            sbLog.AppendFormat("Same MonoBehaviour more than once. Name: {0}, Count: {1} ", t.Key.Name, t.Value);
                        }
                    }

                    for (var c = 0; c < coms.Length; c++)
                    {
                        MonoBehaviour mb = (MonoBehaviour)coms[c];
						if (mb == null)
						{
							continue;
						}
                        if (JSSerializerEditor.WillTypeBeTranslatedToJavaScript(mb.GetType()))
                        {
                            List<string> lstError = ExamMonoBehaviour(mb);
                            for (var x = 0; x < lstError.Count; x++)
                            {
                                if (!hasError) { hasError = true; sbLog.Append(" ERROR: "); }
                                sbLog.Append(lstError[x] + " ");
                            }
                        }
                    }
                }
                break;
            default:
                break;
        }
        sbLog.Append("\n");

        // traverse children
        var childCount = go.transform.childCount;
        for (var i = 0; i < childCount; i++)
        {
            Transform child = go.transform.GetChild(i);
            TraverseGameObject(sbLog, child.gameObject, tab + 1, op);
        }
    }
Example #2
0
    public static void ReplaceAllMonos()
    {
        bool bContinue = EditorUtility.DisplayDialog("WARNING",
            @"1) This action may cause data loss. You better save current scene and backup whole project before executing this action.
2) Make proper settings to 'JSBindingSettings.PathsNotToCheckOrReplace' field before this action.
3) Execute 'JSB | Check All Monos for all Prefabs and Scenes' menu before this action.
4) Scenes and prefabs whose names begin with '_' will be skipped.", 
            "Continue", 
            "Cancel");

        if (!bContinue)
        {
            Debug.Log("Operation canceled.");
            return;
        }

        DelFilterReplaceFile filter = (path) => 
        {
            // path begins witn Assets/
            var subPath = path.Substring("Assets/".Length);

            // Skip paths in JSBindingSettings.PathsNotToCheckOrReplace
            foreach (var p in JSBindingSettings.PathsNotToCheckOrReplace)
            {
                if (subPath.IndexOf(p) == 0)
                    return true;
            }
            // Skip underscore
            if (FileNameBeginsWithUnderscore(path))
                return true;

            return false;
        };

        var lstPrefabs = GetAllPrefabPaths(filter);
        var lstScenes = GetAllScenePaths(filter);

        var sb = new StringBuilder();
        foreach (var p in lstPrefabs)
        {
            sb.Append(p.Substring("Assets/".Length) + "\r\n");
        }
        foreach (var p in lstScenes)
        {
            sb.Append(p.Substring("Assets/".Length) + "\r\n");
        }
        string fileName = GetTempFileNameFullPath("FilesToReplace.txt");
        File.WriteAllText(fileName, sb.ToString());
        bContinue = EditorUtility.DisplayDialog("TIP",
             "Files list are in " + fileName + ". please verify.", 
             "OK",
             "Cancel");

        if (!bContinue)
        {
            Debug.Log("Operation canceled.");
            return;
        }

        StringBuilder sbCheckLog = new StringBuilder();
        sbCheckLog.Append(@"// Usage
// search 'REPLACED' to see whether a GameObject has been replace or not.

");

        // first copy
        // then remove
        var ops = new TraverseOp[] { TraverseOp.CopyMonoBehaviour, TraverseOp.RemoveOldBehaviour};
        foreach (var op in ops)
        {
            foreach (var p in lstScenes)
            {
                StringBuilder sbLog = new StringBuilder();
                sbLog.AppendFormat("FILE: {0}\n", p);

                EditorApplication.OpenScene(p);
                foreach (var go in SceneRoots())
                {
                    TraverseGameObject(sbLog, go, 0, op);
                }
                EditorApplication.SaveScene();
                sbCheckLog.Append(sbLog + "\n");
            }

            foreach (var p in lstPrefabs)
            {
                StringBuilder sbLog = new StringBuilder();
                sbLog.AppendFormat("FILE: {0}\n", p);

                UnityEngine.Object mainAsset = AssetDatabase.LoadMainAssetAtPath(p);
                if (mainAsset is GameObject)
                {
                    TraverseGameObject(sbLog, (GameObject)mainAsset, 1, op);
                    sbCheckLog.Append(sbLog + "\n");
                }
            }
            EditorApplication.SaveAssets();
        }
        fileName = GetTempFileNameFullPath("ReplaceResult.txt");
        File.WriteAllText(fileName, sbCheckLog.ToString());
        Debug.Log("Replace finished. Output file: " + fileName);
        AssetDatabase.Refresh();
    }
Example #3
0
    public static void CheckAllMonos()
    {
        bool bContinue = EditorUtility.DisplayDialog("WARNING",
            @"1) You mush save current scene before this action.
2) Make proper settings to 'JSBindingSettings.PathsNotToCheckOrReplace' field before this action.
3) Scenes and prefabs whose names begin with '_' will be skipped.",
            "Continue",
            "Cancel");

        if (!bContinue)
        {
            Debug.Log("Operation canceled.");
            return;
        }

        DelFilterReplaceFile filter = (path) =>
        {
            // path begins witn Assets/
            var subPath = path.Substring("Assets/".Length);

            // Skip paths in JSBindingSettings.PathsNotToCheckOrReplace
            foreach (var p in JSBindingSettings.PathsNotToCheckOrReplace)
            {
                if (subPath.IndexOf(p) == 0)
                    return true;
            }
            // Skip underscore
            if (FileNameBeginsWithUnderscore(path))
                return true;

            return false;
        };

        var lstPrefabs = GetAllPrefabPaths(filter);
        var lstScenes = GetAllScenePaths(filter);

        var sb = new StringBuilder();
        foreach (var p in lstPrefabs)
        {
            sb.Append(p.Substring("Assets/".Length) + "\r\n");
        }
        foreach (var p in lstScenes)
        {
            sb.Append(p.Substring("Assets/".Length) + "\r\n");
        }
        string fileName = GetTempFileNameFullPath("CheckList.txt");
        File.WriteAllText(fileName, sb.ToString());
        bContinue = EditorUtility.DisplayDialog("TIP",
             "Files list are in " + fileName + ". please verify.",
             "OK",
             "Cancel");

        if (!bContinue)
        {
            Debug.Log("Operation canceled.");
            return;
        }

        StringBuilder sbCheckLog = new StringBuilder();
        sbCheckLog.Append(@"// Usage
// search 'ERROR' to see if any error occurs.
// search 'CHECKED' to see whether a GameObject has been checked or not. (a GameObject will be checked if he has a MonoBehaviour with JsType attribute)

");

        var ops = new TraverseOp[] { TraverseOp.Analyze };
        foreach (var op in ops)
        {
            foreach (var p in lstScenes)
            {
                StringBuilder sbLog = new StringBuilder();
				Debug.Log("Check Scene: " + p);
                sbLog.AppendFormat("FILE: {0}\n", p);

                EditorApplication.OpenScene(p);
                foreach (var go in SceneRoots())
                {
                    TraverseGameObject(sbLog, go, 1, op);
                }
                EditorApplication.SaveScene();

                sbCheckLog.Append(sbLog + "\n");
            }

            foreach (var p in lstPrefabs)
            {
                UnityEngine.Object mainAsset = AssetDatabase.LoadMainAssetAtPath(p);
                if (mainAsset is GameObject)
                {
					StringBuilder sbLog = new StringBuilder();
					Debug.Log("Check Prefab: " + p);
					sbLog.AppendFormat("FILE: {0}\n", p);

                    TraverseGameObject(sbLog, (GameObject)mainAsset, 1, op);
                    sbCheckLog.Append(sbLog + "\n");
                }
            }
            EditorApplication.SaveAssets();
        }
        fileName = GetTempFileNameFullPath("CheckResult.txt");
        File.WriteAllText(fileName, sbCheckLog.ToString());
        Debug.Log("Check finished. Output file: " + fileName);
        AssetDatabase.Refresh();
    }
Example #4
0
    /// <summary>
    /// Do some actions to GameObject hierachy.
    /// </summary>
    /// <param name="sbLog">The log.</param>
    /// <param name="go">The gameobject.</param>
    /// <param name="tab">The tab.</param>
    /// <param name="op">The operation.</param>
    public static void TraverseGameObject(StringBuilder sbLog, GameObject go, int tab, TraverseOp op)
    {
        for (var t = 0; t < tab; t++)
        {
            sbLog.Append("    ");
        }
        sbLog.AppendFormat("{0}", go.name);

        bool hasChecked  = false;
        bool hasReplaced = false;
        bool hasError    = false;

        // disconnect prefab instance !!
        if ((op == TraverseOp.CopyMonoBehaviour || op == TraverseOp.RemoveOldBehaviour) &&
            PrefabUtility.GetPrefabType(go) == PrefabType.PrefabInstance)
        {
            PrefabUtility.DisconnectPrefabInstance(go);
        }

        // action!
        switch (op)
        {
        case TraverseOp.CopyMonoBehaviour:
        {
            bool bReplaced = JSSerializerEditor.CopyGameObject(go);
            if (bReplaced && !hasReplaced)
            {
                hasReplaced = true;
                sbLog.Append(" (REPLACED)");
            }
        }
        break;

        case TraverseOp.RemoveOldBehaviour:
        {
            JSSerializerEditor.RemoveOtherMonoBehaviours(go);
        }
        break;

        case TraverseOp.Analyze:
        {
            var coms = go.GetComponents(typeof(MonoBehaviour));

            // Calculate MonoBehaviour's Count
            // Only check scripts that has JsType attribute
            Dictionary <Type, int> dictMono = new Dictionary <Type, int>();
            for (var c = 0; c < coms.Length; c++)
            {
                MonoBehaviour mb = (MonoBehaviour)coms[c];
                if (mb == null)
                {
                    CheckHasError = true;
                    Debug.LogError("Null MonoBehaviour found, gameObject name: " + go.name);
                    continue;
                }

                if (JSSerializerEditor.WillTypeBeTranslatedToJavaScript(mb.GetType()))
                {
                    if (!dictMono.ContainsKey(mb.GetType()))
                    {
                        dictMono.Add(mb.GetType(), 1);
                    }
                    else
                    {
                        dictMono[mb.GetType()]++;
                    }
                }
            }
            foreach (var t in dictMono)
            {
                if (!hasChecked)
                {
                    hasChecked = true;
                    sbLog.Append(" (CHECKED)");
                }

                if (t.Value > 1)
                {
                    if (!hasError)
                    {
                        hasError = true;  sbLog.Append(" ERROR: ");
                    }
                    CheckHasError = true;
                    sbLog.AppendFormat("Same MonoBehaviour more than once. Name: {0}, Count: {1} ", t.Key.Name, t.Value);
                }
            }

            for (var c = 0; c < coms.Length; c++)
            {
                MonoBehaviour mb = (MonoBehaviour)coms[c];
                if (mb == null)
                {
                    continue;
                }
                if (JSSerializerEditor.WillTypeBeTranslatedToJavaScript(mb.GetType()))
                {
                    List <string> lstError = ExamMonoBehaviour(mb);
                    if (lstError.Count > 0)
                    {
                        CheckHasError = true;
                    }
                    for (var x = 0; x < lstError.Count; x++)
                    {
                        if (!hasError)
                        {
                            hasError = true; sbLog.Append(" ERROR: ");
                        }
                        sbLog.Append(lstError[x] + " ");
                    }
                }
            }
        }
        break;

        default:
            break;
        }
        sbLog.Append("\n");

        // traverse children
        var childCount = go.transform.childCount;

        for (var i = 0; i < childCount; i++)
        {
            Transform child = go.transform.GetChild(i);
            TraverseGameObject(sbLog, child.gameObject, tab + 1, op);
        }
    }
Example #5
0
    /// <summary>
    /// Iterates all scenes and all prefabs in the project.
    /// Replaces all MonoBehaviours who has JsType attribute with JSComponent!
    /// Care muse be taken when executing this menu.
    /// </summary>
    //[MenuItem("JSB/Replace All Monos for all Prefabs and Scenes", false, 113)]
    public static void ReplaceAllMonos()
    {
        bool bContinue = EditorUtility.DisplayDialog("WARNING",
                                                     @"1) This action may cause data loss. You better save current scene and backup whole project before executing this action.
2) Make proper settings to 'JSBindingSettings.PathsNotToCheckOrReplace' field before this action.
3) Execute 'JSB | Check All Monos for all Prefabs and Scenes' menu before this action.
4) Scenes and prefabs whose names begin with '_' will be skipped.",
                                                     "Continue",
                                                     "Cancel");

        if (!bContinue)
        {
            Debug.Log("Operation canceled.");
            return;
        }

        DelFilterReplaceFile filter = (path) =>
        {
            // path begins witn Assets/
            var subPath = path.Substring("Assets/".Length);

            // Skip paths in JSBindingSettings.PathsNotToCheckOrReplace
            foreach (var p in JSBindingSettings.PathsNotToCheckOrReplace)
            {
                if (subPath.IndexOf(p) == 0)
                {
                    return(true);
                }
            }
            // Skip underscore
            if (FileNameBeginsWithUnderscore(path))
            {
                return(true);
            }

            return(false);
        };

        var lstPrefabs = GetAllPrefabPaths(filter);
        var lstScenes  = GetAllScenePaths(filter);

        var sb = new StringBuilder();

        foreach (var p in lstPrefabs)
        {
            sb.Append(p.Substring("Assets/".Length) + "\r\n");
        }
        foreach (var p in lstScenes)
        {
            sb.Append(p.Substring("Assets/".Length) + "\r\n");
        }
        string fileName = GetTempFileNameFullPath("FilesToReplace.txt");

        File.WriteAllText(fileName, sb.ToString());
        bContinue = EditorUtility.DisplayDialog("TIP",
                                                "Files list are in " + fileName + ". please verify.",
                                                "OK",
                                                "Cancel");

        if (!bContinue)
        {
            Debug.Log("Operation canceled.");
            return;
        }

        StringBuilder sbCheckLog = new StringBuilder();

        sbCheckLog.Append(@"// Usage
// search 'REPLACED' to see whether a GameObject has been replace or not.

");

        // first copy
        // then remove
        var ops = new TraverseOp[] { TraverseOp.CopyMonoBehaviour, TraverseOp.RemoveOldBehaviour };

        foreach (var op in ops)
        {
            foreach (var p in lstScenes)
            {
                StringBuilder sbLog = new StringBuilder();
                sbLog.AppendFormat("FILE: {0}\n", p);

                EditorApplication.OpenScene(p);
                foreach (var go in SceneRoots())
                {
                    TraverseGameObject(sbLog, go, 0, op);
                }
                EditorApplication.SaveScene();
                sbCheckLog.Append(sbLog + "\n");
            }

            foreach (var p in lstPrefabs)
            {
                StringBuilder sbLog = new StringBuilder();
                sbLog.AppendFormat("FILE: {0}\n", p);

                UnityEngine.Object mainAsset = AssetDatabase.LoadMainAssetAtPath(p);
                if (mainAsset is GameObject)
                {
                    TraverseGameObject(sbLog, (GameObject)mainAsset, 1, op);
                    sbCheckLog.Append(sbLog + "\n");
                }
            }
            EditorApplication.SaveAssets();
        }
        fileName = GetTempFileNameFullPath("ReplaceResult.txt");
        File.WriteAllText(fileName, sbCheckLog.ToString());
        Debug.Log("Replace finished. Output file: " + fileName);
        AssetDatabase.Refresh();
    }
Example #6
0
    /// <summary>
    /// Iterates all scenes and all prefabs in the project.
    /// Checks all MonoBehaviours who has JsType attribute.
    /// Save current scene before this action.
    /// 3 things will be checked:
    /// 1) Did you bind a MonoBehaviour(with JsType attribute) to a GameObject twice or more? (Support only one)
    /// 2) Did your MonoBehaviour(with JsType attribute) refer to other MonoBehaviour that is not available in JavaScript?
    /// 3) Did your MonoBehaviour(with JsType attribute) have not-supported public fields? (List, for example)
    /// </summary>
    //[MenuItem("JSB/Check All Monos for all Prefabs and Scenes", false, 112)]

    // 返回值:是否继续下一步
    public static bool CheckAllMonos()
    {
        bool bContinue = EditorUtility.DisplayDialog("WARNING",
                                                     @"1) You mush save current scene before this action.
2) Make proper settings to 'JSBindingSettings.PathsNotToCheckOrReplace' field before this action.
3) Scenes and prefabs whose names begin with '_' will be skipped.",
                                                     "Continue",
                                                     "Cancel");

        if (!bContinue)
        {
            Debug.Log("Operation canceled.");
            return(false);
        }

        DelFilterReplaceFile filter = (path) =>
        {
            // path begins witn Assets/
            var subPath = path.Substring("Assets/".Length);

            // Skip paths in JSBindingSettings.PathsNotToCheckOrReplace
            foreach (var p in JSBindingSettings.PathsNotToCheckOrReplace)
            {
                if (subPath.IndexOf(p) == 0)
                {
                    return(true);
                }
            }
            // Skip underscore
            if (FileNameBeginsWithUnderscore(path))
            {
                return(true);
            }

            return(false);
        };

        var lstPrefabs = GetAllPrefabPaths(filter);
        var lstScenes  = GetAllScenePaths(filter);

        var sb = new StringBuilder();

        foreach (var p in lstPrefabs)
        {
            sb.Append(p.Substring("Assets/".Length) + "\r\n");
        }
        foreach (var p in lstScenes)
        {
            sb.Append(p.Substring("Assets/".Length) + "\r\n");
        }
        string fileName = GetTempFileNameFullPath("CheckList.txt");

        File.WriteAllText(fileName, sb.ToString());

        bContinue = EditorUtility.DisplayDialog("TIP",
                                                "Files list are in " + fileName + ". please verify.",
                                                "OK",
                                                "Cancel");

        if (!bContinue)
        {
            Debug.Log("Operation canceled.");
            return(false);
        }

        StringBuilder sbCheckLog = new StringBuilder();

        sbCheckLog.Append(@"// Usage
// search 'ERROR' to see if any error occurs.
// search 'CHECKED' to see whether a GameObject has been checked or not. (a GameObject will be checked if he has a MonoBehaviour with JsType attribute)

");

        CheckHasError = false;
        var ops = new TraverseOp[] { TraverseOp.Analyze };

        foreach (var op in ops)
        {
            // 遍历所有场景
            foreach (var p in lstScenes)
            {
                StringBuilder sbLog = new StringBuilder();
                Debug.Log("Check Scene: " + p);
                sbLog.AppendFormat("FILE: {0}\n", p);

                EditorApplication.OpenScene(p);
                foreach (var go in SceneRoots())
                {
                    TraverseGameObject(sbLog, go, 1, op);
                }
                EditorApplication.SaveScene();

                sbCheckLog.Append(sbLog + "\n");
            }

            // 遍历所有Prefab
            foreach (var p in lstPrefabs)
            {
                UnityEngine.Object mainAsset = AssetDatabase.LoadMainAssetAtPath(p);
                if (mainAsset is GameObject)
                {
                    StringBuilder sbLog = new StringBuilder();
                    Debug.Log("Check Prefab: " + p);
                    sbLog.AppendFormat("FILE: {0}\n", p);

                    TraverseGameObject(sbLog, (GameObject)mainAsset, 1, op);
                    sbCheckLog.Append(sbLog + "\n");
                }
            }
            EditorApplication.SaveAssets();
        }

        fileName = GetTempFileNameFullPath("CheckResult.txt");
        File.WriteAllText(fileName, sbCheckLog.ToString());
        Debug.Log("Check finished. Output file: " + fileName);
        AssetDatabase.Refresh();

        Debug.Log("CheckAllMonos has error: " + (CheckHasError ? "YES" : "NO"));

        return(!CheckHasError);
    }