public void SaveNavInfosToFile(string path) { StreamWriter sw = new StreamWriter(path, false); sw.WriteLine("#,posx,posy,posz,anglex,angley,anglez,dirx,diry,dirz,tranx,trany,tranz,distance,fov,count,range,locked"); if (NavNodeGroup != null) { for (int index = 0; index < NavNodeGroup.transform.childCount; index++) { Transform tchild = NavNodeGroup.transform.GetChild(index); CameraNavNode info = tchild.GetComponent <CameraNavNode>(); if (info == null) { continue; } string sline = "node,"; sline += info.pos.x + ","; sline += info.pos.y + ","; sline += info.pos.z + ","; sline += info.angle.x + ","; sline += info.angle.y + ","; sline += info.angle.z + ","; sline += info.dir.x + ","; sline += info.dir.y + ","; sline += info.dir.z + ","; sline += info.tran.x + ","; sline += info.tran.y + ","; sline += info.tran.z + ","; sline += info.distance + ","; sline += info.fov + ","; sline += info.count + ","; sline += info.range + ","; int locked = info.locked ? 1 : 0; sline += locked + ","; sw.WriteLine(sline); } } sw.Close(); }
public void LoadNavInfoFromText(string text, string tag) { if (NavNodeGroup != null) { for (int index = 0; index < NavNodeGroup.transform.childCount; index++) { Transform tchild = NavNodeGroup.transform.GetChild(index); var temp = tchild.gameObject; ResNode.DestroyRes(ref temp); } } ScpReader reader = new ScpReader(text, tag); for (int i = 0; i < reader.GetRecordCount(); i++) { string cmd = reader.GetString(i, 0, ""); if (cmd != "node") { continue; } Vector3 pos; pos.x = reader.GetFloat(i, 1, 0.0f); pos.y = reader.GetFloat(i, 2, 0.0f); pos.z = reader.GetFloat(i, 3, 0.0f); Vector3 angle; angle.x = reader.GetFloat(i, 4, 0.0f); angle.y = reader.GetFloat(i, 5, 0.0f); angle.z = reader.GetFloat(i, 6, 0.0f); Vector3 dir; dir.x = reader.GetFloat(i, 7, 0.0f); dir.y = reader.GetFloat(i, 8, 0.0f); dir.z = reader.GetFloat(i, 9, 0.0f); Vector3 tran; tran.x = reader.GetFloat(i, 10, 0.0f); tran.y = reader.GetFloat(i, 11, 0.0f); tran.z = reader.GetFloat(i, 12, 0.0f); float distance; distance = reader.GetFloat(i, 13, 0.0f); float fov; fov = reader.GetFloat(i, 14, 0.0f); int count; count = reader.GetInt(i, 15, 0); float range; range = reader.GetFloat(i, 16, NavDefRange); range = Mathf.Clamp(range, 0.0f, 100.0f); bool locked; locked = reader.GetInt(i, 17, 0) != 0; GameObject go = BuildNavNode(pos, angle, dir, tran, distance, fov); CameraNavNode info = go.AddComponent <CameraNavNode>(); info.pos = pos; info.angle = angle; info.dir = dir; info.tran = tran; info.distance = distance; info.fov = fov; info.count = 1; info.range = range; info.locked = locked; } reader.Dispose(); }
//导航协程(对协程不甚了解或者不了解yield return 系列函数用法慎改) public IEnumerator CollectEnumerator() { bCollectRun = true; Vector3 currentpos = m_userDesirePos; CameraNavNode retnode = null; if (NavNodeGroup != null) { for (int index = 0; index < NavNodeGroup.transform.childCount; index++) { if (NavMode != CameraNavMode.Collect) //处于采集模式不导航 { yield return(new WaitForSeconds(1.0f)); break; } //下面逐个每间隔nexttime时间去导航info点遍历一次 Transform tchild = NavNodeGroup.transform.GetChild(index); CameraNavNode node = tchild.GetComponent <CameraNavNode>(); if (node != null) { Vector3 vec = node.pos - currentpos; float mag = vec.magnitude; if (mag < node.range * 0.5f) { retnode = node; break; } } float nexttime = NavTravelTime; if (NavNodeGroup.transform.childCount > 0) { nexttime = NavTravelTime / NavNodeGroup.transform.childCount; } yield return(new WaitForSeconds(nexttime)); } } if (NavMode == CameraNavMode.Collect) { if (retnode != null) //如果已经有数据,加权到旧数据 { CameraNavNode info = retnode; if (!info.locked) { float oldcount = info.count; float newcount = oldcount + 1.0f; //info.pos = (info.pos * oldcount + m_userDesirePos) / newcount; info.angle = (info.angle * oldcount + m_userDesireAngle) / newcount; info.dir = (info.dir * oldcount + m_userDesireDir) / newcount; info.dir.Normalize(); info.tran = (info.tran * oldcount + m_userDesireTran) / newcount; info.distance = (info.distance * oldcount + m_userDesireDistance) / newcount; info.fov = (info.fov * oldcount + m_userDesireFov) / newcount; info.count++; //info.range = info.range; } if (NavLog) { Debug.Log("collect old node" + info.name); } } else //否则添加新数据 { GameObject go = BuildNavNode(currentpos, m_userDesireAngle, m_userDesireDir, m_userDesireTran, m_userDesireDistance, m_userDesireFov); CameraNavNode info = go.AddComponent <CameraNavNode>(); info.pos = currentpos; info.angle = m_userDesireAngle; info.dir = m_userDesireDir; info.tran = m_userDesireTran; info.distance = m_userDesireDistance; info.fov = m_userDesireFov; info.count = 1; info.locked = false; info.range = NavDefRange; if (NavLog) { Debug.Log("collect new node" + info.name); } } } yield return(new WaitForSeconds(1.0f)); bCollectRun = false; }
//导航协程(对协程不甚了解或者不了解yield return 系列函数用法慎改) IEnumerator NavEnumerator() { bNavRun = true; matchnodes.Clear(); Vector3 currentpos = m_userDesirePos; if (NavNodeGroup != null) { for (int index = 0; index < NavNodeGroup.transform.childCount; index++) { if (NavMode != CameraNavMode.Nav) //处于采集模式不导航,歇会退出协程 { yield return(new WaitForSeconds(1.0f)); break; } float time = Time.time; //用户操作期间暂停自动导航NavPauseInterval秒 if (time - NavPauseTime < NavPauseInterval) //用户操作中等待NavPauseInterval秒继续协程 { yield return(new WaitForEndOfFrame()); continue; } //下面逐个每间隔nexttime时间去导航info点遍历一次 Transform tchild = NavNodeGroup.transform.GetChild(index); CameraNavNode node = tchild.GetComponent <CameraNavNode>(); if (node != null) { Vector3 vec = node.pos - currentpos; float mag = vec.magnitude; if (mag < node.range * 0.5f) { matchnodes.Add(node); } } float nexttime = NavTravelTime; if (NavNodeGroup.transform.childCount > 0) { nexttime = NavTravelTime / NavNodeGroup.transform.childCount; } yield return(new WaitForSeconds(nexttime)); } } else //sleep 1秒 { yield return(new WaitForSeconds(1.0f)); } blendnodes.Clear(); for (int k = 0; k < matchnodes.Count; k++) { CameraNavNode node = matchnodes[k]; if (node == null) { continue; } blendnodes.Add(node); } if (blendnodes.Count > 0) { Vector3 blendpos = new Vector3(0, 0, 0); Vector3 blendangle = new Vector3(0, 0, 0); Vector3 blenddir = new Vector3(0, 0, 0); Vector3 blendtran = new Vector3(0, 0, 0); float blenddistance = 0.0f; float blendfov = 0.0f; //下面先计算总权重 float totalweight = 0.0f; for (int k = 0; k < blendnodes.Count; k++) { CameraNavNode node = blendnodes[k]; Vector3 vec = node.pos - currentpos; float mag = vec.magnitude; float weight = 0.0f; if (node.range > 0.01f && mag < node.range * 0.5f) { weight = 1.0f - mag / node.range * 0.5f; } totalweight += weight; } //按距离加权混合 for (int k = 0; k < blendnodes.Count; k++) { CameraNavNode node = blendnodes[k]; Vector3 vec = node.pos - currentpos; float mag = vec.magnitude; float weight = 0.0f; if (node.range > 0.01f && mag < node.range * 0.5f) { weight = 1.0f - mag / node.range * 0.5f; } float factor = weight / totalweight; blendpos += node.pos * factor; blendangle += node.angle * factor; blenddir += node.dir * factor; blendtran += node.tran * factor; blenddistance += node.distance * factor; blendfov += node.fov * factor; } if (NavLog) { string msg = "nav:"; for (int k = 0; k < blendnodes.Count; k++) { CameraNavNode node = blendnodes[k]; if (node == null) { continue; } msg += blendnodes[k].name + ","; } } for (int k = 0; k < 60; k++) //通过60帧逼近目标值,因为navfactor因此逼近效果只依赖于帧数 { m_userDesireAngle = CameraUtil.approximateAngleVec(m_userDesireAngle, blendangle, navFactor); m_userDesireDir = CameraUtil.approximateVec(m_userDesireDir, blenddir, navFactor); m_userDesireTran = CameraUtil.approximateVec(m_userDesireTran, blendtran, navFactor); m_userDesireDistance = CameraUtil.approximateFloat(m_userDesireDistance, blenddistance, navFactor); m_userDesireFov = CameraUtil.approximateFloat(m_userDesireFov, blendfov, navFactor); yield return(new WaitForEndOfFrame()); } } else //sleep 1秒 { yield return(new WaitForSeconds(1.0f)); } bNavRun = false; }