public static TSVector2 Move(this SDFMap map, List <DynamicCircle> circles, FP radius, TSVector2 start, TSVector2 dir, FP len, int layerMask = -1) { start = map.SDF.WorldToLocal(start); TSVector2 end = start + dir * len; RectInt rect = map.SDF.ToRect(start, end); int externSize = (int)TSMath.Ceiling(radius / map.SDF.Grain); rect.max += new Vector2Int(externSize, externSize); moveFilterCache.Clear(); map.FilterToList(moveFilterCache, rect, layerMask); FP maxStepLen = radius * FP.Half; int moveStep = (int)TSMath.Ceiling(len / maxStepLen); TSVector2 result = start; for (int i = 1; i <= moveStep; ++i) { FP moveLen = maxStepLen; if (i == moveStep) { moveLen = len - (moveStep - 1) * maxStepLen; } TSVector2 newPos = result + dir * moveLen; FP sd = map.Sample(newPos, moveFilterCache, circles); if (sd < radius) { TSVector2 gradient = map.Gradient(moveFilterCache, circles, newPos); TSVector2 asjustDir = dir - gradient * TSVector2.Dot(gradient, dir); newPos = result + asjustDir.normalized * moveLen; //多次迭代 for (int j = 0; j < 3; ++j) { sd = map.Sample(newPos, moveFilterCache, circles); if (sd >= radius) { break; } newPos += map.Gradient(moveFilterCache, circles, newPos) * (radius - sd); } //避免往返 if (TSVector2.Dot(newPos - start, dir) < FP.Zero) { return(result + map.SDF.Origin); } else { result = newPos; } break; } else { result = newPos; } } return(result + map.SDF.Origin); }
//直线移动,用于AI的移动 public static TSVector2 StraightMove(this SDFMap map, List <DynamicCircle> circles, FP radius, TSVector2 start, TSVector2 dir, FP len, int layerMask = -1) { start = map.SDF.WorldToLocal(start); TSVector2 end = start + dir * len; RectInt rect = map.SDF.ToRect(start, end); int externSize = (int)TSMath.Ceiling(radius / map.SDF.Grain); rect.max += new Vector2Int(externSize, externSize); moveFilterCache.Clear(); map.FilterToList(moveFilterCache, rect, layerMask); FP maxStepLen = radius * FP.Half; int moveStep = (int)TSMath.Ceiling(len / maxStepLen); TSVector2 result = start; for (int i = 1; i <= moveStep; ++i) { FP moveLen = maxStepLen; if (i == moveStep) { moveLen = len - (moveStep - 1) * maxStepLen; } TSVector2 newPos = result + dir * moveLen; FP sd = map.Sample(newPos, moveFilterCache, circles); if (sd < radius) { newPos = result + dir * sd; sd = map.Sample(newPos, moveFilterCache, circles); if (sd >= radius) { result = newPos; } break; } result = newPos; } return(result + map.SDF.Origin); }