/******************************************************************** created: 2014/03/14 created: 14:3:2014 16:48 filename: NPCEditorRoot.cs author: 王迪 purpose: 种怪编辑器根结点,NPC必须挂在此结点下边界, 导入导出需要选中带有此脚本的物体 *********************************************************************/ using UnityEngine; using System.Collections; using System.Collections.Generic; using System.IO; using System.Text; using GCGame; using System; using Module.Log; using Games.Scene; public class NPCEditorRoot : MonoBehaviour { public float UpdateDuration = 1.0f; private float m_updateTimer = 1.0f; //public float m_terrainHeight = 20.0f; public int curSceneID = 1; public int curDataID = -1; public float curRadius = 1; public Color curColor = Color.white; public GameObject _NPCIniPrefab; // Use this for initialization void Start () { } // Update is called once per frame void OnDrawGizmos() { m_updateTimer -= Time.deltaTime; if (m_updateTimer < 0) { m_updateTimer = UpdateDuration; foreach (NPCPresent child in transform.GetComponentsInChildren(false)) { //child.SetHeight(m_terrainHeight); if (child.DataID == curDataID ) { child.SetColor(curColor); child.SetRadius(curRadius); } } } } public void AddNPC(Vector3 pos) { var npcObj = GameObject.Instantiate(_NPCIniPrefab); npcObj.transform.parent = transform; npcObj.transform.position = pos; npcObj.GetComponent().SetHeight(pos.y + 1); npcObj.GetComponent().DataID = curDataID; npcObj.name = curDataID.ToString(); } public class NPCData { public string name; public int sceneID; public int dataID; public float xPos; public float yPos; public float rad; public int clientOnly; //public int npcType; public string GetString() { return (name + "\t" + sceneID.ToString() + "\t" + dataID.ToString() + "\t" + xPos.ToString("0.##") + "\t" + yPos.ToString("0.##") + "\t" + rad.ToString("0.##") + "\t" + clientOnly.ToString() /*npcType.ToString()*/); } }; private Dictionary> m_dicNPCCache = new Dictionary>(); public void ExportData(string filePath) { LoadFile(filePath); if (m_dicNPCCache.ContainsKey(curSceneID)) { m_dicNPCCache[curSceneID] = new List(); } else { m_dicNPCCache.Add(curSceneID, new List()); } foreach (NPCPresent child in transform.GetComponentsInChildren(false)) { NPCData curNPC = new NPCData(); curNPC.name = child.NPCName; curNPC.sceneID = curSceneID; curNPC.dataID = child.DataID; var pos = GetTerrainPosition(child.transform.position); curNPC.xPos = /*child.transform.position.x;*/pos.x; curNPC.yPos =/* child.transform.position.z;*/ pos.z; curNPC.rad = Utils.DirClientToServer(child.transform.rotation); curNPC.clientOnly = child.ClentOnly; //curNPC.npcType = child.NPCType; m_dicNPCCache[curSceneID].Add(curNPC); } WriteFile(filePath); //ConvertFile(filePath); } public const float navSampleHeight = 30f; public const float raycastHeight = 200f; public const float sphereCastRadius = 1f; public const float edgeSnapDist = 0.05f; //public static readonly int terrainLayMask = LayerMask.GetMask("Default", "T4MLayer"); public Vector3 GetTerrainPosition(Vector3 origin) { var raySource = origin; raySource.y = raycastHeight; RaycastHit raycastHit; if (Physics.Raycast(raySource, Vector3.down, out raycastHit, raycastHeight * 2f, LayerMask.GetMask("Default", "T4MLayer"))) origin = raycastHit.point; if (Physics.SphereCast(raySource, sphereCastRadius, Vector3.down, out raycastHit, raycastHeight * 2f, LayerMask.GetMask("Default", "T4MLayer"))) origin = raycastHit.point; UnityEngine.AI.NavMeshHit navMeshHit; if (UnityEngine.AI.NavMesh.SamplePosition(origin, out navMeshHit, navSampleHeight, UnityEngine.AI.NavMesh.AllAreas)) origin = navMeshHit.position; if (UnityEngine.AI.NavMesh.FindClosestEdge(origin, out navMeshHit, UnityEngine.AI.NavMesh.AllAreas) && (navMeshHit.position - origin).sqrMagnitude < edgeSnapDist.ToSquare()) origin = navMeshHit.position; return origin; } public void ImportData(string path) { foreach (Transform curObj in transform) { DestroyImmediate(curObj.gameObject); } List objList = new List(); for (int i = 0, count = transform.childCount; i < count; i++) { objList.Add(transform.GetChild(i).gameObject); } foreach (GameObject curObj in objList) { DestroyImmediate(curObj); } LoadFile(path); if (!m_dicNPCCache.ContainsKey(curSceneID)) { return; } List curDataList = m_dicNPCCache[curSceneID]; //NPCPresent curPresent = UnityEditor.AssetDatabase.LoadAssetAtPath("Assets/MLDJ/Editor/NPCInst.prefab", typeof(NPCPresent)) as NPCPresent; int curID = 0; foreach (NPCData curNPC in curDataList) { GameObject newRes = GameObject.Instantiate(_NPCIniPrefab) as GameObject; newRes.transform.parent = transform; NPCPresent curNPCS = newRes.GetComponent(); curNPCS.transform.position = new Vector3(curNPC.xPos, 0, curNPC.yPos); curNPCS.transform.rotation = Utils.DirServerToClient(curNPC.rad); curNPCS.SetHeight(GetScenePosy(curNPC.xPos, curNPC.yPos)); curNPCS.NPCName = curNPC.name; curNPCS.DataID = curNPC.dataID; curNPCS.ClentOnly = curNPC.clientOnly; //curNPCS.NPCType = curNPC.npcType; newRes.name = curID.ToString() + "_" + curNPC.name; ; curID++; } return; } private static float GetScenePosy(float fX, float fZ) { Vector3 testPos = new Vector3(fX,100, fZ); Vector3 testDirect = new Vector3(0, -100, 0); Ray ray = new Ray(testPos, testDirect); RaycastHit hit; int layerMask = 1 << 12; if (Physics.Raycast(ray, out hit, 1000, layerMask)) { //如果检测点是 //if (hit.collider.gameObject.CompareTag(m_szServerObstacleTag)) { return hit.point.y; } } //for (int i = 0; i < m_ServerObstacleTestAgent.Count; ++i) //{ // m_ServerObstacleTestAgent[i].destination = pos; // if (m_ServerObstacleTestAgent[i].hasPath) // { // info.m_Value = m_nPath; // break; // } //} return 0; } private List _FileTitleStr = new List(); private void LoadFile(string filePath) { m_dicNPCCache.Clear(); if (File.Exists(filePath)) { FileStream rfs = new FileStream(filePath, FileMode.Open); StreamReader sr = new StreamReader(rfs, Encoding.GetEncoding("GB2312")); _FileTitleStr.Clear(); int i = 0; bool startContentLine = false; while (!sr.EndOfStream) { string curLine = sr.ReadLine(); LogModule.DebugLog(curLine); if (i++ < 2) { _FileTitleStr.Add(curLine); continue; } if (!startContentLine && curLine.StartsWith("#")) { _FileTitleStr.Add(curLine); continue; } startContentLine = true; string[] values = curLine.Split('\t'); if (values.Length !=8) { LogModule.ErrorLog("1"); return; } NPCData curData = new NPCData(); int curID; if (!int.TryParse(values[0], out curID)) { LogModule.ErrorLog("0"); return; } curData.name = values[1]; if (!int.TryParse(values[2], out curData.sceneID)) { LogModule.ErrorLog("2"); return; } if (!int.TryParse(values[3], out curData.dataID)) { LogModule.ErrorLog("3"); return; } if (!float.TryParse(values[4], out curData.xPos)) { LogModule.ErrorLog("4"); return; } if (!float.TryParse(values[5], out curData.yPos)) { LogModule.ErrorLog("5"); return; } if (!float.TryParse(values[6], out curData.rad)) { LogModule.ErrorLog("6"); return; } if (!int.TryParse(values[7], out curData.clientOnly)) { LogModule.ErrorLog("7"); return; } if (!m_dicNPCCache.ContainsKey(curData.sceneID)) { m_dicNPCCache.Add(curData.sceneID, new List()); } m_dicNPCCache[curData.sceneID].Add(curData); LogModule.DebugLog("get record"); } rfs.Close(); sr.Close(); } } void WriteFile(string filePath) { if (File.Exists(filePath)) { File.Delete(filePath); } FileStream wfs = new FileStream(filePath, FileMode.CreateNew); StreamWriter sw = new StreamWriter(wfs, Encoding.GetEncoding("GB2312")); for (int i = 0; i < _FileTitleStr.Count; ++i) { sw.WriteLine(_FileTitleStr[i]); } //sw.WriteLine("Id\tDesc\tSceneID\tDataID\tPosX\tPosZ\tFaceDirection\tClientShow"); //sw.WriteLine("INT\tSTRING\tINT\tINT\tFLOAT\tFLOAT\tFLOAT\tINT"); //sw.WriteLine("#MAX_ID=4999;MAX_RECORD=5000;TableType=Hash;ExportLua=1;\t\t\t\t\t\t\t"); //sw.WriteLine("#唯一标示\t描述,策划维护,此列程序不读\t所属场景\tDataID\t位置X\t位置Z\t纯客户端显示用\t"); int id = 0; foreach (List curList in m_dicNPCCache.Values) { foreach (NPCData curNPC in curList) { sw.WriteLine(id.ToString() + "\t" + curNPC.GetString()); id++; } } sw.Close(); wfs.Close(); } void ConvertFile(string filePath) { #if UNITY_EDITOR FileStream rfs = new FileStream(filePath, FileMode.Open); StreamReader sr = new StreamReader(rfs); string curFile = sr.ReadToEnd(); rfs.Close(); sr.Close(); FileStream wfs = new FileStream(filePath, FileMode.OpenOrCreate); StreamWriter sw = new StreamWriter(wfs); Byte[] bytes = Encoding.Convert(Encoding.UTF8, Encoding.ASCII, Encoding.UTF8.GetBytes(curFile)); //Encoding.ASCII.GetString(Encoding.ASCII.GetBytes(curFile.ToCharArray())); sw.Write(bytes); sw.Close(); wfs.Close(); #endif } }