Unity Blood Fill Path Pathing Проблема: недоступная правая и Bottomost GroundC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Unity Blood Fill Path Pathing Проблема: недоступная правая и Bottomost Ground

Сообщение Anonymous »


Я попытался сделать походки BFS на Unity, но я получил недоступную правую и буботочную проблему границы! иду справа или вниз < /strong>, он говорит «вне диапазона!». Проверено _fromto (хранит стрелки длиной в одну плиту для включения пути) , но это выглядит нормально.
Проверено переменные хранения карты как _mapdict, mapdata по случайным 10 плиткам. Найдено правильно. < /li>
переместил 10 случайно выбранных позиций < /strong>, чтобы подтвердить другие позиции в порядке. < /li>
< /ul>

Что мне нужно < /h3>

. Алгоритм Хорошо.

Код: Выделить всё

    public void DisableWalkableTile()
{
foreach (var go in _walkableOverlays) Destroy(go);
foreach (var go in _routeOverlays) Destroy(go);
_walkableOverlays.Clear();
_routeOverlays.Clear();
_FromTo.Clear();
}

public List FindRoute(Transform character, CursorDirector cursor)
{
int safety = 100; // Prevent Infinite Loop
Vector3Int start = tilemap.WorldToCell(character.transform.position);
Debug.Log($"[MapDirector] Start: {start}");
Vector3Int goal = tilemap.WorldToCell(cursor.transform.position);
var route = new List();
//        route.Add(start); // 시작점 추가

if (!_FromTo.ContainsKey(goal))
{
Debug.Log("사거리 외 지점으로 판단됩니다."); //msg: Out of MoveRange
return null;
}

Vector3Int current = goal;
while (current != start && safety-- > 0) //While Route gets to Start
{
route.Add(current);
Debug.Log($"[MapDirector] Current: {current}");
if (!_FromTo.TryGetValue(current, out current))
{
Debug.LogError("루트를 찾는 도중 오류 발생!"); //Path Finding Error
Debug.LogError($"current: {current}, start: {start}");
break;
}
}
route.Reverse();

Debug.Log($"[MapDirector] Found route: {string.Join(" -> ", route.Select(v => v.ToString()))}");
return route;
}
< /code>

 Полный код < /h3>
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Tilemaps;

public abstract class MapDirector_Parent : MonoBehaviour
{
public class TileInfo
{
public int MoveCost;
public string Name;
public string Description;
public string Effect; // Still making...

public TileInfo(int MoveCost, string Name, string Description, string Effect)
{
this.MoveCost = MoveCost;
this.Name = Name;
this.Description = Description;
this.Effect = Effect;
}
}

public static TileInfo plane = new TileInfo(1, "평원", "", "");
public static TileInfo water = new TileInfo(100, "물", "진행 불가", "");
public static TileInfo forest = new TileInfo(2, "숲", "방어 + 30", "DEF+30");
public static TileInfo Mountain = new TileInfo(2, "산", "행운 + 30", "LUK+30");
public static TileInfo Rook = new TileInfo(1, "요새", "방어 + 30", "DEF+30");
public static TileInfo Castle = new TileInfo(1, "성", "목표!", "");
public static TileInfo Block = new TileInfo(100, "장애물", "진행 불가", "");

public List MapData = new List();
public Tilemap tilemap;
public GameObject walkableTilePrefab;
public GameObject routeTilePrefab;
public int mapWidth;
public int mapHeight;

private Dictionary _mapDict; // [Tile position] = info.
private Dictionary _FromTo = new(); //[dest] = start;
private List _walkableOverlays = new();
private List _routeOverlays = new();
private static readonly Vector3Int[] _dirs = {
new Vector3Int(1,  0, 0), new Vector3Int(-1,  0, 0),
new Vector3Int(0,  1, 0), new Vector3Int( 0, -1, 0),
};

// Make cache only once
private void Awake()
{
InitializeMapDict();
}

public virtual void Update()
{
foreach (var kv in _FromTo)
{
Vector3 from = tilemap.CellToWorld(kv.Value) + new Vector3(0.5f, 0.5f, 0);
Vector3 to = tilemap.CellToWorld(kv.Key) + new Vector3(0.5f, 0.5f, 0);
Debug.DrawLine(from, to, Color.red);
}
}

private void InitializeMapDict()
{
_mapDict = new Dictionary();
BoundsInt bounds = tilemap.cellBounds;
for (int x = bounds.xMin; x < bounds.xMax;  x++)
for (int y = bounds.yMin; y < bounds.yMax; y++)
{
var pos = new Vector3Int(x, y, 0);
var tile = tilemap.GetTile(pos);
if (tile == null) continue;

string baseName = tile.name.Split('_')[0];
TileInfo info = baseName switch
{
"Plane" => plane,
"Water" => water,
"Forest" => forest,
"Mountain" => Mountain,
"Fortress" => Rook,
"Castle" => Castle,
"Block" => Block,
_ => plane
};
_mapDict[pos] = info;
}
Debug.Log($"[MapDirector] Initialized _mapDict with {_mapDict.Count} tiles.");
}

public void DisplayWalkableTile(CharacterDirector character)
{
_FromTo.Clear(); // Clear Previous Path
// 1) Delete Previous Path Tile
DisableWalkableTile();
// 2) Start point and MoveRange
Vector3Int start = tilemap.WorldToCell(character.transform.position - new Vector3(0.5f, 0f, 0f));
int maxCost = character.MoveRange;

// 3) BFS Queue Variable Setting
var costSoFar = new Dictionary { [start] = 0 };
var frontier = new Queue();
var attackFrontier = new HashSet(); // Attack Range (Not Made Yet)
frontier.Enqueue(start);

// 4) BFS
while (frontier.Count > 0)
{
var cur = frontier.Dequeue();
int curCost = costSoFar[cur];

foreach (var d in _dirs)
{
var nxt = cur + d;
if (!_mapDict.TryGetValue(nxt, out var info))
continue;
int newCost = curCost + info.MoveCost;
if (newCost > maxCost)
continue;
// if(Enemy is here) continue;
if (!costSoFar.ContainsKey(nxt) || newCost < costSoFar[nxt])
{
costSoFar[nxt] = newCost;
_FromTo[nxt] = cur; //[destination] -> starting position;
frontier.Enqueue(nxt);
}
}
Debug.Log($"FromTo 개수: {_FromTo.Count}");
}

// 5) View square where he can move
foreach (var kv in costSoFar)
{
if (kv.Key == start) continue;
Vector3 worldPos = tilemap.GetCellCenterWorld(kv.Key);
var go = Instantiate(walkableTilePrefab, worldPos, Quaternion.identity, transform);
_walkableOverlays.Add(go);
}
}

public void DisableWalkableTile()
{
foreach (var go in _walkableOverlays) Destroy(go);
foreach (var go in _routeOverlays) Destroy(go);
_walkableOverlays.Clear();
_routeOverlays.Clear();
_FromTo.Clear();
}

public List FindRoute(Transform character, CursorDirector cursor)
{
int safety = 100; // Prevent Infinite Loop
Vector3Int start = tilemap.WorldToCell(character.transform.position);
Debug.Log($"[MapDirector] Start: {start}");
Vector3Int goal = tilemap.WorldToCell(cursor.transform.position);
var route = new List();
//        route.Add(start); // 시작점 추가

if (!_FromTo.ContainsKey(goal))
{
Debug.Log("사거리 외 지점으로 판단됩니다."); //msg: Out of MoveRange
return null;
}

Vector3Int current = goal;
while (current != start && safety-- > 0) //While Route gets to Start
{
route.Add(current);
Debug.Log($"[MapDirector] Current: {current}");
if (!_FromTo.TryGetValue(current, out current))
{
Debug.LogError("루트를 찾는 도중 오류 발생!"); //msg: Path Finding Error
Debug.LogError($"current: {current}, start: {start}");
break;
}
}
route.Reverse();

Debug.Log($"[MapDirector] Found route: {string.Join(" -> ", route.Select(v =>  v.ToString()))}");
return route;
}

public IEnumerator MoveAlongCoroutine(Transform character, List route, Action Callback)
{
if (route == null || route.Count == 0)
{
Debug.LogError("경로가 비어있거나 잘못되었습니다."); // msg: Route is blank or undefined
yield break;
}

Debug.Log($"[MapDirector] Moving along route: {string.Join(" -> ", route.Select(v => v.ToString()))}");

Queue routeQueue = new Queue(route);

while (routeQueue.Count > 0)
{
Vector3Int nextCell = routeQueue.Dequeue();

Vector3 nextWorldPosition = tilemap.CellToWorld(nextCell);

while (Vector3.Distance(character.position, nextWorldPosition) > 0.1f)
{
character.position = Vector3.MoveTowards(character.position, nextWorldPosition, Time.deltaTime * 5f);
yield return null;
}

character.position = nextWorldPosition;
}

Callback?.Invoke(); // Invoke Callback
}
}
Похоже, что на визуальном порядке, но он написан из диапазона в журнале


Подробнее здесь: https://stackoverflow.com/questions/796 ... t-boundary
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Проблема с поиском пути к крови: недоступная правая и бобовая граница
    Anonymous » » в форуме C#
    0 Ответы
    3 Просмотры
    Последнее сообщение Anonymous
  • Django Url Pathing, Home URL всегда перезаписан ('', Views.home, name = 'Home')
    Anonymous » » в форуме Python
    0 Ответы
    62 Просмотры
    Последнее сообщение Anonymous
  • C ++ Наследование - недоступная база?
    Anonymous » » в форуме C++
    0 Ответы
    2 Просмотры
    Последнее сообщение Anonymous
  • C ++ Наследование - недоступная база?
    Anonymous » » в форуме C++
    0 Ответы
    4 Просмотры
    Последнее сообщение Anonymous
  • Является ли утверждение этого CPPREF устаревшим на типичном использовании STD :: Ground?
    Anonymous » » в форуме C++
    0 Ответы
    6 Просмотры
    Последнее сообщение Anonymous

Вернуться в «C#»