using JamesGame; using System.Collections.Generic; using UnityEditor; using UnityEngine; public class PhysicPlayEditor : EditorWindow { private static string targetName; private static string isDone = string.Empty; private static bool isPhysicName = false; private static bool isPhysicRound = false; private static string oldLevelStr; private static string newLevelStr; private static string oldRoundStr; private static string newRoundStr; [MenuItem("NeoGame/物理玩法/创建空靶子")] public static void CreateBlankTarget() { var window = EditorWindow.GetWindow(); isPhysicName = true; isPhysicRound = false; window.titleContent.text = "物理玩法"; window.Show(); } [MenuItem("NeoGame/物理玩法/添加无刚体靶子脚本(气球)")] public static void AttachBallonScriptAndSetting() { GameObject go = Selection.activeGameObject; if (go != null) { ChangeChildLayer(LayerMask.NameToLayer("Target"), go); NormalTarget td = go.GetComponent(); if (td != null) { GameObject hitRoot = td.shape.center.gameObject; PhysicDestructAnim physicCtrl = hitRoot.AddComponent(); td.shape.aniPlayer = physicCtrl; physicCtrl.model = UnityUtils.FindChild(hitRoot.transform, "model").gameObject; AutoFill(go, physicCtrl.model); } else { Debug.Log("要挂的东西上没有TargetData"); } } else { EditorGUILayout.LabelField("选中刚要添加脚本的物体"); } } [MenuItem("NeoGame/物理玩法/添加打碎靶子脚本(木箱,木棍)")] public static void AttachBreakScriptAndSetting() { GameObject go = Selection.activeGameObject; if (go != null) { PhysicDestructAnim ppb = AutoAttachParts(go); if (ppb != null) { AutoFill(go, ppb.model); } } else { EditorGUILayout.LabelField("选中刚要添加脚本的物体"); } } [MenuItem("NeoGame/物理玩法/添加摔碎靶子脚本(冰块)")] public static void AttachDropBreakScriptAndSetting() { GameObject go = Selection.activeGameObject; if (go != null) { PhysicDestructAnim ppb = AutoAttachParts(go); if (ppb != null) { AutoFill(go, ppb.model); AddDropBreakScript(go, ppb.model); } } else { EditorGUILayout.LabelField("选中刚要添加脚本的物体"); } } [MenuItem("NeoGame/物理玩法/添加不破碎靶子脚本(铁块)")] public static void AttachNoBreakScriptAndSetting() { GameObject go = Selection.activeGameObject; if (go != null) { PhysicDestructAnim ppb = AutoAttachParts(go); if(ppb != null) { AddCollusionScript(go, ppb.model); TargetCtrl tc = go.GetComponent(); if (tc != null) { GameObject.Destroy(tc); } } } else { EditorGUILayout.LabelField("选中刚要添加脚本的物体"); } } [MenuItem("NeoGame/物理玩法/添加滚动靶子脚本(铁球)")] public static void AttachRollScriptAndSetting() { GameObject go = Selection.activeGameObject; if (go != null) { PhysicDestructAnim ppb = AutoAttachParts(go); if (ppb != null) { AddRollBreakScript(go, ppb.model); TargetCtrl tc = go.GetComponent(); if (tc != null) { DestroyImmediate(tc); } } } else { EditorGUILayout.LabelField("选中刚要添加脚本的物体"); } } //跟冰块的不同在于,执行完脚本后要自己在prefab上设置爆炸范围和爆炸力 [MenuItem("NeoGame/物理玩法/添加炸药桶靶子脚本")] public static void AttachBoomScriptAndSetting() { GameObject go = Selection.activeGameObject; if (go != null) { PhysicDestructAnim ppb = AutoAttachParts(go); if (ppb != null) { ppb.boomPower = 10f; ppb.boomRange = 10f; AutoFill(go, ppb.model); AddBoomScript(go, ppb.model); } } else { EditorGUILayout.LabelField("选中刚要添加脚本的物体"); } } [MenuItem("NeoGame/物理玩法/添加人形靶子脚本")] public static void AttachBanditScriptAndSetting() { GameObject go = Selection.activeGameObject; if (go != null) { AutoAttachBandits(go); } else { EditorGUILayout.LabelField("选中刚要添加脚本的物体"); } } [MenuItem("NeoGame/物理玩法/移动关卡波次")] public static void MoveLevelRound() { var window = EditorWindow.GetWindow(); isPhysicName = false; isPhysicRound = true; window.titleContent.text = "物理玩法"; window.Show(); } //[MenuItem("NeoGame/物理玩法/添加p")] //public static void AttachP() //{ // GameObject go = Selection.activeGameObject; // if (go != null) // { // int characterControllerLayer = LayerMask.NameToLayer("ZombieCharacter"); // int ragdollLayer = LayerMask.NameToLayer("ZombieRagdoll"); // //puppet只能运行时脚本添加 // TargetData td = go.GetComponent(); // GameObject hitRoot = td.shape.center.gameObject; // Transform model = UnityUtils.FindChild(hitRoot.transform, "model"); // PuppetMaster.SetUp(model.transform, characterControllerLayer, ragdollLayer); // } // else // { // EditorGUILayout.LabelField("选中刚要添加脚本的物体"); // } //} private static void AutoAttachBandits(GameObject go) { //TargetData td = go.GetComponent(); //if (td != null) //{ // GameObject hitRoot = td.shape.center.gameObject; // PhysicPlayEnemyCtrl enemyCtrl = hitRoot.AddComponent(); // td.shape.aniPlayer = enemyCtrl; // Animator model = hitRoot.GetComponentInChildren(); // enemyCtrl.model = model.transform; // AutoPupuet(model); // AutoFill(go, null); // CloseRigi(go); //} //else //{ // Debug.Log("要挂的东西上没有TargetData"); //} } private static void CloseRigi(GameObject go) { Rigidbody[] rigis = go.GetComponentsInChildren(); for (int i = 0;i < rigis.Length; ++i) { rigis[i].isKinematic = true; rigis[i].useGravity = false; } } private static PhysicDestructAnim AutoAttachParts(GameObject go) { ChangeChildLayer(LayerMask.NameToLayer("Target"), go); NormalTarget td = go.GetComponent(); if (td != null) { GameObject hitRoot = td.shape.center.gameObject; PhysicDestructAnim physicCtrl = hitRoot.AddComponent(); td.shape.aniPlayer = physicCtrl; physicCtrl.model = UnityUtils.FindChild(hitRoot.transform, "model").gameObject; physicCtrl.partsModel = UnityUtils.FindChild(hitRoot.transform, "partsModel").gameObject; AddRigiBody(physicCtrl.model, false); AddRigiBody(physicCtrl.partsModel, true); physicCtrl.partsModel.SetActive(false); return physicCtrl; } else { Debug.Log("要挂的东西上没有TargetData"); return null; } } private static void AddCollusionScript(GameObject root, GameObject go) { for (int i = 0; i < go.transform.childCount; ++i) { Transform trans = go.transform.GetChild(i); if (trans != null) { Rigidbody rigi = trans.GetComponent(); if (rigi != null) { PhysicTargetCollusionHandler ppb = trans.gameObject.AddComponent(); ppb.breakCtrl = root.GetComponentInChildren(); } } } } private static void AddDropBreakScript(GameObject root, GameObject go) { for (int i = 0; i < go.transform.childCount; ++i) { Transform trans = go.transform.GetChild(i); if (trans != null) { Rigidbody rigi = trans.GetComponent(); if (rigi != null) { PhysicPlayDropBreakHandler ppb = trans.gameObject.AddComponent(); ppb.breakCtrl = root.GetComponentInChildren(); } } } } private static void AddRollBreakScript(GameObject root, GameObject go) { for (int i = 0; i < go.transform.childCount; ++i) { Transform trans = go.transform.GetChild(i); if (trans != null) { Rigidbody rigi = trans.GetComponent(); if (rigi != null) { PhysicTargetRollCollusionHandler ppb = trans.gameObject.AddComponent(); ppb.breakCtrl = root.GetComponentInChildren(); } } } } private static void AddBoomScript(GameObject root, GameObject go) { for (int i = 0; i < go.transform.childCount; ++i) { Transform trans = go.transform.GetChild(i); if (trans != null) { Rigidbody rigi = trans.GetComponent(); if (rigi != null) { PhysicPlayBoomCollusionHandler ppb = trans.gameObject.AddComponent(); ppb.breakCtrl = root.GetComponentInChildren(); } } } } private static void AddRigiBody(GameObject go, bool isFragment) { for (int i = 0; i < go.transform.childCount; ++i) { Transform trans = go.transform.GetChild(i); if (trans != null) { MeshRenderer mr = trans.GetComponent(); if (mr != null) { Rigidbody rigi = mr.gameObject.AddComponent(); rigi.isKinematic = true; rigi.useGravity = false; } if (isFragment) { trans.gameObject.layer = LayerMask.NameToLayer("Fragment"); } } } } private static void AutoPupuet(Animator model) { //if (model.isHuman) //{ // BipedRagdollReferences r = BipedRagdollReferences.FromAvatar(model); // BipedRagdollCreator.Options options = BipedRagdollCreator.AutodetectOptions(r); // BipedRagdollCreator.Create(r, options); //} //else //{ // BipedReferences r = new BipedReferences(); // BipedReferences.AutoDetectReferences(ref r, model.transform.parent, BipedReferences.AutoDetectParams.Default); // if (r.isFilled) // { // BipedRagdollReferences references = BipedRagdollReferences.FromBipedReferences(r); // BipedRagdollCreator.Options options = BipedRagdollCreator.AutodetectOptions(references); // BipedRagdollCreator.Create(references, options); // } //} //int characterControllerLayer = LayerMask.NameToLayer("ZombieCharacter"); //int ragdollLayer = LayerMask.NameToLayer("ZombieRagdoll"); ////puppet只能运行时脚本添加 //PuppetMaster.SetUp(model.transform, characterControllerLayer, ragdollLayer); } private static void AutoFill(GameObject go, GameObject findObj) { TargetRendererCtrl targetRender = go.GetComponent(); if (targetRender != null) { targetRender.GenerateRenders(); } TargetCtrl tc = go.GetComponent(); if (tc != null) { tc.colliders.Clear(); if (findObj == null) { findObj = tc.gameObject; } var colliders = findObj.transform.GetComponentsInChildren(); foreach (var col in colliders) { int score; if (!int.TryParse(col.name, out score)) { score = 0; } tc.colliders.Add(new TargetScoreCollider { collider = col, score = score, }); } } else { Debug.Log("要挂的东西上没有TargetController"); } } void OnGUI() { GUILayout.BeginVertical(); GUILayout.Space(10); if (isPhysicName) { targetName = EditorGUILayout.TextField("靶子名称", targetName); EditorGUILayout.Space(); if (GUILayout.Button("创建")) { CreateTargetObject(); } } if (isPhysicRound) { oldLevelStr = EditorGUILayout.TextField("旧关卡", oldLevelStr); oldRoundStr = EditorGUILayout.TextField("旧波次", oldRoundStr); newLevelStr = EditorGUILayout.TextField("新关卡", newLevelStr); newRoundStr = EditorGUILayout.TextField("新波次", newRoundStr); EditorGUILayout.Space(); //if (GUILayout.Button("互换")) //{ // ChangeRoundObject(); //} //if (GUILayout.Button("插入")) //{ // InsertRoundObject(); //} } EditorGUILayout.Space(); if (!string.IsNullOrEmpty(isDone)) { EditorGUILayout.LabelField("结果:"+ isDone); } GUILayout.EndVertical(); } private void CreateTargetObject() { GameObject go = CreateGo(targetName, null); GameObject topRoot = CreateGo("top_root", go.transform); GameObject root = CreateGo("root", topRoot.transform); GameObject hitRoot = CreateGo("hit_root", root.transform); GameObject splashSound = CreateGo("splashSound", hitRoot.transform); GameObject splashEffect = CreateGo("splashEffect", hitRoot.transform); GameObject modelObj = CreateGo("model", hitRoot.transform); GameObject partsModelObj = CreateGo("partsModel", hitRoot.transform); GameObject modelCenter = CreateGo("modelCenter", hitRoot.transform); GameObject score = CreateGo("score", hitRoot.transform); NormalTarget td = go.AddComponent(); TargetExt tsd = new TargetExt(); tsd.center = hitRoot.transform; tsd.HitDeathNode = root; tsd.EventNodeName = topRoot; td.shape = tsd; //TargetRendererGather tr = go.AddComponent(); TargetCtrl tc = go.AddComponent(); isDone = "完成"; } private GameObject CreateGo(string objName, Transform objParent) { GameObject obj = new GameObject(); obj.name = objName; obj.transform.SetParent(objParent); obj.transform.localPosition = Vector3.zero; obj.transform.localRotation = Quaternion.identity; obj.transform.localScale = Vector3.one; return obj; } private static void ChangeChildLayer(int layerIndex, GameObject go) { Transform[] tranList = go.GetComponentsInChildren(); foreach (Transform tran in tranList) { tran.gameObject.layer = layerIndex; } } ////未写完 //private static void ChangeRoundObject() //{ // int oldLevel = int.Parse(oldLevelStr); // int newLevel = int.Parse(newLevelStr); // int oldRound = int.Parse(oldRoundStr); // int newRound = int.Parse(newRoundStr); // var levelData = DataManager.Instance.csvData.GetLevelByID(oldLevel); // //获取旧的波次的靶子信息 // List oldRoundTargets = null; // var oldLevelData = DataManager.Instance.csvData.GetLevelByID(oldLevel); // Dictionary> oldRoundDict = RoundTarget.GetRoundTargetDict(oldLevelData.roundTargetIds); // if (oldRoundDict.ContainsKey(oldRound)) // { // oldRoundTargets = oldRoundDict[oldRound]; // } // if (oldRoundTargets != null && oldRoundTargets.Count > 0) // { // //看targetGroup中是否有重复的targetID的靶子,重复的最好人工解决 // for (int i = 0; i < oldRoundTargets.Count; ++i) // { // int targetID = oldRoundTargets[i]; // bool flag = IsUniqueInTargetGroup(oldLevel, targetID); // if (!flag) // { // isDone = "有相同targetID在targetGroup中,需要人工手动处理"; // return; // } // } // } // //获取新的波次的靶子信息 // List newRoundTargets = null; // var newLevelData = DataManager.Instance.csvData.GetLevelByID(newLevel); // Dictionary> newRoundDict = RoundTarget.GetRoundTargetDict(newLevelData.roundTargetIds); // if (newRoundDict.ContainsKey(newRound)) // { // newRoundTargets = newRoundDict[oldRound]; // } // if (newRoundTargets != null && newRoundTargets.Count > 0) // { // //看targetGroup中是否有重复的targetID的靶子,重复的最好人工解决 // for (int i = 0; i < newRoundTargets.Count; ++i) // { // int targetID = newRoundTargets[i]; // bool flag = IsUniqueInTargetGroup(newLevel, targetID); // if (!flag) // { // isDone = "有相同targetID在targetGroup中,需要人工手动处理"; // return; // } // } // } // isDone = "完成"; //} ////未测试 //private static void InsertRoundObject() //{ // int oldLevel = int.Parse(oldLevelStr); // int newLevel = int.Parse(newLevelStr); // int oldRound = int.Parse(oldRoundStr); // int newRound = int.Parse(newRoundStr); // //获取旧的波次的靶子信息 // List oldRoundTargets = null; // var oldLevelData = DataManager.Instance.csvData.GetLevelByID(oldLevel); // Dictionary> oldRoundDict = RoundTarget.GetRoundTargetDict(oldLevelData.roundTargetIds); // if (oldRoundDict.ContainsKey(oldRound)) // { // oldRoundTargets = oldRoundDict[oldRound]; // } // if (oldRoundTargets != null && oldRoundTargets.Count > 0) // { // //看targetGroup中是否有重复的targetID的靶子,重复的最好人工解决 // for (int i = 0; i < oldRoundTargets.Count; ++i) // { // int targetID = oldRoundTargets[i]; // bool flag = IsUniqueInTargetGroup(oldLevel, targetID); // if (!flag) // { // isDone = "有相同targetID在targetGroup中,需要人工手动处理"; // return; // } // } // //在targetgroup中追加要加入的波次的靶子id // var gameDataDir = ConfigEditor.GAME_DATA_DIR; // Dictionary targetGroups = GetTargetGroupDict(); // for (int i = 0; i < oldRoundTargets.Count; ++i) // { // int targetID = oldRoundTargets[i]; // TargetGroupDefine tg = new TargetGroupDefine(); // tg.ID = curMaxTargetGroupID + i + 1; // tg.TargetID = targetID; // tg.GroupID = newLevel; // targetGroups.Add(tg.ID, tg); // } // DataWriter.SaveTargetGroupData(gameDataDir, "TargetGroup", targetGroups); // //把旧的关卡的波次的targetobject添加到新的关卡的指定的波次中,自动将波次后的信息延后 // var newLevelData = DataManager.Instance.csvData.GetLevelByID(newLevel); // Dictionary> newRoundDict = RoundTarget.GetRoundTargetDict(newLevelData.roundTargetIds); // Dictionary> rebuildRoundDict = new Dictionary>(); // foreach (var item in newRoundDict) // { // if (item.Key < newRound) // { // rebuildRoundDict.Add(item.Key, item.Value); // } // else // { // rebuildRoundDict.Add(item.Key + 1, item.Value); // } // } // rebuildRoundDict.Add(newRound, oldRoundTargets); // newLevelData.roundTargetIds = RoundTarget.GetTargetDictStr(rebuildRoundDict); // //挪动旧关卡的关联的刚体信息,与新关卡的关联刚体信息合并 // Dictionary> oldOpenRigiBodys = TargetOpenRigiBody.GetTargetRigiBodyDict(oldLevelData.openRigiBody); // Dictionary> newOpenRigiBodys = TargetOpenRigiBody.GetTargetRigiBodyDict(newLevelData.openRigiBody); // foreach (int targetID in oldRoundTargets) // { // newOpenRigiBodys.Add(targetID, oldOpenRigiBodys[targetID]); // } // newLevelData.openRigiBody = TargetOpenRigiBody.GetTargetRigiBodyList(newOpenRigiBodys); // //挪动旧关卡的关联的移动信息,与新关卡的关联移动信息合并 // Dictionary> oldMoveRigiBodys = TargetOpenRigiBody.GetTargetRigiBodyDict(oldLevelData.moveRigiBody); // Dictionary> newMoveRigiBodys = TargetOpenRigiBody.GetTargetRigiBodyDict(newLevelData.moveRigiBody); // foreach (int targetID in oldRoundTargets) // { // newMoveRigiBodys.Add(targetID, oldMoveRigiBodys[targetID]); // } // newLevelData.moveRigiBody = TargetOpenRigiBody.GetTargetRigiBodyList(newMoveRigiBodys); // Dictionary levelCfgs = GetLevelDict(); // DataWriter.SaveLevelData(gameDataDir, "Level", levelCfgs); // } // isDone = "完成"; //} //private static bool IsUniqueInTargetGroup(int levelID, int targetID) //{ // bool result = true; // var targetGroups = DataManager.Instance.csvData.TargetGroup; // foreach (var cfg in targetGroups) // { // if (cfg.TargetID == targetID && cfg.GroupID == levelID) // { // result = false; // break; // } // } // return result; //} //private static int curMaxTargetGroupID = 0; //private static Dictionary GetTargetGroupDict() //{ // Dictionary targetGroupCfgs = new Dictionary(); // var rawCfgs = DataManager.Instance.csvData.TargetGroup; // foreach (var cfg in rawCfgs) // { // targetGroupCfgs.Add(cfg.ID, cfg); // if (cfg.ID > curMaxTargetGroupID) // { // curMaxTargetGroupID = cfg.ID; // } // } // return targetGroupCfgs; //} //private static Dictionary GetLevelDict() //{ // Dictionary levelCfgs = new Dictionary(); // var rawCfgs = DataManager.Instance.csvData.Level; // foreach (var cfg in rawCfgs) // { // levelCfgs.Add(cfg.ID, cfg); // } // return levelCfgs; //} }