protected void Update() { if (NavMsh == null) { return; } CurNode = NavMsh.findNode(Trnsfrm.position, CurNode); if (Target != null) { TargetP = Target.Trnsfrm.position; TargetNode = Target.CurNode; } Vector2 tPos = TargetP, cPos = Trnsfrm.position; //Debug.DrawLine(tPos, cPos); // if target moved much - need to recalculate path if (Path != null && LastPath - Time.frameCount < -10) { // Debug.Log(" LastPath -Time.frameCount " + (LastPath - Time.frameCount) ); if ((Path.Smooth[0].P - tPos).sqrMagnitude > 0.25f || LastPath - Time.frameCount < -180) { Path = null; } } if (Path == null) { Path = NavMsh.getPath(cPos, tPos, TargetNode); if (Path != null) { LastPath = Time.frameCount; CurNodeI = Path.Smooth.Count - 2; ValidPos = Trnsfrm.position; // Debug.Log("pc " + Path.Smooth.Count + " cn " + CurNode); } else { CurNodeI = -1; // Debug.Log("path fail"); } } ///funnel! // basicly recursivlely look at edge we must travers to get to next node until we find a corner in our way - then move thataway // no corner in the way means just go towards target Vector2 vec, cnrA, cnrB; if (Path != null) { for (; CurNodeI > 0; CurNodeI--) //path is backwards - because .... reasons // tPos = Path.Smooth[CurNode].P; /// { if (Util.sign(Path.Smooth[CurNodeI].E2, cPos, Path.Smooth[CurNodeI].E1) < 0) { // if so then we passed through an edge - advance our place along the path // -done awkard way because fo how things were refactored - not neatening because it won't be more efficent - and might somehow implode //CurNode = Path.Smooth[CurNodeI].;///todo continue; } // the arc defined between cnrA < cPos > cnrB is the range of current valid directions cnrA = smoothHelper(Path.Smooth[CurNodeI].E1, cPos, true); cnrB = smoothHelper(Path.Smooth[CurNodeI].E2, cPos, false); float sgn = -1; // int msi = MaxSmoothIter; for (int ci = CurNodeI - 1; ; ci--) { if (ci <= 0) { break; //reached end of path } // only one of these will be different from current corners -- this would be an obvious place to optimise (todo) Vector2 nCnrA = smoothHelper(Path.Smooth[ci].E1, cPos, true); Vector2 nCnrB = smoothHelper(Path.Smooth[ci].E2, cPos, false); //new corner may refine our current valid arc // it may refine it so far that the angle of the arc becomes 0 - ie a direction - cnrA . cnrB would be exactly the same direction - if so then we are done here if ((nCnrA - cnrA).sqrMagnitude > (nCnrB - cnrB).sqrMagnitude) { //Debug.DrawLine(cPos, fnlA2, Color.black); sgn = Util.sign(nCnrA, cPos, cnrA); if (Util.sign(nCnrA, cPos, cnrA) > 0) { if (Util.sign(cnrB, cPos, nCnrA) < 0) { tPos = cnrB; // Debug.Log("breakb"); break; } cnrA = nCnrA; } } else { //Debug.DrawLine(cPos, fnlB2, Color.black); sgn = Util.sign(cnrB, cPos, nCnrB); if (Util.sign(cnrB, cPos, nCnrB) > 0) { if (Util.sign(cnrB, cPos, nCnrA) < 0) { tPos = cnrA; // Debug.Log("breaka"); break; } cnrB = nCnrB; } } // if( msi-- == 0 ) break; } if (Util.sign(cnrB, cPos, tPos) < 0) { tPos = cnrB; } if (Util.sign(tPos, cPos, cnrA) < 0) { tPos = cnrA; } /*// Debug.Log("sgn " + sgn); * Debug.DrawLine(cPos, fnlA, Color.green); * Debug.DrawLine(cPos, fnlB, Color.red); * Debug.DrawLine(cPos, tPos, Color.white); */ break; } } else { if (NavMsh.findNode(cPos) != TargetNode) //fallen off map somehow ... used to happen when colliders dind match map and also current node wasn't clamped -- try and move back to last valid position { tPos = ValidPos; } } vec = tPos - cPos; DesVec = vec; if (isInvincible) { if ((invincibleTimer -= Time.deltaTime) <= 0) { isInvincible = false; invincibleTimer = invincibleTimerInit; } } }
protected void Update() { if( NavMsh == null ) return; CurNode = NavMsh.findNode(Trnsfrm.position, CurNode); if(Target != null) { TargetP = Target.Trnsfrm.position; TargetNode = Target.CurNode; } Vector2 tPos = TargetP, cPos = Trnsfrm.position; //Debug.DrawLine(tPos, cPos); // if target moved much - need to recalculate path if(Path != null && LastPath -Time.frameCount < -10 ) { // Debug.Log(" LastPath -Time.frameCount " + (LastPath - Time.frameCount) ); if((Path.Smooth[0].P - tPos).sqrMagnitude > 0.25f || LastPath - Time.frameCount < -180 ) Path = null; } if(Path == null) { Path = NavMsh.getPath(cPos, tPos, TargetNode); if(Path != null) { LastPath = Time.frameCount; CurNodeI = Path.Smooth.Count - 2; ValidPos = Trnsfrm.position; // Debug.Log("pc " + Path.Smooth.Count + " cn " + CurNode); } else { CurNodeI = -1; // Debug.Log("path fail"); } } ///funnel! // basicly recursivlely look at edge we must travers to get to next node until we find a corner in our way - then move thataway // no corner in the way means just go towards target Vector2 vec, cnrA, cnrB; if(Path != null) { for(; CurNodeI > 0; CurNodeI--) { //path is backwards - because .... reasons // tPos = Path.Smooth[CurNode].P; /// if(Util.sign(Path.Smooth[CurNodeI].E2, cPos, Path.Smooth[CurNodeI].E1) < 0) { // if so then we passed through an edge - advance our place along the path // -done awkard way because fo how things were refactored - not neatening because it won't be more efficent - and might somehow implode //CurNode = Path.Smooth[CurNodeI].;///todo continue; } // the arc defined between cnrA < cPos > cnrB is the range of current valid directions cnrA = smoothHelper(Path.Smooth[CurNodeI].E1, cPos, true); cnrB = smoothHelper(Path.Smooth[CurNodeI].E2, cPos, false); float sgn = -1; // int msi = MaxSmoothIter; for(int ci = CurNodeI - 1; ; ci--) { if(ci <= 0) break; //reached end of path // only one of these will be different from current corners -- this would be an obvious place to optimise (todo) Vector2 nCnrA = smoothHelper(Path.Smooth[ci].E1, cPos, true); Vector2 nCnrB = smoothHelper(Path.Smooth[ci].E2, cPos, false); //new corner may refine our current valid arc // it may refine it so far that the angle of the arc becomes 0 - ie a direction - cnrA . cnrB would be exactly the same direction - if so then we are done here if((nCnrA - cnrA).sqrMagnitude > (nCnrB - cnrB).sqrMagnitude) { //Debug.DrawLine(cPos, fnlA2, Color.black); sgn = Util.sign(nCnrA, cPos, cnrA); if(Util.sign(nCnrA, cPos, cnrA) > 0) { if(Util.sign(cnrB, cPos, nCnrA) < 0) { tPos = cnrB; // Debug.Log("breakb"); break; } cnrA = nCnrA; } } else { //Debug.DrawLine(cPos, fnlB2, Color.black); sgn = Util.sign(cnrB, cPos, nCnrB); if(Util.sign(cnrB, cPos, nCnrB) > 0) { if(Util.sign(cnrB, cPos, nCnrA) < 0) { tPos = cnrA; // Debug.Log("breaka"); break; } cnrB = nCnrB; } } // if( msi-- == 0 ) break; } if(Util.sign(cnrB, cPos, tPos) < 0) tPos = cnrB; if(Util.sign(tPos, cPos, cnrA) < 0) tPos = cnrA; /*// Debug.Log("sgn " + sgn); Debug.DrawLine(cPos, fnlA, Color.green); Debug.DrawLine(cPos, fnlB, Color.red); Debug.DrawLine(cPos, tPos, Color.white); */ break; } } else { if(NavMsh.findNode(cPos) != TargetNode) //fallen off map somehow ... used to happen when colliders dind match map and also current node wasn't clamped -- try and move back to last valid position tPos = ValidPos; } vec = tPos - cPos; DesVec = vec; if (isInvincible) { if ((invincibleTimer -= Time.deltaTime) <= 0) { isInvincible = false; invincibleTimer = invincibleTimerInit; } } }
protected void updatePath() { if(NavMsh == null) return; var lCn = CurNode; CurNode = NavMsh.findNode(SyncO.Body. position, CurNode); if(CurNode == null) { Debug.Log("no node.."); Debug.DrawLine(Trnsfrm.position, Vector3.zero); } checkTarget(); Vector2 biasOff = (Vector2)Trnsfrm.up * RoughRadius*2 + Body.velocity / Acceleration; //cPos = SyncO.Body.position Debug.DrawLine(SyncO.Body.position + biasOff, SyncO.Body.position, Color.black); if(!PathActive) return; Vector2 tPos = TargetP, cPos = SyncO.Body.position; Vector2 tPos2 = tPos; if(CurNode != TargetNode) { if(Path != null && LPathTime - Time.time < -0.2f) { if(LPathTime - Time.time < -2.0f) Path = null; //recalc every so often else { var sqDiff = (LTPos - tPos).sqrMagnitude; // if target moved much - need to recalculate path if(sqDiff > 4.0f || (LTNode != TargetNode && sqDiff > 0.5f)) Path = null; } } if(Path != null && lCn != CurNode) { if(!fixNodeI(ref CurNodeI, CurNode)) { ///not resolved!! -- we got shunted off to side most likely.. --- or possibly rewound but too far - (likely cos we just repathed) // Debug.Log("SHUNTED!!"); Path = null; //todo - we may be able to quick fix some of thse cases } } if(Path == null) { Path = NavMsh.getPath2(cPos, cPos+ biasOff, tPos, TargetNode); if(Path != null) { LTPos = tPos; LTNode = TargetNode; LPathTime = Time.time; LSmoothTime = -1.0f; CurNodeI = Path.Smooth.Count - 1; if(CurNode != Path.Smooth[CurNodeI].N) Debug.LogError("err"); // ValidPos = Trnsfrm.position; // Debug.Log("pc " + Path.Smooth.Count + " cn " + CurNode); } else { CurNodeI = -1; // Debug.Log("path fail"); } } ///funnel! // basicly recursivlely look at edge we must travers to get to next node until we find a corner in our way - then move thataway // no corner in the way means just go towards target if(Time.time - LSmoothTime > 0.5f) { //todo - can check if we have diverged from path to affect resmooth var smthP = WorkingSmoothPath; smthP.Clear(); if(Path != null) { #if DRAW_NAV_LINES Vector2 lastPos = cPos; for(int i = CurNodeI; i-- > 0; ) { Debug.DrawLine(lastPos, Path.Smooth[i].P, Color.white); Debug.DrawLine(lastPos, Path.Smooth[i].E1, Color.grey); Debug.DrawLine(lastPos, Path.Smooth[i].E2, Color.grey); lastPos = Path.Smooth[i].P; } Debug.DrawLine(lastPos, tPos, Color.white); #endif // for(; CurNodeI >= 0; CurNodeI--) { //path is backwards - because .... reasons funnel(cPos, ref tPos, CurNodeI); var lp = cPos; var cp = tPos; var cni = CurNodeI; var n = CurNode; float dis = (lp - cp).magnitude; float lDis = 0; float maxDis = 25; for(int maxIter = 10; maxIter-- > 0; ) { // Debug.Log("iter " + maxIter); smthP.Add(cp); var tp = TargetP; if(dis > maxDis) { // Debug.Log("PASS dis " + maxIter); var v = (cp - lp); #if DRAW_NAV_LINES Debug.DrawLine(lp, lp + v * (maxDis - lDis) / v.magnitude, Color.black); #endif break; } if((tp - cp).sqrMagnitude < 0.5f) { // Debug.Log("PASS " + maxIter); #if DRAW_NAV_LINES Debug.DrawLine(lp, cp, Color.black); #endif break; } #if DRAW_NAV_LINES Debug.DrawLine(lp, cp, Color.black); #endif var ln = n; n = NavMsh.findNode(cp, n); if(ln != n) { if(n == TargetNode) { // Debug.Log("PASS " + maxIter); #if DRAW_NAV_LINES Debug.DrawLine(cp, tp, Color.black); #endif smthP.Add(tp); break; } if(!fixNodeI(ref cni, n)) { // Debug.Log("FAIL --- you shall not pass"); smthP.Add(tp); //hope for the best break; } } funnel(cp, ref tp, cni); float d = (cp - tp).magnitude; // Debug.Log("dis " + d); float minStep = 0.75f; if(d < minStep) { tp = cp + (tp - cp) * minStep / d; d = minStep; } lDis = dis; dis += d; // break; lp = cp; cp = tp; } } else { smthP.Add(TargetP); if(CurNode != TargetNode) //fallen off map somehow ... used to happen when colliders dind match map and also current node wasn't clamped -- try and move back to last valid position // tPos = ValidPos; Debug.Log("Awk noes we appear to have fallen off the map"); } if( SmoothPath.Count > 0 ) { if(Vector2.Dot((Body.position - smthP[0]).normalized, (Body.position - SmoothPath[SyncO.SPi]).normalized) < 0.8f) steerUpdate(); } else steerUpdate(); SmoothPath = new List<Vector2>(smthP); //todo SPi = SyncO.SPi = 0; } } else { Path = null; //bool dirty = false; if(SmoothPath.Count < 1) { // dirty = true; SmoothPath.Add(TargetP); steerUpdate(); } else if( (SmoothPath[0]- TargetP).sqrMagnitude > 0.5f ) { // dirty = true; if( Vector2.Dot( (Body.position - TargetP).normalized, (Body.position - SmoothPath[0]).normalized ) < 0.8f ) steerUpdate(); SmoothPath.Clear(); SmoothPath.Add(TargetP); } SPi = SyncO.SPi = 0; } // Debug.DrawLine( Body.position, tPos, Color.white); // Debug.DrawLine( tPos2, tPos, Color.white); //DesPos = tPos; //vec = tPos - cPos; // DesVec = vec; }