public bool CompareXY(Vec3df pos) { return(x == pos.x && y == pos.y); }
public Vec3df(Vec3df P) { x = P.x; y = P.y; z = P.z; }
public bool Compare(Vec3df pos) { return(x == pos.x && y == pos.y && z == pos.z); }
IEnumerator coFollowPath(List <Vec3df> path, float speedPerTile) { Vector3 curAim = Vector3.zero; // unit vector that points in x direction Vector3 unit_vector_x = new Vector3(1, 0, 0); // solution.Count=4 // 3 steps required // from to // step 1: 0 .. 1 // step 2: 1 .. 2 // step 3: 2 .. 3 // PcntPerStep=0.33f // e.g 4 points pcntg idx0 idx1 // point 0: 0.00 -> 0.33 0 1 // point 1: 0.33 -> 0.66 1 2 // point 2: 0.66 -> 1.00 2 3 if (path.Count > 1) { float pcntg = 0; // pcntg that is necessary per walk step from point to pint float PcntPerStep = 1.0f / (float)(path.Count - 1); // check if previous job was interrupted and resume it to avoid jerky movement if (curWalkPos != null && nextWalkPos != null && path.Count > 2) { // if job was interrupted we can match the last 2 positions in the new solution if (path[0].Compare(curWalkPos) && path[1].Compare(nextWalkPos)) { // if the first 2 positions in new path match this means we have been travelling the same direction before and we can skip the delta amount pcntg = walkDelta * PcntPerStep; } } Vec3df lastPosition = new Vec3df(ownPosition); while (pcntg < 1.0f) { pcntg = Mathf.Clamp01(pcntg + Time.deltaTime * speedPerTile); // 0.24 .. 0 , 0.25 .. 1, 0.5 .. 2, 0.75 .. 3 0.99 .. 3 float idx0f = (float)(path.Count - 1) * pcntg; // truncate the float int idx0 = (int)(idx0f); int idx1 = idx0 + 1; // will be 0.33 with above example // lower percentage border float pidx0 = ((float)idx0) * PcntPerStep; // delta will now go from 0 .. 1 walkDelta = (pcntg - pidx0) / PcntPerStep; if (idx1 < path.Count) { curWalkPos = path[idx0]; nextWalkPos = path[idx1]; ownPosition.x = path[idx0].x * (1.0f - walkDelta) + path[idx1].x * (walkDelta); ownPosition.y = path[idx0].y * (1.0f - walkDelta) + path[idx1].y * (walkDelta); ownPosition.z = path[idx0].z * (1.0f - walkDelta) + path[idx1].z * (walkDelta); curAim.x = ownPosition.x - lastPosition.x; curAim.y = ownPosition.y - lastPosition.y; curAim.z = 0; if (curAim.magnitude > 0) { curAimXY = Angle(curAim, unit_vector_x); // correct the rotation directions by using negative angles that are closer to the destination if (curAimXY - curAimXYAnimated > 180.0f) { // happens if aimXYanimated is negativ!! e.g: curAimXY: 180 aimXYanimated: -90 curAimXY -= 360.0f; } if (curAimXYAnimated - curAimXY > 180.0f) { // happens if curAimXY is negative!! e.g curAimXY: -90 aimXYanimated: -180 curAimXYAnimated -= 360.0f; } curAimXY = Wrap360(curAimXY); curAimXYAnimated = Wrap360(curAimXYAnimated); } if (curAimXYAnimated < curAimXY) { curAimXYAnimated += aimXYAnimationSpeed * Time.deltaTime; if (curAimXYAnimated > curAimXY) { curAimXYAnimated = curAimXY; } } else if (curAimXYAnimated > curAimXY) { curAimXYAnimated -= aimXYAnimationSpeed * Time.deltaTime; if (curAimXYAnimated < curAimXY) { curAimXYAnimated = curAimXY; } } lastPosition.x = ownPosition.x; lastPosition.y = ownPosition.y; lastPosition.z = ownPosition.z; } // wait for next frame! yield return(null); } ownPosition = path[path.Count - 1]; yield return(null); // path is complete, now finish rotation if required if (curAimXYAnimated < curAimXY) { while (curAimXYAnimated < curAimXY) { curAimXYAnimated += aimXYAnimationSpeed * Time.deltaTime; if (curAimXYAnimated > curAimXY) { curAimXYAnimated = curAimXY; } yield return(null); } } else if (curAimXYAnimated > curAimXY) { while (curAimXYAnimated > curAimXY) { curAimXYAnimated -= aimXYAnimationSpeed * Time.deltaTime; if (curAimXYAnimated < curAimXY) { curAimXYAnimated = curAimXY; } yield return(null); } } curWalkPos = null; nextWalkPos = null; curWalkJob = null; } }