374 lines
12 KiB
C#
374 lines
12 KiB
C#
/********************************************************************
|
||
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<NPCPresent>(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<NPCPresent>().SetHeight(pos.y + 1);
|
||
npcObj.GetComponent<NPCPresent>().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<int, List<NPCData>> m_dicNPCCache = new Dictionary<int, List<NPCData>>();
|
||
public void ExportData(string filePath)
|
||
{
|
||
|
||
LoadFile(filePath);
|
||
if (m_dicNPCCache.ContainsKey(curSceneID))
|
||
{
|
||
m_dicNPCCache[curSceneID] = new List<NPCData>();
|
||
}
|
||
else
|
||
{
|
||
m_dicNPCCache.Add(curSceneID, new List<NPCData>());
|
||
}
|
||
|
||
foreach (NPCPresent child in transform.GetComponentsInChildren<NPCPresent>(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<GameObject> objList = new List<GameObject>();
|
||
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<NPCData> 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<NPCPresent>();
|
||
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<string> _FileTitleStr = new List<string>();
|
||
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<NPCData>());
|
||
}
|
||
|
||
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<NPCData> 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
|
||
}
|
||
}
|