using UnityEngine; using UnityEditor; using System; using System.Collections; using System.Collections.Generic; namespace TBTK{ //[CustomEditor(typeof(GridManager))] public class I_GridEditor : TBEditorInspector { private static GridManager gm; private static GridGenerator gGen; private static UnitManager unitManager; private static CollectibleManager collectibleManager; private enum _EditMode{ Node, Unit, Collectible, } private static _EditMode editMode; private static Color colorOn=new Color(.25f, 1f, 1f, 1f); private static bool showGridEditor=false; private static bool enableEditing=false; public static void DrawGridEditor(GridManager gridM){ gm=gridM; gGen=gm.gameObject.GetComponent(); Init(); GetUnitAndCollectibleManager(); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); EditorGUI.BeginChangeCheck(); showGridEditor=EditorGUILayout.Foldout(showGridEditor, "Show Grid editor", TBE.foldoutS); if(EditorGUI.EndChangeCheck()) enableEditing=showGridEditor; GUI.color=enableEditing ? colorOn : new Color(0.5f, 0.5f, 0.5f, 1); if(GUILayout.Button("Edit Grid", GUILayout.MaxWidth(80))){ enableEditing=!enableEditing; if(enableEditing) showGridEditor=true; else showGridEditor=false; } GUI.color=Color.white; EditorGUILayout.EndHorizontal(); if(!showGridEditor) return; if(Application.isPlaying){ EditorGUILayout.HelpBox("Grid editing is not allowed during runtime", MessageType.Warning); return; } GUILayout.Label("Edit Type:", GUILayout.MaxWidth(60)); EditorGUILayout.BeginHorizontal(); GUI.color=editMode==_EditMode.Node ? colorOn : Color.white ; if(GUILayout.Button("Node")) editMode=_EditMode.Node; GUI.color=editMode==_EditMode.Unit ? colorOn : Color.white ; if(GUILayout.Button("Unit")) editMode=_EditMode.Unit; GUI.color=editMode==_EditMode.Collectible ? colorOn : Color.white ; if(GUILayout.Button("Collectible")) editMode=_EditMode.Collectible; GUI.color=Color.white; EditorGUILayout.EndHorizontal(); editorWidth=Screen.width; if(editMode==_EditMode.Node) DrawEditModeUINode(); if(editMode==_EditMode.Unit) DrawEditModeUIUnit(); if(editMode==_EditMode.Collectible) DrawEditModeUICollectible(); GUI.color=new Color(1, 1, 1, 1); } private static void GetUnitAndCollectibleManager(){ if(unitManager==null) unitManager=(UnitManager)FindObjectOfType(typeof(UnitManager)); if(collectibleManager==null) collectibleManager=(CollectibleManager)FindObjectOfType(typeof(CollectibleManager)); } private static bool init=false; private static void Init(){ if(gGen==null) return; if(init) return; init=true; prefabObsHexH=gGen.obstaclePrefabHexH.Count>0 ? gGen.obstaclePrefabHexH[0] : null; prefabObsHexF=gGen.obstaclePrefabHexF.Count>0 ? gGen.obstaclePrefabHexF[0] : null; prefabObsSqH=gGen.obstaclePrefabSqH.Count>0 ? gGen.obstaclePrefabSqH[0] : null; prefabObsSqF=gGen.obstaclePrefabSqF.Count>0 ? gGen.obstaclePrefabSqF[0] : null; prefabWallH=gGen.wallPrefabH.Count>0 ? gGen.wallPrefabH[0] : null; prefabWallF=gGen.wallPrefabF.Count>0 ? gGen.wallPrefabF[0] : null; } private static float editorWidth=1; //used to determined the width of the inspector private enum _NodeStateE {Unwalkable, Default, WallH, WallF, ObstacleH, ObstacleF, SpawnArea, Deployment} private static _NodeStateE nodeState=_NodeStateE.Default; //~ private int spawnAreaFactionID=0; //factionID of the spawnArea //~ private int spawnAreaInfoID=0; //spawnInfoID of the spawnArea (each faction could have multiple spawnInfo) //~ private int deployAreaFactionID=0; private static int deployFacID; private static int spawnGroupFacID; private static int spawnGroupID; private static void DrawStateButton(_NodeStateE state, string text){ GUI.color=nodeState==state ? colorOn : Color.white; if(GUILayout.Button(text, GUILayout.MaxWidth(editorWidth/2))) nodeState=state; GUI.color=Color.white; } private static void DrawEditModeUINode(){ GUILayout.Label("Node State:"); EditorGUILayout.BeginHorizontal(); DrawStateButton(_NodeStateE.Unwalkable, "Unwalkable"); DrawStateButton(_NodeStateE.Default, "Default"); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); DrawStateButton(_NodeStateE.WallH, "Wall (Half)"); DrawStateButton(_NodeStateE.WallF, "Wall (Full)"); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); DrawStateButton(_NodeStateE.ObstacleH, "Obstacle (Half)"); DrawStateButton(_NodeStateE.ObstacleF, "Obstacle (Full)"); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); DrawStateButton(_NodeStateE.Deployment, "Deployment"); DrawStateButton(_NodeStateE.SpawnArea, "SpawnArea"); EditorGUILayout.EndHorizontal(); if(nodeState==_NodeStateE.SpawnArea){ GUILayout.Label("________________________________________________________________________________________________________", GUILayout.Width(editorWidth-30)); GetUnitAndCollectibleManager(); for(int i=0; i> grid=GridManager.GetGrid(); for(int x=0; x> grid=GridManager.GetGrid(); for(int x=0; x prefabList){ GUILayout.Label("________________________________________________________________________________________________________", GUILayout.Width(editorWidth-30)); GUILayout.Label("Prefabs:"); itemInRow=(int)Mathf.Max(1, Mathf.Floor((editorWidth)/50)); Rect rect=new Rect(0, 0, 0, 0); EditorGUILayout.BeginHorizontal(); for(int i=0; i unitList=TBE.unitDB.unitList; itemInRow=(int)Mathf.Max(1, Mathf.Floor((editorWidth)/50)); Rect rect=new Rect(0, 0, 0, 0); EditorGUILayout.BeginHorizontal(); for(int i=0; i collectibleList=TBE.collectibleDB.collectibleList; itemInRow=(int)Mathf.Max(1, Mathf.Floor((editorWidth)/50)); Rect rect=new Rect(0, 0, 0, 0); EditorGUILayout.BeginHorizontal(); for(int i=0; i(); //else if(gm.gridColliderType==GridManager._GridColliderType.Master) // node=gm._GetNodeOnPos(hit.point); if(node==null) return; //Undo.RecordObject(node, "Node"); Undo.RecordObject(GridManager.GetInstance(), "gm"); if(editMode==_EditMode.Node) EditNodeState(node, current.button, hit.point); else if(editMode==_EditMode.Unit) EditNodeUnit(node, current.button, hit.point); else if(editMode==_EditMode.Collectible) EditNodeCollectible(node, current.button, hit.point); //EditorUtility.SetDirty(node); } //else Debug.Log("hit nothing"); } private static void EditNodeState(Node node, int mouseClick=0, Vector3 hitPos=default(Vector3)){ Undo.RecordObject(GridManager.GetInstance(), "gm"); if(nodeState==_NodeStateE.Unwalkable){ if(node.HasObstacle()){ Debug.LogWarning("Cannot set node to unwalkable. Clear obstacle on node first", gm); return; } //Undo.RecordObject(node.gameObject, "Node"); node.walkable=false; node.objT.GetComponent().enabled=node.walkable;//.SetActive(node.walkable); //node.gameObject.SetActive(false); } else if(nodeState==_NodeStateE.Default){ if(node.HasObstacle()){ Debug.LogWarning("Cannot set node to walkable. Clear obstacle on node first", gm); return; } //Undo.RecordObject(node.gameObject, "Node"); node.walkable=true; node.objT.GetComponent().enabled=node.walkable;//.SetActive(node.walkable); //node.gameObject.SetActive(true); } else if(nodeState==_NodeStateE.WallH || nodeState==_NodeStateE.WallF){ if(node.HasObstacle()){ Debug.LogWarning("Cannot add/remove wall. Clear obstacle on node first", gm); return; } //~ Grid grid=instance.GetGrid(); //~ Vector3 dir=hitPos-node.GetPos(); //~ float angle=0; //~ if(instance.nodeType==_NodeType.Square) angle=Utilities.VectorToAngle90(new Vector2(dir.x, dir.z)); //~ else if(instance.nodeType==_NodeType.Hex) angle=Utilities.VectorToAngle60(new Vector2(dir.x, dir.z)); //~ Node neighbourNode=grid.GetNeighbourInDir(node, angle); //~ if(neighbourNode==null){ Debug.LogWarning("Cannot add/remove wall. There's no adjacent node", this); return; } //~ if(neighbourNode.HasObstacle()){ Debug.LogWarning("Cannot add/remove wall. Clear obstacle on neighbour node first", this); return; } //~ if(mouseClick==0) node.AddWall(angle, neighbourNode, nodeState==_NodeStateE.WallH ? 1 : 2); //~ else node.RemoveWall(angle, neighbourNode); //~ Debug.Log(node.wallList.Count); if(mouseClick==0){ Node neighbour=node.GetNeighbourFromPos(hitPos); if(neighbour==null){ Debug.Log("neighbour is null"); return; } if(nodeState==_NodeStateE.WallH) node.AddWall(node.GetPos()+(neighbour.GetPos()-node.GetPos()), prefabWallH); if(nodeState==_NodeStateE.WallF) node.AddWall(node.GetPos()+(neighbour.GetPos()-node.GetPos()), prefabWallF); Unit cachedUnit1=neighbour.unit; neighbour.unit=null; Unit cachedUnit2=node.unit; node.unit=null; bool flag=true; List path=AStar.SearchWalkableNode(node, neighbour, AStar.BypassUnitCode(false), false, false); if(path.Count==0){ flag=false; } neighbour.unit=cachedUnit1; node.unit=cachedUnit2; if(!flag){ node.RemoveWall(node.GetPos()+(neighbour.GetPos()-node.GetPos())); Debug.Log("Cannot create wall here, would block off the node completely"); } } else node.RemoveWall(hitPos); } else if(nodeState==_NodeStateE.ObstacleH || nodeState==_NodeStateE.ObstacleF){ if(node.HasWall()){ Debug.LogWarning("Cannot add/remove obstacle. Clear wall on node first", gm); return; } if(mouseClick==1){ if(node.HasObstacle()) node.RemoveObstacle(); } else{ if(nodeState==_NodeStateE.ObstacleH) node.AddObstacle(GridManager.IsHexGrid() ? prefabObsHexH : prefabObsSqH); else node.AddObstacle(GridManager.IsHexGrid() ? prefabObsHexF : prefabObsSqF); //~ ClearSpawnNode(node); //~ ClearDeployableNode(node); } } else if(nodeState==_NodeStateE.SpawnArea){ //if(node.HasObstacle()){ Debug.LogWarning("Cannot add/remove obstacle. Clear wall on node first", gm); return; } //~ if(spawnAreaFactionID>=unitManager.factionList.Count) return; //~ if(spawnAreaInfoID>=unitManager.factionList[spawnAreaFactionID].spawnInfoList.Count) return; //~ //Undo.RecordObject(unitManager, "FactionManager"); //~ Faction fac=null; if(mouseClick==1){ //ClearSpawnNode(node); node.ClearSpawnGroup(); } else{ if(spawnGroupFacID>=0 && spawnGroupID>=0){ int facID=unitManager.factionList[spawnGroupFacID].factionID; int groupID=unitManager.factionList[spawnGroupFacID].spawnGroupList[spawnGroupID].ID; //if(grid[x][z].spawnGroupFacID==fac.factionID && grid[x][z].spawnGroupID==fac.spawnGroupList[n].factionID) node.SetSpawnGroup(facID, groupID); } //~ fac=unitManager.factionList[spawnAreaFactionID]; //~ if(node.spawnAreaID!=fac.ID) ClearSpawnNode(node); //~ if(!fac.spawnInfoList[spawnAreaInfoID].startingNodeList.Contains(node)){ //~ fac.spawnInfoList[spawnAreaInfoID].startingNodeList.Add(node); //~ node.spawnAreaID=fac.ID; //~ } } SceneView.RepaintAll(); } else if(nodeState==_NodeStateE.Deployment){ //if(node.HasObstacle()){ Debug.LogWarning("Cannot add/remove obstacle. Clear wall on node first", gm); return; } //~ if(deployAreaFactionID>=unitManager.factionList.Count) return; //~ //Undo.RecordObject(unitManager, "FactionManager"); //~ Faction fac=null; if(mouseClick==1){ //ClearDeployableNode(node); node.ClearDeploymentFac(); } else{ //Debug.Log(deployFacID+" "+unitManager.factionList[deployFacID].factionID); node.SetDeploymentFac(unitManager.factionList[deployFacID].factionID); //~ fac=unitManager.factionList[deployAreaFactionID]; //~ if(node.deployAreaID!=fac.ID) ClearDeployableNode(node); //~ if(!fac.deployableNodeList.Contains(node)){ //~ fac.deployableNodeList.Add(node); //~ node.deployAreaID=fac.ID; //~ } } SceneView.RepaintAll(); } } private static void EditNodeUnit(Node node, int mouseClick=0, Vector3 hitPos=default(Vector3)){ if(mouseClick==0){ if(!node.walkable){ Debug.LogWarning("Cannot place unit on unwalkable node", gm); return; } if(node.obstacleT!=null){ Debug.LogWarning("Cannot place unit on node with obstacle", gm); return; } if(selectedUnit==null){ Debug.LogWarning("No unit selected. Select a unit from the editor first", gm); return; } if(node.unit!=null) RemoveUnit(node.unit); if(node.collectible!=null) RemoveCollectible(node.collectible); //~ Vector3 dir=hitPos-node.GetPos(); //~ float angle=0; //~ if(instance.nodeType==_NodeType.Square) angle=360-(Utilities.VectorToAngle90(new Vector2(dir.x, dir.z))-90); //~ else if(instance.nodeType==_NodeType.Hex) angle=360-(Utilities.VectorToAngle60(new Vector2(dir.x, dir.z))-90); float angle=GridManager.GetAngle(node.GetPos(), hitPos, true); GameObject unitObj=(GameObject)PrefabUtility.InstantiatePrefab(selectedUnit.gameObject); Undo.RegisterCreatedObjectUndo(unitObj, "CreatedUnit"); unitObj.transform.position=node.GetPos(); unitObj.transform.rotation=Quaternion.Euler(0, 360-angle+90, 0); if(UnitManager.GetInstance()!=null) unitObj.transform.parent=UnitManager.GetInstance().transform; Unit unit=unitObj.GetComponent(); node.unit=unit; unit.node=node; unitManager.factionList[unitFactionID].unitList.Add(unit); unit.SetFacID(unitManager.factionList[unitFactionID].factionID); } else if(mouseClick==1) RemoveUnit(node.unit); } private static void RemoveUnit(Unit unit){ if(unit==null) return; for(int i=0; i(); node.collectible=item; collectibleManager.PlaceItemAtNode(item, node); } else if(mouseClick==1) RemoveCollectible(node.collectible); } private static void RemoveCollectible(Collectible item){ if(item==null) return; //item.node.collectible=null; collectibleManager.RemoveItem(item); Undo.DestroyObjectImmediate(item.gameObject); } #endregion } }