private void SetPosition(HisPosInfo hisPosInfo, float rateT) { Vector3 showPos = hisPosInfo.ShowPos; if (navAgent && useNavAgent) //使用NavAgent修改位置 { navAgent.SetDestination(hisPosInfo, rateT); //新的设置位置的有效代码 } else { //原来的有效代码 float disT = Vector3.Distance(showPos, transform.position); if (disT < maxMoveLength && enableMoveByController)//如果当前位置与目标位置超过三维里的一个单位(不考虑y轴方向),就可以进行穿墙移动,小于一个单位会被阻挡 { if (personmove != null) { personmove.SetPosition_History(showPos);//CharactorController控制走路,会被墙等物体挡住。 } } else { transform.position = showPos;//根据历史轨迹走路 } } if (navAgentFollow)//跟谁人员,不用管原来的代码,设置跟随人员的位置就行 { navAgentFollow.SetDestination(hisPosInfo, rateT); } }
private void PrintTimeInfo() { HisPosInfo hisPosInfo = posInfo as HisPosInfo; //假如是历史数据 if (hisPosInfo != null) { var current = hisPosInfo.CurrentPosInfo; var next = current.Next; if (next != null) { TimeSpan time = next.Time - current.Time; //下一个点的时间 float distance = Vector3.Distance(next.Vec, current.Vec); //下一个点的距离 Log.Info("NavAgentControllerBase.UpdatePosition", string.Format("{0}=>{1},time:{2},distance:{3}", current.Vec, next.Vec, time, distance)); MultHistoryTimeStamp timeStamp = LocationHistoryUITool.GetTimeStamp(); double timesum = timeStamp.timeSum; DateTime showPointTime = timeStamp.showPointTime; float currentSpeedT = timeStamp.currentSpeed; Log.Info("NavAgentControllerBase.UpdatePosition", string.Format("t1:{0},t2:{1},t3{2}", current.Time.ToString("HH:mm:ss.f"), next.Time.ToString("HH:mm:ss.f"), showPointTime.ToString("HH:mm:ss.f"))); } } }
/// <summary> /// 执行轨迹演变 /// </summary> protected PositionInfo ExcuteHistoryPath(int currentIndex, float rateT = 1f, bool isLerp = true) { HisPosInfo info = new HisPosInfo(); info.PreHisInfo = hisPosInfo; hisPosInfo = info; hisPosInfo.currentIndex = currentIndex; //Debug.Log("ExcuteHistoryPath:"+ currentIndex); HighlightTestPoint(currentIndex); //if (!MultHistoryPlayUI.Instance.isNewWalkPath) //{ #region 用画线插件来设置人员在轨迹上的位置 //ExcuteHistoryPathOP(currentIndex, isLerp); #endregion //} //else //{ #region 自己计算设置人员在轨迹上的位置 if (rateChanged) { previousPos = transform.position; SetRateChanged(false); timesub = timesub - timesum * rateT; timesum = 0; } if (previousCurrentPointIndex != currentIndex) { count = 0; timesum = 0; previousCurrentPointIndex = currentIndex; if (currentIndex - 1 >= 0 && currentIndex - 1 < PosCount) { hisPosInfo.PrePosInfo = PosInfoList[currentIndex - 1]; previousPos = PosInfoList[currentIndex - 1].Vec; timesub = (float)PosInfoList.GetTimeSpane(currentPointIndex); } } count++; timesum += Time.deltaTime; PositionInfo posInfo = PosInfoList[currentIndex]; hisPosInfo.CurrentPosInfo = posInfo; Vector3 targetPos = posInfo.Vec; Vector3 showPos = targetPos; if (isLerp && currentIndex > 0) { //showPos = Vector3.Lerp(previousPos, targetPos, count * speed * rateT * Time.fixedDeltaTime);//speed小的话会导致计算出来的演变点比实际要演变的点慢很多(两个位置点差距比较大) if (timesub == 0) { showPos = Vector3.Lerp(transform.position, targetPos, count * speed * rateT * Time.deltaTime); //Debug.LogError("timesub == 0!!!!!"); } else { showPos = Vector3.Lerp(previousPos, targetPos, timesum * rateT / timesub); } } else { showPos = targetPos; } //Debug.LogError("显示位置:" + showPos + ",索引:" + currentIndex + ",起始点:" + previousPos + ",计数:" + count + ",系数:" + count * speed * rateT * Time.deltaTime + ",speed:" + speed + ",Time.fixedDeltaTime" + Time.fixedDeltaTime); //Debug.LogError("timesum / timesub:" + timesum / timesub); SetRotaion(targetPos); //设置旋转角度 //transform.position = new Vector3(showPos.x, showPos.y - historyOffsetY, showPos.z);//减去0.4是为了让人员高度贴近地面,通常为人的一半高度 if (LocationHistoryManager.Instance.isSetPersonHeightByRay) { showPos = SetPersonHeightByRay(showPos); } else { showPos = new Vector3(showPos.x, showPos.y - heightOffset, showPos.z); //卡拿着的大约高度 } //transform.position = showPos; hisPosInfo.TargetPos = targetPos; hisPosInfo.ShowPos = showPos; hisPosInfo.CurrentPos = transform.position; SetPosition(hisPosInfo, rateT); #endregion //} return(posInfo); }
protected void SetDestination(Vector3 pos, Action <bool> callback) { Log.Info("NavAgentControllerBase.SetDestination", string.Format("{0}->{1},obj:{2}", transform.position, pos, this)); if (lastPos == pos)//坐标不变,不用计算处理。 { if (callback != null) { callback(false); } return; } //if (lastPos == Vector3.zero)//说明是第一次,直接跳过去吧 //{ // lastPos = pos; // Vector3 posNew=NavMeshHelper.GetClosetPointEx(pos, agent); // if (agent != null) // { // if (agent.gameObject.activeInHierarchy) // { // // } // else // { // transform.position = posNew; // } // } // else // { // transform.position = posNew; // } // if (callback != null) // { // callback(true); // } // return; //} lastPos = pos; //Log.Info("NavAgentControllerBase.SetDestination", string.Format("pos:{0},obj:{1}",pos,this)); if (IsBusyUpdatePosition) { //Log.Info("NavAgentControllerBase.UpdatePosition", "IsBusyUpdatePosition"); if (callback != null) { callback(false); } return; } DateTime start = DateTime.Now; IsBusyUpdatePosition = true; NavMeshHelper.GetClosetPointAsync(pos, this.name, agent, (destination, p) => //多线程异步方式计算,避免影响性能 { try { //Log.Info("NavAgentControllerBase.SetDestination", string.Format("{0}=>{1},{2}", pos,destination, this)); if (SystemSettingHelper.IsDebug())//调试模式下,查看接下来的移动方向 { if (ArcManager.Instance != null) { if (p != null) { ArcManager.Instance.SetLine(gameObject.transform, p.transform); } } } if (agent != null) { if (agent.gameObject.activeInHierarchy) { if (EnableUpdate == false)//代表第一次 { Log.Info("NavAgentControllerBase.SetDestination", string.Format("First Wrap!! pos:{0},obj:{1}", pos, this)); agent.Warp(destination); } else { bool r = agent.SetDestination(destination); //Agent被关闭或者被销毁,调用这个方法会报错 if (r == false) //人物物体不在NavMesh上,立刻跳到目标位置 { Log.Info("NavAgentControllerBase.SetDestination", string.Format("Wrap pos:{0},obj:{1}", pos, this)); //this.transform.position = destination; agent.Warp(destination);//要用这个,用上面那句话,"不在NavMesh上"的问题会一直出现,要用Warp才会重新计算 } else { HisPosInfo hisPosInfo = posInfo as HisPosInfo; //假如是历史数据 if (hisPosInfo != null) { var current = hisPosInfo.CurrentPosInfo; var next = current.Next; if (next != null) { TimeSpan t = next.Time - current.Time; //下一个点的时间 //float distance = Vector3.Distance(next.Vec, current.Vec); //下一个点的距离 //Log.Info("NavAgentControllerBase.UpdatePosition", string.Format("{0}=>{1},time:{2},distance:{3}", current.Vec, next.Vec, time, distance)); this.timespan = t.TotalSeconds;//时间越长,走的越慢 } } } } EnableUpdate = true; } else { Log.Error("NavAgentControllerBase.SetDestination", "agent.gameObject.activeInHierarchy==false:" + this); } } else { Log.Error("NavAgentControllerBase.SetDestination", "agent==null:" + this); } } catch (Exception ex) { Log.Error("NavAgentControllerBase.SetDestination", "Exception:" + ex); } finally { IsBusyUpdatePosition = false; TimeSpan time = DateTime.Now - start; if (callback != null) { callback(false); } } //Log.Info("NavAgentControllerBase.UpdatePosition", NavMeshHelper.Log); //Log.Info("NavAgentControllerBase.SetDestination", "UpdatePosition End time:" +time.TotalMilliseconds+"ms"); }); //IsBusyUpdatePosition = true; //var destination = NavMeshHelper.GetClosetPoint(pos); // => //多线程异步方式计算,避免影响性能 //if (agent != null && agent.gameObject.activeInHierarchy) //{ // bool r = agent.SetDestination(destination); //Agent被关闭或者被销毁,调用这个方法会报错 // Log.Info("NavAgentControllerBase.UpdatePosition", "r:" + r); // if (r == false) //人物物体不在NavMesh上,立刻跳到目标位置 // { // //this.transform.position = destination; // agent.Warp(destination);//要用这个,用上面那句话,"不在NavMesh上"的问题会一直出现,要用Warp才会重新计算 // } //} //IsBusyUpdatePosition = false; //TimeSpan time = DateTime.Now - start; ////Log.Info("NavAgentControllerBase.UpdatePosition", NavMeshHelper.Log); //Log.Info("NavAgentControllerBase.UpdatePosition", "UpdatePosition End time:" + time.TotalMilliseconds + "ms"); //return true; }