using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
using SpacePlayer;
using System.IO;
using System.Xml;
using System;
using System.Text;
using Ionic.Zip;
using System.Collections;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEditor.SceneManagement;
using SimpleFileBrowser;
using Wormhole;

public class SPEditor_SpaceSource : MonoBehaviour
{
    public  static BaseSpace space;

    static string formworkPath = "ISPlayer/Sample/Scenes/Formwork.unity";
    static SpaceSourceObj  curMainSrc;

    static  Transform srcTran;
    static int actorCount = 0;
    static int srcActorCount = 0;
    static Transform  actorsParent;
    static Transform behaviorsParent;
    static Transform datumDriversParent;

    static AssetBundle spaceObjBundle;


    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/导入许可", false, 30)]
    private static void ImportSpaceObj()
    {
        string path = EditorUtility.OpenFilePanelWithFilters("选择目标空间许可文件",System.Environment .GetFolderPath(Environment.SpecialFolder.Desktop),
            new string[] {"SpaceLicense", "lic" } );

        if (!string.IsNullOrEmpty(path))
        {
            FileInfo fi = new FileInfo(path);
            if (!fi.Exists)
            {
                return;
            }

            fi = new FileInfo(Path.Combine(Application.streamingAssetsPath, "Config.json"));
            if (fi.Exists)
            {
                if (EditorUtility.DisplayDialog("警告", "工程内已经包含许可证，确定导入将覆盖旧许可证，不可撤销，你确定导入新许可证吗？", "确定", "取消"))
                {
                    ImportLicense(path);
                    EditorUtility.DisplayDialog("提示", "许可证导入完毕", "确定");
                }
                else
                {
                    EditorUtility.DisplayDialog("提示", "许可证导入完毕", "确定");
                }
            }
            else
            {
                ImportLicense(path);
                EditorUtility.DisplayDialog("提示", "许可证导入完毕", "确定");

            }                
        }
    }

    /// <summary>
    /// 导入证书
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    public static bool ImportLicense(string path)
    {
        using (ZipFile zip = ZipFile.Read(path))
        {
            if (zip != null && zip.Count > 0)
            {
                //int i = 0;
                foreach (ZipEntry zEntry in zip)
                {
                    zEntry.Extract(Application.streamingAssetsPath, ExtractExistingFileAction.OverwriteSilently);
                }
            }
        }

        return true;
    }


    static bool GettingBaseConditionForCreatingActor(string compType)
    {
        SpaceSourceObj sso = FindObjectOfType<SpaceSourceObj>();
        if (srcTran == null && sso !=null )
            srcTran = sso.transform;
        if(srcTran == null )
            return false;

        if (actorsParent ==null)
        {
            actorsParent = srcTran.Find("ActorsParent");
            if (actorsParent == null)
            {
                actorsParent = new GameObject().transform;
                actorsParent.SetParent(srcTran);
                actorsParent.name = "ActorsParent";
            }
        }

        if (behaviorsParent == null)
        {
            behaviorsParent = srcTran.Find("BehaviorsParent");
            if (behaviorsParent == null)
            {
                behaviorsParent = new GameObject().transform;
                behaviorsParent.SetParent(srcTran);
                behaviorsParent.localPosition = Vector3.zero;
                behaviorsParent.localEulerAngles = Vector3.zero;
                behaviorsParent.name = "BehaviorsParent";
            }
        }

        return true;
    }


    static bool GettingBaseConditionForSettingAsActor(string compType)
    {
        SpaceSourceObj sso = FindObjectOfType<SpaceSourceObj>();
        if (srcTran == null && sso != null)
            srcTran = sso.transform;
        if (srcTran == null) 
            return false;     //至少有一个CustomSceneSrc

        if (Selection.activeGameObject == null) return false;     //至少有一个选择物

        if (Selection.activeGameObject.GetComponent(compType) != null) return false;     //所选物体必须为资源内物体

        return true;
    }



    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/新建空间播放资源", true, 51)]
    private static bool NewSpaceSourceObjValidateFunc()
    {
        //检查是否有配置文件
        FileInfo fi = new FileInfo(Path.Combine(Application.streamingAssetsPath, "Config.json"));
        if (!fi.Exists)
        {
            return false;
        }

        if(space == null )
            space = SpacePlayerLicUtility.ParseSpace(false);
        
        if (space == null)
            return false;
        else  
            return true;
    }

    [MenuItem("SpacePlayer/前景主体/新建空间播放资源", false ,51)]
    static void NewSpaceSourceObj()
    {
        string newSourcePath = SPEditor_GeneralTools.CreateFormwork(formworkPath);
        if (string.IsNullOrEmpty(newSourcePath))
        {
            Debug.Log("资源创建失败");
            return;   //创建失败则停止创建
        }

        ////解析基础Space空间
        //space = ImageSpacePlayer.SpacePlayerLicUtility.ParseSpace(false);

        //往场景中添加空间基座
        GameObject spacePivotRoot = GameObject.Find("SpacePivotRoot");
        if (spacePivotRoot == null)
        {
            spacePivotRoot = new GameObject();
            spacePivotRoot.name = "SpacePivotRoot";
        }


        //往场景中添加初始内容
        GameObject srcRootObj = new GameObject();
        srcRootObj.name = Path.GetFileNameWithoutExtension(newSourcePath);
        srcTran = srcRootObj.transform;
        srcTran.SetParent(spacePivotRoot.transform );

        curMainSrc = srcTran.gameObject.AddComponent<SpaceSourceObj>();
        //srcTran.gameObject.AddComponent<SpaceSetting>();

        //创建摄像机容器物体
        actorsParent = new GameObject().transform ;
        actorsParent.name = "ActorsParent";
        actorsParent.SetParent ( srcTran);

        SpacePlayerManager player = FindObjectOfType<SpacePlayerManager>();

        if (space != null)
        {
            spacePivotRoot.transform.position = space.position;
            spacePivotRoot.transform.localEulerAngles = space.localEulur;

            //SPEditor_GeneralTools. LoadBundleInBaseSpaceAndInstantiate(space,player,curMainSrc .transform );
        }

        //创建Prefab
        SPEditor_GeneralTools.CreatePrefabAndAssetBundle(curMainSrc.gameObject, newSourcePath, "sps");

        // 注册撤销操作
        Undo.RegisterCreatedObjectUndo(spacePivotRoot, "Create Base GameObject");

        UnityEditor.SceneManagement.EditorSceneManager.SaveOpenScenes();

        Selection.activeGameObject = curMainSrc.gameObject;
    }


    [MenuItem("SpacePlayer/前景主体/自定义镜头设置", true, 101)]
    private static bool SetCustomCameraParamValidateFunc()
    {
        if (curMainSrc == null)
        {
            curMainSrc = FindObjectOfType<SpaceSourceObj>();      
        }
        if (curMainSrc == null)
            return false;

        //检查是否有配置文件
        FileInfo fi = new FileInfo(Path.Combine(Application.streamingAssetsPath, "Config.json"));
        if (!fi.Exists)
        {
            return false;
        }

        if (space == null)
            space = SpacePlayerLicUtility.ParseSpace(false);

        if (space == null)
            return false;
        else
            return true;
    }

    [MenuItem("SpacePlayer/前景主体/自定义镜头设置", false, 101)]
    static void SetCustomCameraParam()
    {
        //往场景中添加初始内容
        GameObject spaceCameraSettingGO = new GameObject();
        spaceCameraSettingGO.name = "SpaceCameraSetting";
        spaceCameraSettingGO.transform.SetParent(curMainSrc.transform);
        spaceCameraSettingGO.transform.localPosition = Vector3.zero;
        spaceCameraSettingGO.transform.localEulerAngles = Vector3.zero;
        spaceCameraSettingGO.transform.localScale = Vector3.one;

        SpaceSetting spaceCameraSetting = spaceCameraSettingGO.AddComponent<SpaceSetting >();

        GameObject spaceRefCameraGO = new GameObject();
        spaceRefCameraGO.name = "SpaceRefCamera";
        spaceRefCameraGO.transform.SetParent(spaceCameraSettingGO.transform );
        spaceRefCameraGO.transform.localScale = Vector3.one;
        spaceRefCameraGO.transform.position = space.cameraPosition;
        spaceRefCameraGO.transform.localEulerAngles = space.cameraLocalEulur;

        Camera spaceRefCamera = spaceRefCameraGO.AddComponent<Camera >();
        spaceRefCamera.fieldOfView = space.camFOV;

        spaceCameraSetting.refParamCamera = spaceRefCamera;

        // 注册撤销操作
        Undo.RegisterCreatedObjectUndo(spaceCameraSettingGO, "Create SpaceCameraSetting GameObject");
        UnityEditor.SceneManagement.EditorSceneManager.SaveOpenScenes();
        Selection.activeGameObject = spaceCameraSettingGO.gameObject;
    }




    [MenuItem("SpacePlayer/前景主体/为资源自定义内置背景空间", true, 102)]
    private static bool AddSpaceObjValidateFunc()
    {
        if (curMainSrc == null)
        {
            curMainSrc = FindObjectOfType<SpaceSourceObj>();
        }
        if (curMainSrc == null)
            return false;

        //检查是否有配置文件
        FileInfo fi = new FileInfo(Path.Combine(Application.streamingAssetsPath, "Config.json"));
        if (!fi.Exists)
        {
            return false;
        }

        if (space == null)
            space = SpacePlayerLicUtility.ParseSpace(false);

        if (space == null)
            return false;
        else
            return true;
    }

    [MenuItem("SpacePlayer/前景主体/为资源自定义内置背景空间", false, 102)]
    static void AddSpaceObj()
    {
        //先检查场景是否已经包含内置空间
        SimpleSpaceObj sso = curMainSrc.GetComponentInChildren<SimpleSpaceObj>();
        if (sso != null)
        {
            if (EditorUtility.DisplayDialog("已存在背景空间", "场景中已存在背景空间，是否覆盖", "覆盖", "取消"))
            {
                Undo.DestroyObjectImmediate(sso.gameObject);
            }
            else
            {
                Debug.Log("取消创建内置背景空间");
                return;
            }
        }

        //往场景中添加初始内容
        GameObject spaceFrame = new GameObject();
        spaceFrame.name = "SpaceFrame";
        spaceFrame.transform.SetParent(curMainSrc.transform);
        spaceFrame.transform.localPosition = Vector3.zero;
        spaceFrame.transform.localEulerAngles = Vector3.zero;
        spaceFrame.transform.localScale  = Vector3.one;

        GameObject wallRoot = new GameObject();
        wallRoot.name = "BGWallRoot";
        wallRoot.transform .SetParent(spaceFrame.transform);
        wallRoot.transform.localPosition = Vector3.zero;
        wallRoot.transform.localEulerAngles = Vector3.zero;
        wallRoot.transform.localScale = Vector3.one;

        GameObject edgeRoot = new GameObject();
        edgeRoot.name = "EdgeRoot";
        edgeRoot.transform .SetParent(spaceFrame.transform);
        wallRoot.transform.localPosition = Vector3.zero;
        wallRoot.transform.localEulerAngles = Vector3.zero;
        wallRoot.transform.localScale = Vector3.one;

        spaceFrame.gameObject.AddComponent<SimpleSpaceObj>();

        // 注册撤销操作
        Undo.RegisterCreatedObjectUndo(spaceFrame, "Create Base GameObject");
        UnityEditor.SceneManagement.EditorSceneManager.SaveOpenScenes();
        Selection.activeGameObject = spaceFrame.gameObject;
    }



    [MenuItem("SpacePlayer/前景主体/根据所选母版Prefab为资源创建内置背景空间", true, 103)]
    private static bool CopySpaceObjValidateFunc()
    {
        if (curMainSrc == null)
        {
            curMainSrc = FindObjectOfType<SpaceSourceObj>();
        }
        if (Selection.activeObject == null)
            return false ;

        if (!(Selection.activeObject is GameObject))
            return false;

        if ((Selection.activeObject as GameObject).GetComponent<SPSpaceObj>() == null)
            return false;
        
        return true;
    }

    [MenuItem("SpacePlayer/前景主体/根据所选母版Prefab为资源创建内置背景空间", false, 103)]
    static void CopySpaceObj()
    {
        //先检查场景是否已经包含内置空间
        SimpleSpaceObj sso = curMainSrc.GetComponentInChildren<SimpleSpaceObj>();
        if (sso != null)
        {
            if (EditorUtility.DisplayDialog("已存在背景空间", "场景中已存在背景空间，是否覆盖", "覆盖", "取消"))
            {
                Undo.DestroyObjectImmediate(sso.gameObject);
            }
            else
            {
                Debug.Log("取消创建内置背景空间");
                return;
            }
        }

        //往场景中添加空间基座
        GameObject spacePivotRoot = GameObject.Find("SpacePivotRoot");
        if (spacePivotRoot == null)
        {
            spacePivotRoot = new GameObject();
            spacePivotRoot.name = "SpacePivotRoot";
        }

        //Prefab加载
        GameObject prefab = Selection.activeObject as GameObject;
        if (prefab == null || PrefabUtility.GetPrefabAssetType(prefab) != PrefabAssetType.Regular)
        {
            Debug.LogError("Please select a valid prefab to instantiate and break connection.");
            return;
        }

        // 在场景中实例化Prefab
        GameObject spaceFrame = PrefabUtility.InstantiatePrefab(prefab, curMainSrc .transform) as GameObject;
        spaceFrame.name = "SpaceFrame";   // Path.GetFileNameWithoutExtension(newSourcePath);
        sso = spaceFrame.GetComponent<SimpleSpaceObj>();
        if (sso == null)
        {
            sso = spaceFrame.AddComponent<SimpleSpaceObj>();
        }

        // 打断Prefab连接
        PrefabUtility.UnpackPrefabInstance(spaceFrame, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction);


        // 注册撤销操作
        Undo.RegisterCreatedObjectUndo(spaceFrame, "Create Base GameObject");

        UnityEditor.SceneManagement.EditorSceneManager.SaveOpenScenes();

        Selection.activeGameObject = spaceFrame;
        EditorUtility.DisplayDialog("提示", "从背景空间模板Prefab为资源创建背景空间完成，请根据需要继续编辑", "确定");
    }



    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/响应行为/新建", true, 148)]
    private static bool NewBehaviorValidateFunc()
    {
        return GettingBaseConditionForCreatingActor("SpaceSrcBehaviour");
    }
    [MenuItem("SpacePlayer/前景主体/响应行为/新建", false, 148)]
    private static void NewBehavior()
    {
        GameObject go = new GameObject();
        go.name = "Behaviour";
        go.transform.SetParent(behaviorsParent);
        go.transform.localPosition = Vector3.zero;
        go.transform.localEulerAngles = Vector3.zero;
        go.AddComponent<SpaceSrcBehaviour>();

        // 注册撤销操作
        Undo.RegisterCreatedObjectUndo(go, "Create Behaviour");
        Selection.activeGameObject = go;
    }

    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/响应行为/设置所选", true, 149)]
    private static bool SetAsBehaviorValidateFunc()
    {
        return GettingBaseConditionForSettingAsActor("SpaceSrcBehaviour");
    }
    [MenuItem("SpacePlayer/前景主体/响应行为/设置所选", false, 149)]
    private static void SetAsBehavior()
    {
        if(Selection.objects != null && Selection.objects.Length > 1)
        {
            for (int i = 0; i < Selection.objects.Length; i++)
            {
                ((GameObject)Selection.objects[i]).AddComponent<SpaceSrcBehaviour>();
            }
        }
        else 
            Selection.activeGameObject.AddComponent<SpaceSrcBehaviour>();
    }




    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/点击交互物体/新建", true, 150)]
    private static bool NewActorValidateFunc()
    {
        return GettingBaseConditionForCreatingActor("CommonClickableTrigger");
    }
    [MenuItem("SpacePlayer/前景主体/点击交互物体/新建", false, 150)]
    private static void NewActor()
    {
        GameObject go = new GameObject();
        go.name = "ClickableTrigger";
        go.transform.SetParent(actorsParent);
        go.transform.localPosition = Vector3.zero;
        go.transform.localEulerAngles = Vector3.zero;
        CommonClickableTrigger trigger = go.AddComponent<CommonClickableTrigger>();

        SpaceSrcBehaviour spaceSrcBehaviour = go.AddComponent<SpaceSrcBehaviour>();
        trigger.triggeredBehaviour = spaceSrcBehaviour;

        // 注册撤销操作
        Undo.RegisterCreatedObjectUndo(go, "Create Actor");
        Selection.activeGameObject = go;
    }

    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/点击交互物体/设置所选", true, 151)]
    private static bool SetAsActorValidateFunc()
    {
        return GettingBaseConditionForSettingAsActor("CommonClickableTrigger");
    }
    [MenuItem("SpacePlayer/前景主体/点击交互物体/设置所选", false, 151)]
    private static void SetAsActor()
    {
        CommonClickableTrigger trigger = Selection.activeGameObject.AddComponent<CommonClickableTrigger>();
        SpaceSrcBehaviour spaceSrcBehaviour = Selection.activeGameObject.AddComponent<SpaceSrcBehaviour>();
        trigger.triggeredBehaviour = spaceSrcBehaviour;
    }



    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/点击切换状态物体/新建", true, 152)]
    private static bool NewSwitcherValidateFunc()
    {
        return GettingBaseConditionForCreatingActor("CommonSwitchStatusTrigger");
    }


    [MenuItem("SpacePlayer/前景主体/点击切换状态物体/新建", false, 152)]
    private static void NewSwitcher()
    {
        GameObject go = new GameObject();
        go.name = "SwitchStatusTrigger";
        go.transform.SetParent(actorsParent);
        go.transform.localPosition = Vector3.zero;
        go.transform.localEulerAngles = Vector3.zero;
        CommonSwitchStatusTrigger trigger = go.AddComponent<CommonSwitchStatusTrigger>();

        SpaceSrcBehaviour spaceSrcBehaviour = go.AddComponent<SpaceSrcBehaviour>();
        trigger.triggeredBehaviour = spaceSrcBehaviour;

        // 注册撤销操作
        Undo.RegisterCreatedObjectUndo(go, "Create Actor");
        Selection.activeGameObject = go;
    }

    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/点击切换状态物体/设置所选", true, 153)]
    private static bool SetAsSwitcherValidateFunc()
    {
        return GettingBaseConditionForSettingAsActor("CommonSwitchStatusTrigger");
    }


    [MenuItem("SpacePlayer/前景主体/点击切换状态物体/设置所选", false, 153)]
    private static void SetAsSwitcher()
    {
        CommonSwitchStatusTrigger trigger = Selection.activeGameObject.AddComponent<CommonSwitchStatusTrigger>();
        SpaceSrcBehaviour spaceSrcBehaviour = Selection.activeGameObject.AddComponent<SpaceSrcBehaviour>();
        trigger.triggeredBehaviour = spaceSrcBehaviour;
    }


    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/按住拖动旋转物体/新建", true, 154)]
    private static bool NewCommonRotatableTriggerValidateFunc()
    {
        return GettingBaseConditionForCreatingActor("CommonRotatableTrigger");
    }


    [MenuItem("SpacePlayer/前景主体/按住拖动旋转物体/新建", false, 154)]
    private static void NewCommonRotatableTrigger()
    {
        GameObject go = new GameObject();
        go.name = "CommonRotatableTrigger";
        go.transform.SetParent(actorsParent);
        go.transform.localPosition = Vector3.zero;
        go.transform.localEulerAngles = Vector3.zero;
        CommonRotatableTrigger trigger = go.AddComponent<CommonRotatableTrigger>();

        SpaceSrcBehaviour spaceSrcBehaviour = go.AddComponent<SpaceSrcBehaviour>();
        trigger.triggeredBehaviour = spaceSrcBehaviour;

        // 注册撤销操作
        Undo.RegisterCreatedObjectUndo(go, "Create Actor");
        Selection.activeGameObject = go;
    }

    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/按住拖动旋转物体/设置所选", true, 155)]
    private static bool SetAsCommonRotatableTriggerValidateFunc()
    {
        return GettingBaseConditionForSettingAsActor("CommonRotatableTrigger");
    }


    [MenuItem("SpacePlayer/前景主体/按住拖动旋转物体/设置所选", false, 155)]
    private static void SetAsCommonRotatableTrigger()
    {
        CommonRotatableTrigger trigger = Selection.activeGameObject.AddComponent<CommonRotatableTrigger>();
        SpaceSrcBehaviour spaceSrcBehaviour = Selection.activeGameObject.AddComponent<SpaceSrcBehaviour>();
        trigger.triggeredBehaviour = spaceSrcBehaviour;
    }




    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/拖至目标触发器/新建", true, 161)]
    private static bool NewDraggerValidateFunc()
    {
        return GettingBaseConditionForCreatingActor("CommonHoldableTriggerForTarget");
    }


    [MenuItem("SpacePlayer/前景主体/拖至目标触发器/新建", false, 161)]
    private static void NewDragger()
    {
        GameObject go = new GameObject();
        go.name = "HoldableTriggerForTarget";
        go.transform.SetParent(actorsParent);
        go.transform.localPosition = Vector3.zero;
        go.transform.localEulerAngles = Vector3.zero;
        CommonHoldableTriggerForTarget trigger = go.AddComponent<CommonHoldableTriggerForTarget>();

        SpaceSrcBehaviour spaceSrcBehaviour = go.AddComponent<SpaceSrcBehaviour>();
        trigger.triggeredBehaviour = spaceSrcBehaviour;

        // 注册撤销操作
        Undo.RegisterCreatedObjectUndo(go, "Create Actor");
        Selection.activeGameObject = go;
    }


    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/拖至目标触发器/设置所选", true, 162)]
    private static bool SetAsDaggerValidateFunc()
    {
        return GettingBaseConditionForSettingAsActor("CommonHoldableTriggerForTarget");
    }


    [MenuItem("SpacePlayer/前景主体/拖至目标触发器/设置所选", false, 162)]
    private static void SetAsDagger()
    {
        CommonHoldableTriggerForTarget trigger = Selection.activeGameObject.AddComponent<CommonHoldableTriggerForTarget>();
        SpaceSrcBehaviour spaceSrcBehaviour = Selection.activeGameObject.AddComponent<SpaceSrcBehaviour>();
        trigger.triggeredBehaviour = spaceSrcBehaviour;
    }

    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/拖至目标触发器目标位置/新建", true, 163)]
    private static bool NewTargetPlaceValidateFunc()
    {
        return GettingBaseConditionForCreatingActor("CommonHoldableTriggerForTargetTargetPlace");
    }


    [MenuItem("SpacePlayer/前景主体/拖至目标触发器目标位置/新建", false, 163)]
    private static void NewTargetPlace()
    {
        GameObject go = new GameObject();
        go.name = "HoldableTriggerForTarget";
        go.transform.SetParent(actorsParent);
        go.transform.localPosition = Vector3.zero;
        go.transform.localEulerAngles = Vector3.zero;
        CommonHoldableTriggerForTargetTargetPlace trigger = go.AddComponent<CommonHoldableTriggerForTargetTargetPlace>();

        if (Selection.activeGameObject != null)
        {
            CommonHoldableTriggerForTarget chtft = Selection.activeGameObject.GetComponent<CommonHoldableTriggerForTarget>();
            if(chtft!= null )
            {
                CommonHoldableTriggerForTargetTargetPlace[] places = new CommonHoldableTriggerForTargetTargetPlace[chtft.targetPlaces.Length + 1];
                for (int i = 0,length = chtft .targetPlaces.Length ; i < length; i++)
                {
                    places[i] = chtft.targetPlaces[i];
                }
                places[places.Length - 1] = trigger;
                chtft.targetPlaces = places;
            }
        }

        // 注册撤销操作
        Undo.RegisterCreatedObjectUndo(go, "Create Actor");
        Selection.activeGameObject = go;
    }

    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/拖至目标触发器目标位置/设置所选", true, 164)]
    private static bool SetAsTargetPlaceValidateFunc()
    {
        return GettingBaseConditionForSettingAsActor("CommonHoldableTriggerForTargetTargetPlace");
    }


    [MenuItem("SpacePlayer/前景主体/拖至目标触发器目标位置/设置所选", false, 164)]
    private static void SetAsTargetPlace()
    {
        CommonHoldableTriggerForTargetTargetPlace trigger = Selection.activeGameObject.AddComponent<CommonHoldableTriggerForTargetTargetPlace>();
    }

    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/长按触发器/新建", true, 165)]
    private static bool NewHolderValidateFunc()
    {
        return GettingBaseConditionForCreatingActor("CommonHoldableTriggerForDuration");
    }


    [MenuItem("SpacePlayer/前景主体/长按触发器/新建", false, 165)]
    private static void NewHolder()
    {
        GameObject go = new GameObject();
        go.name = "HoldableTriggerForDuration";
        go.transform.SetParent(actorsParent);
        go.transform.localPosition = Vector3.zero;
        go.transform.localEulerAngles = Vector3.zero;
        CommonHoldableTriggerForDuration trigger = go.AddComponent<CommonHoldableTriggerForDuration>();

        SpaceSrcBehaviour spaceSrcBehaviour = go.AddComponent<SpaceSrcBehaviour>();
        trigger.triggeredBehaviour = spaceSrcBehaviour;

        // 注册撤销操作
        Undo.RegisterCreatedObjectUndo(go, "Create Actor");
        Selection.activeGameObject = go;
    }


    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/长按触发器/设置所选", true, 166)]
    private static bool SetAsHolderValidateFunc()
    {
        return GettingBaseConditionForSettingAsActor("CommonHoldableTriggerForDuration");
    }


    [MenuItem("SpacePlayer/前景主体/长按触发器/设置所选", false, 166)]
    private static void SetAsHolder()
    {
        CommonHoldableTriggerForDuration trigger = Selection.activeGameObject.AddComponent<CommonHoldableTriggerForDuration>();
        SpaceSrcBehaviour spaceSrcBehaviour = Selection.activeGameObject.AddComponent<SpaceSrcBehaviour>();
        trigger.triggeredBehaviour = spaceSrcBehaviour;
    }


    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/拖动位置触发器/新建", true, 167)]
    private static bool NewPositionHolderValidateFunc()
    {
        return GettingBaseConditionForCreatingActor("CommonHoldableTriggerForPosition");
    }


    [MenuItem("SpacePlayer/前景主体/拖动位置触发器/新建", false, 167)]
    private static void NewPositionHolder()
    {
        GameObject go = new GameObject();
        go.name = "HoldableTriggerForPosition";
        go.transform.SetParent(actorsParent);
        go.transform.localPosition = Vector3.zero;
        go.transform.localEulerAngles = Vector3.zero;
        CommonHoldableTriggerForPosition trigger = go.AddComponent<CommonHoldableTriggerForPosition>();

        SpaceSrcBehaviour spaceSrcBehaviour = go.AddComponent<SpaceSrcBehaviour>();
        trigger.triggeredBehaviour = spaceSrcBehaviour;

        // 注册撤销操作
        Undo.RegisterCreatedObjectUndo(go, "Create Actor");
        Selection.activeGameObject = go;
    }


    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/拖动位置触发器/设置所选", true, 168)]
    private static bool SetAsPositionHolderValidateFunc()
    {
        return GettingBaseConditionForSettingAsActor("CommonHoldableTriggerForPosition");
    }


    [MenuItem("SpacePlayer/前景主体/拖动位置触发器/设置所选", false, 168)]
    private static void SetAsPositionHolder()
    {
        CommonHoldableTriggerForPosition trigger = Selection.activeGameObject.AddComponent<CommonHoldableTriggerForPosition>();
        SpaceSrcBehaviour spaceSrcBehaviour = Selection.activeGameObject.AddComponent<SpaceSrcBehaviour>();
        trigger.triggeredBehaviour = spaceSrcBehaviour;
    }



    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/拖动角度触发器/新建", true, 169)]
    private static bool NewAngleHolderValidateFunc()
    {
        return GettingBaseConditionForCreatingActor("CommonHoldableTriggerForAngle");
    }


    [MenuItem("SpacePlayer/前景主体/拖动角度触发器/新建", false, 169)]
    private static void NewAngleHolder()
    {
        GameObject go = new GameObject();
        go.name = "HoldableTriggerForAngle";
        go.transform.SetParent(actorsParent);
        go.transform.localPosition = Vector3.zero;
        go.transform.localEulerAngles = Vector3.zero;
        CommonHoldableTriggerForAngle trigger = go.AddComponent<CommonHoldableTriggerForAngle>();

        SpaceSrcBehaviour spaceSrcBehaviour = go.AddComponent<SpaceSrcBehaviour>();
        trigger.triggeredBehaviour = spaceSrcBehaviour;

        // 注册撤销操作
        Undo.RegisterCreatedObjectUndo(go, "Create Actor");
        Selection.activeGameObject = go;
    }


    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/拖动角度触发器/设置所选", true, 170)]
    private static bool SetAsAngleHolderValidateFunc()
    {
        return GettingBaseConditionForSettingAsActor("CommonHoldableTriggerForAngle");
    }


    [MenuItem("SpacePlayer/前景主体/拖动角度触发器/设置所选", false, 170)]
    private static void SetAsAngleHolder()
    {
        CommonHoldableTriggerForAngle trigger = Selection.activeGameObject.AddComponent<CommonHoldableTriggerForAngle>();
        SpaceSrcBehaviour spaceSrcBehaviour = Selection.activeGameObject.AddComponent<SpaceSrcBehaviour>();
        trigger.triggeredBehaviour = spaceSrcBehaviour;
    }

    ////////////////////////////////////以下为数据相关////////////////////////////////


    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/添加数据抓取器", true, 250)]
    private static bool NewDataCatcherValidateFunc()
    {
        if (curMainSrc == null)
        {
            curMainSrc = FindObjectOfType<SpaceSourceObj>();
        }
        if(curMainSrc == null ) 
            return false;
        if (curMainSrc.GetComponent<DataCatcher>()) 
            return false;
        return true;
    }


    [MenuItem("SpacePlayer/前景主体/添加数据抓取器", false, 250)]
    private static void NewDataCatcher()
    {
        curMainSrc.gameObject.AddComponent<DataCatcher>();

        // 注册撤销操作
        Undo.RegisterCreatedObjectUndo(curMainSrc.gameObject, "Create DataCatcher");
        Selection.activeGameObject = curMainSrc.gameObject;
    }


    static bool GettingBaseConditionForCreatingDatumDriver(string compType)
    {
        if (srcTran == null)
        {
            SpaceSourceObj t = FindObjectOfType<SpaceSourceObj>();
            if(t != null )
                srcTran = t.transform;
        }
        if (srcTran == null)
            return false;

        if (datumDriversParent == null)
        {
            datumDriversParent = srcTran.Find("DatumDriversParent");
            if (datumDriversParent == null)
            {
                datumDriversParent = new GameObject().transform;
                datumDriversParent.SetParent(srcTran);
                datumDriversParent.localPosition = Vector3.zero;
                datumDriversParent.localEulerAngles = Vector3.zero;
                datumDriversParent.name = "DatumDriversParent";
            }
                //return false;
        }
        return true;
    }


    static bool GettingBaseConditionForSettingAsDatumDriver(string compType)
    {
        if (srcTran == null)
        {
            SpaceSourceObj t = FindObjectOfType<SpaceSourceObj>();
            if (t != null)
                srcTran = t.transform;
        }
        if (srcTran == null)
            return false;    

        if (Selection.activeGameObject == null) return false;     //至少有一个选择物

        if (Selection.activeGameObject.GetComponent(compType) != null) return false;     //所选物体必须为资源内物体

        return true;
    }

    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/Bool驱动Active/新建", true, 251)]
    private static bool NewBoolDriveActiveValidateFunc()
    {
        return GettingBaseConditionForCreatingDatumDriver("CommonBoolDriveActive");
    }
    [MenuItem("SpacePlayer/前景主体/Bool驱动Active/新建", false, 251)]
    private static void NewBoolDriveActive()
    {
        GameObject go = new GameObject();
        go.name = "BoolDriveActive";
        go.transform.SetParent(datumDriversParent);
        go.transform.localPosition = Vector3.zero;
        go.transform.localEulerAngles = Vector3.zero;
        go.AddComponent<CommonBoolDriveActive>();

        // 注册撤销操作
        Undo.RegisterCreatedObjectUndo(go, "Create DriverObject");
        Selection.activeGameObject = go;
    }

    [MenuItem("SpacePlayer/前景主体/Bool驱动Active/设置所选", true, 252)]
    private static bool SetAsBoolDriveActiveValidateFunc()
    {
        return GettingBaseConditionForSettingAsDatumDriver("CommonBoolDriveActive");
    }
    [MenuItem("SpacePlayer/前景主体/Bool驱动Active/设置所选", false, 252)]
    private static void SetAsBoolDriveActive()
    {
        Selection.activeGameObject.AddComponent<CommonBoolDriveActive>();
    }

    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/Bool驱动Enable/新建", true, 253)]
    private static bool NewBoolDriveEnableValidateFunc()
    {
        return GettingBaseConditionForCreatingDatumDriver("CommonBoolDriveEnable");
    }
    [MenuItem("SpacePlayer/前景主体/Bool驱动Enable/新建", false, 253)]
    private static void NewBoolDriveEnable()
    {
        GameObject go = new GameObject();
        go.name = "BoolDriveEnable";
        go.transform.SetParent(datumDriversParent);
        go.transform.localPosition = Vector3.zero;
        go.transform.localEulerAngles = Vector3.zero;
        go.AddComponent<CommonBoolDriveEnable>();

        // 注册撤销操作
        Undo.RegisterCreatedObjectUndo(go, "Create DriverObject");
        Selection.activeGameObject = go;
    }
    [MenuItem("SpacePlayer/前景主体/Bool驱动Enable/设置所选", true, 254)]
    private static bool SetAsBoolDriveEnableValidateFunc()
    {
        return GettingBaseConditionForSettingAsDatumDriver("CommonBoolDriveEnable");
    }
    [MenuItem("SpacePlayer/前景主体/Bool驱动Enable/设置所选", false, 254)]
    private static void SetAsBoolDriveEnable()
    {
        Selection.activeGameObject.AddComponent<CommonBoolDriveEnable>();
    }

    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/数值驱动位置/新建", true, 255)]
    private static bool NewDatumDrivePositionValidateFunc()
    {
        return GettingBaseConditionForCreatingDatumDriver("CommonDatumDrivePosition");
    }
    [MenuItem("SpacePlayer/前景主体/数值驱动位置/新建", false, 255)]
    private static void NewDatumDrivePosition()
    {
        GameObject go = new GameObject();
        go.name = "DatumDrivePosition";
        go.transform.SetParent(datumDriversParent);
        go.transform.localPosition = Vector3.zero;
        go.transform.localEulerAngles = Vector3.zero;
        go.AddComponent<CommonDatumDrivePosition>();

        // 注册撤销操作
        Undo.RegisterCreatedObjectUndo(go, "Create DriverObject");
        Selection.activeGameObject = go;
    }
    [MenuItem("SpacePlayer/前景主体/数值驱动位置/设置所选", true, 256)]
    private static bool SetAsDatumDrivePositionValidateFunc()
    {
        return GettingBaseConditionForSettingAsDatumDriver("CommonDatumDrivePosition");
    }
    [MenuItem("SpacePlayer/前景主体/数值驱动位置/设置所选", false, 256)]
    private static void SetAsDatumDrivePosition()
    {
        Selection.activeGameObject.AddComponent<CommonDatumDrivePosition>();
    }

    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/数值驱动角度/新建", true, 257)]
    private static bool NewDatumDriveAngleValidateFunc()
    {
        return GettingBaseConditionForCreatingDatumDriver("CommonDatumDriveAngle");
    }
    [MenuItem("SpacePlayer/前景主体/数值驱动角度/新建", false, 257)]
    private static void NewDatumDriveAngle()
    {
        GameObject go = new GameObject();
        go.name = "DatumDriveAngle";
        go.transform.SetParent(datumDriversParent);
        go.transform.localPosition = Vector3.zero;
        go.transform.localEulerAngles = Vector3.zero;
        go.AddComponent<CommonDatumDriveAngle>();

        // 注册撤销操作
        Undo.RegisterCreatedObjectUndo(go, "Create DriverObject");
        Selection.activeGameObject = go;
    }
    [MenuItem("SpacePlayer/前景主体/数值驱动角度/设置所选", true, 258)]
    private static bool SetAsDatumDriveAngleValidateFunc()
    {
        return GettingBaseConditionForSettingAsDatumDriver("CommonDatumDriveAngle");
    }
    [MenuItem("SpacePlayer/前景主体/数值驱动角度/设置所选", false, 258)]
    private static void SetAsDatumDriveAngle()
    {
        Selection.activeGameObject.AddComponent<CommonDatumDriveAngle>();
    }


    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/数值驱动缩放/新建", true, 259)]
    private static bool NewDatumDriveScaleValidateFunc()
    {
        return GettingBaseConditionForCreatingDatumDriver("CommonDatumDriveScale");
    }
    [MenuItem("SpacePlayer/前景主体/数值驱动缩放/新建", false, 259)]
    private static void NewDatumDriveScale()
    {
        GameObject go = new GameObject();
        go.name = "DatumDriveScale";
        go.transform.SetParent(datumDriversParent);
        go.transform.localPosition = Vector3.zero;
        go.transform.localEulerAngles = Vector3.zero;
        go.AddComponent<CommonDatumDriveScale>();

        // 注册撤销操作
        Undo.RegisterCreatedObjectUndo(go, "Create DriverObject");
        Selection.activeGameObject = go;
    }
    [MenuItem("SpacePlayer/前景主体/数值驱动缩放/设置所选", true, 260)]
    private static bool SetAsDatumDriveScaleValidateFunc()
    {
        return GettingBaseConditionForSettingAsDatumDriver("CommonDatumDriveScale");
    }
    [MenuItem("SpacePlayer/前景主体/数值驱动缩放/设置所选", false, 260)]
    private static void SetAsDatumDriveScale()
    {
        Selection.activeGameObject.AddComponent<CommonDatumDriveScale>();
    }

    ///////////////////////////////////////////////////////////////////////////////////////    
    [MenuItem("SpacePlayer/前景主体/数值驱动Slider/设置所选Slider为数值驱动", true, 261)]
    private static bool SetAsDatumDriveSliderValidateFunc()
    {
        if (!GettingBaseConditionForSettingAsDatumDriver("CommonDatumDriveSlider")) return false;
        if (Selection.activeGameObject.GetComponent<Slider>() == null)
            return false;
        return true;
    }
    [MenuItem("SpacePlayer/前景主体/数值驱动Slider/设置所选Slider为数值驱动", false, 261)]
    private static void SetAsDatumDriveSlider()
    {
        Selection.activeGameObject.AddComponent<CommonDatumDriveSlider>();
    }


    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/数值驱动透明/新建", true, 262)]
    private static bool NewFloatDriveAlphaValidateFunc()
    {
        return GettingBaseConditionForCreatingDatumDriver("CommonFloatDriveAlpha");
    }
    [MenuItem("SpacePlayer/前景主体/数值驱动透明/新建", false, 262)]
    private static void NewFloatDriveAlpha()
    {
        GameObject go = new GameObject();
        go.name = "FloatDriveAlpha";
        go.transform.SetParent(datumDriversParent);
        go.transform.localPosition = Vector3.zero;
        go.transform.localEulerAngles = Vector3.zero;
        go.AddComponent<CommonFloatDriveAlpha>();

        // 注册撤销操作
        Undo.RegisterCreatedObjectUndo(go, "Create DriverObject");
        Selection.activeGameObject = go;
    }
    [MenuItem("SpacePlayer/前景主体/数值驱动透明/设置所选", true, 263)]
    private static bool SetAsFloatDriveAlphaValidateFunc()
    {
        return GettingBaseConditionForSettingAsDatumDriver("CommonFloatDriveAlpha");
    }
    [MenuItem("SpacePlayer/前景主体/数值驱动透明/设置所选", false, 263)]
    private static void SetAsFloatDriveAlpha()
    {
        Selection.activeGameObject.AddComponent<CommonFloatDriveAlpha>();
    }



    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/数值驱动光亮/新建", true, 264)]
    private static bool NewFloatDriveLightIntensityValidateFunc()
    {
        return GettingBaseConditionForCreatingDatumDriver("CommonFloatDriveLightIntensity");
    }
    [MenuItem("SpacePlayer/前景主体/数值驱动光亮/新建", false, 264)]
    private static void NewFloatDriveLightIntensity()
    {
        GameObject go = new GameObject();
        go.name = "FloatDriveLightIntensity";
        go.transform.SetParent(datumDriversParent);
        go.transform.localPosition = Vector3.zero;
        go.transform.localEulerAngles = Vector3.zero;
        go.AddComponent<CommonFloatDriveLightIntensity>();

        // 注册撤销操作
        Undo.RegisterCreatedObjectUndo(go, "Create DriverObject");
        Selection.activeGameObject = go;
    }
    [MenuItem("SpacePlayer/前景主体/数值驱动光亮/设置所选", true, 265)]
    private static bool SetAsFloatDriveLightIntensityValidateFunc()
    {
        return GettingBaseConditionForSettingAsDatumDriver("CommonFloatDriveLightIntensity");
    }
    [MenuItem("SpacePlayer/前景主体/数值驱动光亮/设置所选", false, 265)]
    private static void SetAsFloatDriveLightIntensity()
    {
        Selection.activeGameObject.AddComponent<CommonFloatDriveLightIntensity>();
    }




    ///////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/数值驱动状态/新建", true, 266)]
    private static bool NewIntDriveStatusValidateFunc()
    {
        return GettingBaseConditionForCreatingDatumDriver("CommonIntDriveStatus");
    }
    [MenuItem("SpacePlayer/前景主体/数值驱动状态/新建", false, 266)]
    private static void NewIntDriveStatusIntensity()
    {
        GameObject go = new GameObject();
        go.name = "IntDriveStatus";
        go.transform.SetParent(datumDriversParent);
        go.transform.localPosition = Vector3.zero;
        go.transform.localEulerAngles = Vector3.zero;
        go.AddComponent<CommonIntDriveStatus>();

        // 注册撤销操作
        Undo.RegisterCreatedObjectUndo(go, "Create DriverObject");
        Selection.activeGameObject = go;
    }
    [MenuItem("SpacePlayer/前景主体/数值驱动状态/设置所选", true, 267)]
    private static bool SetAsIntDriveStatusValidateFunc()
    {
        return GettingBaseConditionForSettingAsDatumDriver("CommonIntDriveStatus");
    }
    [MenuItem("SpacePlayer/前景主体/数值驱动状态/设置所选", false, 267)]
    private static void SetAsIntDriveStatusIntensity()
    {
        Selection.activeGameObject.AddComponent<CommonIntDriveStatus>();
    }



    /////////////////////////////////////////////////////////////////////////////////////////
    //[MenuItem("SpacePlayer/前景主体/添加微信数据抓取器", true, 300)]
    //private static bool NewWeChatDataCatcherValidateFunc()
    //{
    //    if (curMainSrc == null)
    //    {
    //        curMainSrc = FindObjectOfType<SpaceSourceObj>();
    //    }
    //    if (curMainSrc == null)
    //        return false;
    //    if (curMainSrc.GetComponent<WeChatDataCatcher>())
    //        return false;
    //    return true;
    //}


    //[MenuItem("SpacePlayer/前景主体/添加微信数据抓取器", false, 300)]
    //private static void NewWeChatDataCatcher()
    //{
    //    curMainSrc.gameObject.AddComponent<WeChatDataCatcher>();

    //    // 注册撤销操作
    //    Undo.RegisterCreatedObjectUndo(curMainSrc.gameObject, "Create WeChat DataCatcher");
    //    Selection.activeGameObject = curMainSrc.gameObject;
    //}



    ///////////////////////////////////////////////////////////////////////////////////////////////////////
    [MenuItem("SpacePlayer/前景主体/检查在编资源是否存在常见问题", true, 2557)]
    private static bool PreCheckProblemInValidateFunc()
    {
        return true;
    }

    [MenuItem("SpacePlayer/前景主体/检查在编资源是否存在常见问题", false, 2557)]
    static void PreCheckProblemInSrc()
    {
        CheckToRemoveMovieRecorder();

        if (null == curMainSrc)
        {
            EditorUtility.DisplayDialog("没有在当前场景中找到空间播放资源体", "没有在当前场景中找到空间播放资源体，检查无法进行，请先打开要检查的资源体所在的scene场景。", "确定");
            return;
        }

        //检查确保所有东西都要在Src之下 // 获取当前场景的根物体列表
        GameObject[] rootObjects = UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects();
        if (rootObjects.Length >3 )
        {
            if (EditorUtility.DisplayDialog("【警告】", "一般来说标准的编辑场景的根级物体只有ImageSpacePlayer、StandardLights、SpacePivotRoot三个物体，请检查下要编辑的所有物体是否都在CustomObjSrc脚本物体(" + curMainSrc.gameObject + ")之下。", "确定", "忽略"))
            {
                Selection.activeGameObject = curMainSrc.gameObject;
                //return;
            }
        }
        else
        {
            if(curMainSrc.transform .parent .childCount > 1)
            {
                if (EditorUtility.DisplayDialog("【警告】", "一般来说,所有用户搭建的场景物体都应该在SpacePivotRoot/" + curMainSrc.gameObject + "物体之下，请检查下是否有超出该范围的物体，这可能会影响最终打包是否正确。", "确定", "忽略"))
                {
                    Selection.activeGameObject = curMainSrc.gameObject;
                    //return;
                }
            }
        }

        //检查WormholeSrc脚本是否在
        WormholeSrc wormholeSrc = curMainSrc.GetComponent<WormholeSrc>();
        if (wormholeSrc == null)
        {
            if (curMainSrc.GetComponentInChildren<WormHoleBase>() != null)
            {
                if (EditorUtility.DisplayDialog("【警告】", "一般来说,含有虫洞脚本的资源，要在SpaceSourceObj物体上添加WormholeSrc脚本，以实现对必要参数的共享引用,是否帮你加上？", "确定", "忽略"))
                {
                    wormholeSrc = curMainSrc.gameObject.AddComponent<WormholeSrc>();
                    Selection.activeGameObject = curMainSrc.gameObject;
                }
            }
            else if (curMainSrc.GetComponentInChildren<DisplayBase>() != null)
            {
                if (EditorUtility.DisplayDialog("【警告】", "一般来说,含有虫洞显示脚本的资源，要在SpaceSourceObj物体上添加WormholeSrc脚本，以实现对必要参数的共享引用,是否帮你加上？", "确定", "忽略"))
                {
                    wormholeSrc = curMainSrc.gameObject.AddComponent<WormholeSrc>();
                    Selection.activeGameObject = curMainSrc.gameObject;
                }
            }
        }

        EditorUtility.DisplayDialog("预检完成", "未发现常见的错误，可以选中资源Prefab，通过菜单开始打包。", "确定");
    }


    #region 打包输出
    [MenuItem("SpacePlayer/前景主体/选择SpaceSourceObj预制体打包导出预制体资源(.sps)", true, 2558)]
    private static bool ExportSpacePlayerSrcValidateFunc()
    {
        if (Selection.activeObject == null)
            return false;

        if (!(Selection.activeObject is GameObject))
            return false;

        if(curMainSrc==null )
        {
            curMainSrc = FindObjectOfType <SpaceSourceObj>();
            if (curMainSrc == null)
                return false;
        } 

        return true;
    }

    [MenuItem("SpacePlayer/前景主体/选择SpaceSourceObj预制体打包导出预制体资源(.sps)", false, 2558)]
    private static void ExportSpacePlayerSrc()
    {
        CheckToRemoveMovieRecorder();

        string packagePath = UnityEditor.EditorUtility.OpenFolderPanel("选择打包输出的目标文件夹",
            Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
            , "");
        DirectoryInfo di = new DirectoryInfo(packagePath);

        if (!di.Exists )
        {
            Debug.Log("未选择输出路径，中断打包");
            return;
        }

        string fileName = Selection.activeObject.name.ToLower() + ".sps";
        FileInfo  fi = new FileInfo (Path.Combine(packagePath, fileName));
        if (fi.Exists)
        {
            if (EditorUtility.DisplayDialog("警告", "目标文件夹已经存在同名文件:"+ fileName + "，是否继续，继续将覆盖已存在的文件。", "确定", "取消"))
            {
                Export(di, Selection.activeObject);
            }
        }
        else
        {
            Export(di, Selection.activeObject);
        }
    }

    static void Export(DirectoryInfo di, UnityEngine.Object obj)
    {
        GameObject go = obj as GameObject;
        if (null == go)
            Debug.LogWarning("没有在当前场景中找到对应的结构根物体，未能检查场景中的预制体实例更改是否已经全部更新到预制体上了，但并没影响打包。");

        //检查WormholeSrc脚本是否在
        WormholeSrc wormholeSrc = curMainSrc.GetComponent<WormholeSrc>();
        if (wormholeSrc == null)
        {
            if (curMainSrc.GetComponentInChildren<WormHoleBase>() != null)
            {
                wormholeSrc = curMainSrc.gameObject.AddComponent<WormholeSrc>();
            }
            else if (curMainSrc.GetComponentInChildren<DisplayBase>() != null)
            {
                wormholeSrc = curMainSrc.gameObject.AddComponent<WormholeSrc>();
            }
        }

        if (null == curMainSrc)
            Debug.LogWarning("没有在当前场景中找到对应的结构根物体，未能检查场景中的预制体实例更改是否已经全部更新到预制体上了，但并没影响打包。");
        else
        {
            if (curMainSrc.name == obj.name)
            {
                PrefabUtility.ApplyPrefabInstance(curMainSrc.gameObject, InteractionMode.UserAction);
                AssetDatabase.Refresh();
                Debug.Log("预制体已经跟场景中实例刷新一致");
            }
            else
                Debug.LogWarning("对应场景未打开，未能检查场景中的预制体实例更改是否已经全部更新到预制体上了，但并没影响打包。");
        }

        /////开始输出
        string fileName = go.name.ToLower() + ".sps";
        if (!SPEditor_GeneralTools.Create3DSourceFolder(di, fileName)) return;

        //拷贝链接资源文件
        Debug.Log("拷贝链接资源文件");
        if (wormholeSrc != null)
        {
            SPEditor_Wormhole.CopySrc(di, go);
        }
        //CreateConfigFile(go, di.FullName + "/" + go.name.ToLower() + ".xml");    

        if (EditorUtility.DisplayDialog("成功", go.name.ToLower() + "资源导出完毕。", "确定"))
        {
            Application.OpenURL(di.FullName);
        }
    }


    [MenuItem("SpacePlayer/前景主体/选择场景文件打包导出场景资源(.spss)", true, 2559)]
    private static bool ExportSpacePlayerSceneSrcValidateFunc()
    {
        if (Selection.activeObject == null)
            return false;

        return true;
    }

    [MenuItem("SpacePlayer/前景主体/选择场景文件打包导出场景资源(.spss)", false, 2559)]
    private static void ExportSpacePlayerSceneSrc()
    {
        CheckToRemoveMovieRecorder();

        string packagePath = UnityEditor.EditorUtility.OpenFolderPanel("选择打包输出的目标文件夹",
            Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
            , "");
        DirectoryInfo di = new DirectoryInfo(packagePath);

        if (!di.Exists)
        {
            Debug.Log("未选择输出路径，中断打包");
            return;
        }

        string fileName = Selection.activeObject.name.ToLower() + ".spss";
        FileInfo fi = new FileInfo(Path.Combine(packagePath, fileName));
        if (fi.Exists)
        {
            if (EditorUtility.DisplayDialog("警告", "目标文件夹已经存在同名文件:" + fileName + "，是否继续，继续将覆盖已存在的文件。", "确定", "取消"))
            {
                ExportScene(di, Selection.activeObject);
            }
        }
        else
        {
            ExportScene(di, Selection.activeObject);
        }
    }




    static void ExportScene(DirectoryInfo di, UnityEngine.Object obj)
    {
        bool destroySpacePlayerManager = false;    //标记是否删除过SpacePlayerManager
        string assetsPath = SPEditor_GeneralTools.GetSelectedAssetsPath();
        Debug.Log("assetsPath:" + assetsPath);
        if (string.IsNullOrEmpty(assetsPath))
        {
            Debug.LogError("所选物体对应的资源路径位空。");
            return;
        }
        if (!assetsPath.EndsWith(".unity"))
        {
            Debug.LogError("所选物体对应的资源不是场景。");
            return;
        }

        Scene nowScene = EditorSceneManager.OpenScene(assetsPath);   //, OpenSceneMode.Single);

        curMainSrc = FindObjectOfType<SpaceSourceObj>();
        if (curMainSrc == null)
        {
            Debug.Log("缺少SpaceSourceObj组件"); 
            return;
        }

        SpacePlayerManager spm = FindObjectOfType<SpacePlayerManager>();
        if (spm == null)
        {
            //Debug.LogError("该场景中不存在SpacePlayerManager组件，不是一个标准的合格的SpacePlayer场景。");
            if (EditorUtility.DisplayDialog("提示", "该场景中不存在SpacePlayerManager组件，不是一个标准的合格的SpacePlayer场景，是否添加【ImageSpacePlayer】,添加完毕后重新选择场景进行导出。", "确定", "取消"))
            {
                KeepBaseManagerForSpacePlayer();            //要把测试用的BaseManager加回去
                return;
            }
            else
                return;
        }
        else
        {
            GameObject baseManagerForCuss = spm.gameObject;
            if (baseManagerForCuss != null)
            {
                DestroyImmediate(baseManagerForCuss);
                destroySpacePlayerManager = true;
            }
        }

        //检查WormholeSrc脚本是否在
        WormholeSrc wormholeSrc = curMainSrc.GetComponent<WormholeSrc>();
        if (wormholeSrc == null)
        {
            if (curMainSrc.GetComponentInChildren<WormHoleBase>() != null)
            {
                wormholeSrc = curMainSrc.gameObject.AddComponent<WormholeSrc>();
            }
            else if(curMainSrc.GetComponentInChildren<DisplayBase>() != null)
            {
                wormholeSrc = curMainSrc.gameObject.AddComponent<WormholeSrc>();
            }
        }

        EditorSceneManager.SaveScene(nowScene);
        Debug.Log("场景导出前更新完成");

        //创建Prefab
        AssetDatabase.Refresh();

        assetsPath = Path.Combine(Application.dataPath.Remove (Application.dataPath.Length -7), assetsPath);   //减掉"Assets/"
        //Debug.Log("assetsPath:" + assetsPath);
        AssetImporter importer = AssetImporter.GetAtPath(assetsPath.Remove(0, Application.dataPath.Length - 6));
        importer.assetBundleName = nowScene.name;
        importer.assetBundleVariant = "spss";

        //创建Prefab
        AssetDatabase.Refresh();

        /////开始输出
        try
        {
            string fileName = obj.name.ToLower() + ".spss";
            if (!SPEditor_GeneralTools.Create3DSourceFolder(di, fileName))
            {
                if(destroySpacePlayerManager)
                    KeepBaseManagerForSpacePlayer();            //要把测试用的BaseManager加回去
                return;
            }

            //CreateConfigFile(di.FullName + "/" + obj.name.ToLower() + ".xml");

            if (curMainSrc == null)
            {
                curMainSrc = FindObjectOfType<SpaceSourceObj>();
            }
                        
            if (curMainSrc == null )
            {
                //Debug.LogError("当前场景缺少SpaceSourceObj主资源，不符合可播放场景标准。");
                if (EditorUtility.DisplayDialog("提示", "当前场景缺少SpaceSourceObj主资源，不符合可播放场景标准，不能导出。", "确定"))
                {
                    if (destroySpacePlayerManager)
                        KeepBaseManagerForSpacePlayer();            //要把测试用的BaseManager加回去
                    return;
                }
            }

            //拷贝链接资源文件
            Debug.Log("拷贝链接资源文件");
            if (wormholeSrc != null )
            {
                SPEditor_Wormhole.CopySrc(di, curMainSrc.gameObject );
            }

            //要把测试用的BaseManager加回去
            if (destroySpacePlayerManager)
                KeepBaseManagerForSpacePlayer();

            EditorSceneManager.SaveScene(nowScene);

            if (EditorUtility.DisplayDialog("成功", obj.name.ToLower() + "资源导出完毕。", "确定"))
            {
                Application.OpenURL(di.Parent.FullName);
            }
        }
        catch (Exception e)
        {
            Debug.LogError("打包失败：" + e.Message);
            //要把测试用的BaseManager加回去
            KeepBaseManagerForSpacePlayer();
            EditorSceneManager.SaveScene(nowScene);
        }

    }


    /// <summary>
    /// 保持场景始终有测试环境的控制器
    /// </summary>
    static void KeepBaseManagerForSpacePlayer()
    {
        GameObject spmRoot = GameObject.Find("ImageSpacePlayer");
        if (spmRoot == null)
        {
            Transform managerPrefab = Resources.Load<Transform>("ImageSpacePlayer");
            Transform managerTemp = Instantiate(managerPrefab);
            managerTemp.name = "ImageSpacePlayer";
            managerTemp.SetAsFirstSibling();
        }
    }


    #endregion


    #region 输出视频
    [MenuItem("SpacePlayer/前景主体/运行当前场景导出视频资源(.MP4),停止运行即结束录制", true, 2560)]
    private static bool ExportMP4ValidateFunc()
    {
        //if (Selection.activeObject == null)
        //    return false;
        CheckToRemoveMovieRecorder();

        return true;
    }

    [MenuItem("SpacePlayer/前景主体/运行当前场景导出视频资源(.MP4),停止运行即结束录制", false, 2560)]
    private static void ExportMP4()
    {
        Debug.Log("ExportMP4");
        AddScriptToGameObject();
        EditorApplication.EnterPlaymode();
    }

    private static void AddScriptToGameObject()
    {
        Debug.Log("AddScriptToGameObject");
        // 获取场景中的目标对象
        GameObject targetObject = GameObject.Find("ImageSpacePlayer");        
        if (targetObject != null)
        {
            MovieRecorder mr = FindObjectOfType<MovieRecorder>();
            if(mr == null )
                targetObject.AddComponent<MovieRecorder>();
        }
        else
        {
            Debug.LogError ("缺少必要的ImageSpacePlayer物体，未能正确录制"); 
        }
    }


    /// <summary>
    /// 检查并移除MovieRecord组件
    /// </summary>
    public static void CheckToRemoveMovieRecorder()
    {
        SpacePlayerManager spm = FindObjectOfType<SpacePlayerManager>();
        if (spm != null)
        {
            MovieRecorder mr = spm.gameObject.GetComponent<MovieRecorder>();
            if (mr != null)
            {
                DestroyImmediate(mr);
            }
        }
    }

    #endregion 
}

