Перемещение Pacman с помощью Keys работает отлично. pong. < /p>
Этот метод должен обрабатывать автоматический метод. Я также проверяю, чтобы избежать обратного движения, чтобы Пакман всегда двигался вперед. < /p>
void HandleAutoInputDirection()
{
// Define direction priority
Vector2Int[] directions = new Vector2Int[]
{
Vector2Int.right,
-Vector2Int.up,
Vector2Int.left,
-Vector2Int.down
};
// Try all directions except the reverse of the current moveDir
foreach (var dir in directions)
{
// Skip reversing back to where we came from
if (dir == -moveDir)
continue;
Vector2Int nextGrid = currentGrid + dir;
if (IsWalkable(nextGrid))
{
nextDir = dir;
break;
}
}
// Only change moveDir if we stopped or hit a wall
if (moveDir == Vector2Int.zero && IsWalkable(currentGrid + nextDir))
{
moveDir = nextDir;
targetPos = GridToWorld(currentGrid + moveDir);
UpdateFacingDirection();
}
}
< /code>
Используя его в Update () < /p>
void Update()
{
if (!handleInputDirectinManualAuto)
{
HandleManualInputDirection();
}
else
{
HandleAutoInputDirection();
}
if (moveDir != Vector2Int.zero)
{
float step = moveSpeed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, targetPos, step);
if (Vector3.Distance(transform.position, targetPos) < 0.001f)
{
currentGrid += moveDir;
textCurrentGridValue.text = currentGrid.ToString();
int width = layout[0].Length;
// Tunnel wrap logic
if (currentGrid.x = width - 1)
{
currentGrid.x = 0;
transform.position = GridToWorld(currentGrid);
targetPos = GridToWorld(currentGrid + moveDir);
}
if (IsWalkable(currentGrid + nextDir))
{
moveDir = nextDir;
targetPos = GridToWorld(currentGrid + moveDir);
UpdateFacingDirection();
}
else if (IsWalkable(currentGrid + moveDir))
{
targetPos = GridToWorld(currentGrid + moveDir);
UpdateFacingDirection();
}
else
{
moveDir = Vector2Int.zero;
}
}
}
// Pellet eating logic
for (int i = allPellets.Count - 1; i >= 0; i--)
{
var pellet = allPellets;
if (pellet == null) continue;
if (Vector2.Distance(transform.position, pellet.transform.position) < 0.1f)
{
pellet.OnEaten();
allPellets.RemoveAt(i);
break;
}
}
}
Я создал короткое видео, показывающее проблему в Unity при запуске игры и настройке Bool для перемещения Pacman Automatic.using System.Collections.Generic;
using System.IO;
using System.Linq;
using TMPro;
using UnityEngine;
public class PacManMover : MonoBehaviour
{
public float moveSpeed = 5f;
public float distancePacmanFromPellet;
public bool handleInputDirectinManualAuto = false;
public TextMeshProUGUI textCurrentGridValue;
private Vector2Int currentGrid;
private Vector2Int moveDir = Vector2Int.zero;
private Vector2Int nextDir = Vector2Int.zero;
private Vector3 targetPos;
private Dictionary waypointDict = new();
private Vector3 mazeOffset;
private string[] layout;
private float tileSize;
private StreamWriter logWriter;
private List allPellets = new();
void Start()
{
MazeGenerator mazeGen = FindFirstObjectByType();
layout = MazeGenerator.layout;
tileSize = mazeGen.tileSize;
mazeOffset = mazeGen.offset;
logWriter = new StreamWriter(@"D:\PacManMoveLog.txt", false);
Log("=== PacMan Start ===");
var waypoints = GameObject.FindGameObjectsWithTag("Waypoint");
foreach (var wp in waypoints)
{
Vector2Int gridPos = WorldToGrid(wp.transform.position);
if (!waypointDict.ContainsKey(gridPos))
waypointDict[gridPos] = wp.transform;
}
currentGrid = WorldToGrid(transform.position);
moveDir = Vector2Int.zero;
nextDir = Vector2Int.zero;
targetPos = transform.position;
Log($"Start Grid: {currentGrid} -> {transform.position}");
allPellets = Object.FindObjectsByType(FindObjectsSortMode.None).ToList();
}
void Update()
{
if (!handleInputDirectinManualAuto)
{
HandleManualInputDirection();
}
else
{
HandleAutoInputDirection();
}
if (moveDir != Vector2Int.zero)
{
float step = moveSpeed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, targetPos, step);
if (Vector3.Distance(transform.position, targetPos) < 0.001f)
{
currentGrid += moveDir;
textCurrentGridValue.text = currentGrid.ToString();
int width = layout[0].Length;
// Tunnel wrap logic
if (currentGrid.x = width - 1)
{
currentGrid.x = 0;
transform.position = GridToWorld(currentGrid);
targetPos = GridToWorld(currentGrid + moveDir);
}
if (IsWalkable(currentGrid + nextDir))
{
moveDir = nextDir;
targetPos = GridToWorld(currentGrid + moveDir);
UpdateFacingDirection();
}
else if (IsWalkable(currentGrid + moveDir))
{
targetPos = GridToWorld(currentGrid + moveDir);
UpdateFacingDirection();
}
else
{
moveDir = Vector2Int.zero;
}
}
}
// Pellet eating logic
for (int i = allPellets.Count - 1; i >= 0; i--)
{
var pellet = allPellets;
if (pellet == null) continue;
if (Vector2.Distance(transform.position, pellet.transform.position) < 0.1f)
{
pellet.OnEaten();
allPellets.RemoveAt(i);
break;
}
}
}
void HandleManualInputDirection()
{
if (Input.GetKeyDown(KeyCode.UpArrow)) nextDir = -Vector2Int.up;
if (Input.GetKeyDown(KeyCode.DownArrow)) nextDir = -Vector2Int.down;
if (Input.GetKeyDown(KeyCode.LeftArrow)) nextDir = Vector2Int.left;
if (Input.GetKeyDown(KeyCode.RightArrow))
{
nextDir = Vector2Int.right;
Debug.Log($"Trying right → Grid: {currentGrid + Vector2Int.right}, Walkable: {IsWalkable(currentGrid + Vector2Int.right)}");
}
if (moveDir == Vector2Int.zero && IsWalkable(currentGrid + nextDir))
{
moveDir = nextDir;
targetPos = GridToWorld(currentGrid + moveDir);
UpdateFacingDirection();
}
}
void HandleAutoInputDirection()
{
// Define direction priority
Vector2Int[] directions = new Vector2Int[]
{
Vector2Int.right,
-Vector2Int.up,
Vector2Int.left,
-Vector2Int.down
};
// Try all directions except the reverse of the current moveDir
foreach (var dir in directions)
{
// Skip reversing back to where we came from
if (dir == -moveDir)
continue;
Vector2Int nextGrid = currentGrid + dir;
if (IsWalkable(nextGrid))
{
nextDir = dir;
break;
}
}
// Only change moveDir if we stopped or hit a wall
if (moveDir == Vector2Int.zero && IsWalkable(currentGrid + nextDir))
{
moveDir = nextDir;
targetPos = GridToWorld(currentGrid + moveDir);
UpdateFacingDirection();
}
}
void UpdateFacingDirection()
{
if (moveDir == Vector2Int.left)
{
transform.localScale = new Vector3(-1f, 1f, 1f);
transform.rotation = Quaternion.Euler(0, 0, 0f);
}
else if (moveDir == Vector2Int.right)
{
transform.localScale = new Vector3(1f, 1f, 1f);
transform.rotation = Quaternion.Euler(0, 0, 0f);
}
else if (moveDir == -Vector2Int.up) // Up
{
transform.localScale = new Vector3(1f, 1f, 1f);
transform.rotation = Quaternion.Euler(0, 0, 90f);
}
else if (moveDir == -Vector2Int.down) // Down
{
transform.localScale = new Vector3(1f, 1f, 1f);
transform.rotation = Quaternion.Euler(0, 0, -90f);
}
}
bool IsWalkable(Vector2Int gridPos)
{
int height = layout.Length;
int width = layout[0].Length;
int x = gridPos.x;
int y = gridPos.y;
if (y < 0 || y >= height)
return false;
if (x < 0) x = width - 1;
else if (x >= width) x = 0;
char c = layout[y][x];
return c == '.' || c == ' ' || c == 'P';
}
Vector2Int WorldToGrid(Vector3 worldPos)
{
float x = (worldPos.x - mazeOffset.x + tileSize / 2f) / tileSize;
float y = (mazeOffset.y - worldPos.y + tileSize / 2f) / tileSize;
return new Vector2Int(Mathf.RoundToInt(x), Mathf.RoundToInt(y));
}
Vector3 GridToWorld(Vector2Int gridPos)
{
int width = layout[0].Length;
int x = gridPos.x;
int y = gridPos.y;
if (x < 0) x = width - 1;
else if (x >= width) x = 0;
float worldX = x * tileSize;
float worldY = -y * tileSize;
return new Vector3(worldX, worldY, -1f) + mazeOffset;
}
void Log(string msg)
{
Debug.Log(msg);
if (logWriter != null)
logWriter.WriteLine($"[{System.DateTime.Now:HH:mm:ss}] {msg}");
}
void OnApplicationQuit()
{
if (logWriter != null)
{
logWriter.Close();
logWriter = null;
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/796 ... h-the-path
Как переместить Pacman в автоматическом Unity2d через путь? ⇐ C#
Место общения программистов C#
-
Anonymous
1751990478
Anonymous
Перемещение Pacman с помощью Keys работает отлично. pong. < /p>
Этот метод должен обрабатывать автоматический метод. Я также проверяю, чтобы избежать обратного движения, чтобы Пакман всегда двигался вперед. < /p>
void HandleAutoInputDirection()
{
// Define direction priority
Vector2Int[] directions = new Vector2Int[]
{
Vector2Int.right,
-Vector2Int.up,
Vector2Int.left,
-Vector2Int.down
};
// Try all directions except the reverse of the current moveDir
foreach (var dir in directions)
{
// Skip reversing back to where we came from
if (dir == -moveDir)
continue;
Vector2Int nextGrid = currentGrid + dir;
if (IsWalkable(nextGrid))
{
nextDir = dir;
break;
}
}
// Only change moveDir if we stopped or hit a wall
if (moveDir == Vector2Int.zero && IsWalkable(currentGrid + nextDir))
{
moveDir = nextDir;
targetPos = GridToWorld(currentGrid + moveDir);
UpdateFacingDirection();
}
}
< /code>
Используя его в Update () < /p>
void Update()
{
if (!handleInputDirectinManualAuto)
{
HandleManualInputDirection();
}
else
{
HandleAutoInputDirection();
}
if (moveDir != Vector2Int.zero)
{
float step = moveSpeed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, targetPos, step);
if (Vector3.Distance(transform.position, targetPos) < 0.001f)
{
currentGrid += moveDir;
textCurrentGridValue.text = currentGrid.ToString();
int width = layout[0].Length;
// Tunnel wrap logic
if (currentGrid.x = width - 1)
{
currentGrid.x = 0;
transform.position = GridToWorld(currentGrid);
targetPos = GridToWorld(currentGrid + moveDir);
}
if (IsWalkable(currentGrid + nextDir))
{
moveDir = nextDir;
targetPos = GridToWorld(currentGrid + moveDir);
UpdateFacingDirection();
}
else if (IsWalkable(currentGrid + moveDir))
{
targetPos = GridToWorld(currentGrid + moveDir);
UpdateFacingDirection();
}
else
{
moveDir = Vector2Int.zero;
}
}
}
// Pellet eating logic
for (int i = allPellets.Count - 1; i >= 0; i--)
{
var pellet = allPellets[i];
if (pellet == null) continue;
if (Vector2.Distance(transform.position, pellet.transform.position) < 0.1f)
{
pellet.OnEaten();
allPellets.RemoveAt(i);
break;
}
}
}
Я создал короткое видео, показывающее проблему в Unity при запуске игры и настройке Bool для перемещения Pacman Automatic.using System.Collections.Generic;
using System.IO;
using System.Linq;
using TMPro;
using UnityEngine;
public class PacManMover : MonoBehaviour
{
public float moveSpeed = 5f;
public float distancePacmanFromPellet;
public bool handleInputDirectinManualAuto = false;
public TextMeshProUGUI textCurrentGridValue;
private Vector2Int currentGrid;
private Vector2Int moveDir = Vector2Int.zero;
private Vector2Int nextDir = Vector2Int.zero;
private Vector3 targetPos;
private Dictionary waypointDict = new();
private Vector3 mazeOffset;
private string[] layout;
private float tileSize;
private StreamWriter logWriter;
private List allPellets = new();
void Start()
{
MazeGenerator mazeGen = FindFirstObjectByType();
layout = MazeGenerator.layout;
tileSize = mazeGen.tileSize;
mazeOffset = mazeGen.offset;
logWriter = new StreamWriter(@"D:\PacManMoveLog.txt", false);
Log("=== PacMan Start ===");
var waypoints = GameObject.FindGameObjectsWithTag("Waypoint");
foreach (var wp in waypoints)
{
Vector2Int gridPos = WorldToGrid(wp.transform.position);
if (!waypointDict.ContainsKey(gridPos))
waypointDict[gridPos] = wp.transform;
}
currentGrid = WorldToGrid(transform.position);
moveDir = Vector2Int.zero;
nextDir = Vector2Int.zero;
targetPos = transform.position;
Log($"Start Grid: {currentGrid} -> {transform.position}");
allPellets = Object.FindObjectsByType(FindObjectsSortMode.None).ToList();
}
void Update()
{
if (!handleInputDirectinManualAuto)
{
HandleManualInputDirection();
}
else
{
HandleAutoInputDirection();
}
if (moveDir != Vector2Int.zero)
{
float step = moveSpeed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, targetPos, step);
if (Vector3.Distance(transform.position, targetPos) < 0.001f)
{
currentGrid += moveDir;
textCurrentGridValue.text = currentGrid.ToString();
int width = layout[0].Length;
// Tunnel wrap logic
if (currentGrid.x = width - 1)
{
currentGrid.x = 0;
transform.position = GridToWorld(currentGrid);
targetPos = GridToWorld(currentGrid + moveDir);
}
if (IsWalkable(currentGrid + nextDir))
{
moveDir = nextDir;
targetPos = GridToWorld(currentGrid + moveDir);
UpdateFacingDirection();
}
else if (IsWalkable(currentGrid + moveDir))
{
targetPos = GridToWorld(currentGrid + moveDir);
UpdateFacingDirection();
}
else
{
moveDir = Vector2Int.zero;
}
}
}
// Pellet eating logic
for (int i = allPellets.Count - 1; i >= 0; i--)
{
var pellet = allPellets[i];
if (pellet == null) continue;
if (Vector2.Distance(transform.position, pellet.transform.position) < 0.1f)
{
pellet.OnEaten();
allPellets.RemoveAt(i);
break;
}
}
}
void HandleManualInputDirection()
{
if (Input.GetKeyDown(KeyCode.UpArrow)) nextDir = -Vector2Int.up;
if (Input.GetKeyDown(KeyCode.DownArrow)) nextDir = -Vector2Int.down;
if (Input.GetKeyDown(KeyCode.LeftArrow)) nextDir = Vector2Int.left;
if (Input.GetKeyDown(KeyCode.RightArrow))
{
nextDir = Vector2Int.right;
Debug.Log($"Trying right → Grid: {currentGrid + Vector2Int.right}, Walkable: {IsWalkable(currentGrid + Vector2Int.right)}");
}
if (moveDir == Vector2Int.zero && IsWalkable(currentGrid + nextDir))
{
moveDir = nextDir;
targetPos = GridToWorld(currentGrid + moveDir);
UpdateFacingDirection();
}
}
void HandleAutoInputDirection()
{
// Define direction priority
Vector2Int[] directions = new Vector2Int[]
{
Vector2Int.right,
-Vector2Int.up,
Vector2Int.left,
-Vector2Int.down
};
// Try all directions except the reverse of the current moveDir
foreach (var dir in directions)
{
// Skip reversing back to where we came from
if (dir == -moveDir)
continue;
Vector2Int nextGrid = currentGrid + dir;
if (IsWalkable(nextGrid))
{
nextDir = dir;
break;
}
}
// Only change moveDir if we stopped or hit a wall
if (moveDir == Vector2Int.zero && IsWalkable(currentGrid + nextDir))
{
moveDir = nextDir;
targetPos = GridToWorld(currentGrid + moveDir);
UpdateFacingDirection();
}
}
void UpdateFacingDirection()
{
if (moveDir == Vector2Int.left)
{
transform.localScale = new Vector3(-1f, 1f, 1f);
transform.rotation = Quaternion.Euler(0, 0, 0f);
}
else if (moveDir == Vector2Int.right)
{
transform.localScale = new Vector3(1f, 1f, 1f);
transform.rotation = Quaternion.Euler(0, 0, 0f);
}
else if (moveDir == -Vector2Int.up) // Up
{
transform.localScale = new Vector3(1f, 1f, 1f);
transform.rotation = Quaternion.Euler(0, 0, 90f);
}
else if (moveDir == -Vector2Int.down) // Down
{
transform.localScale = new Vector3(1f, 1f, 1f);
transform.rotation = Quaternion.Euler(0, 0, -90f);
}
}
bool IsWalkable(Vector2Int gridPos)
{
int height = layout.Length;
int width = layout[0].Length;
int x = gridPos.x;
int y = gridPos.y;
if (y < 0 || y >= height)
return false;
if (x < 0) x = width - 1;
else if (x >= width) x = 0;
char c = layout[y][x];
return c == '.' || c == ' ' || c == 'P';
}
Vector2Int WorldToGrid(Vector3 worldPos)
{
float x = (worldPos.x - mazeOffset.x + tileSize / 2f) / tileSize;
float y = (mazeOffset.y - worldPos.y + tileSize / 2f) / tileSize;
return new Vector2Int(Mathf.RoundToInt(x), Mathf.RoundToInt(y));
}
Vector3 GridToWorld(Vector2Int gridPos)
{
int width = layout[0].Length;
int x = gridPos.x;
int y = gridPos.y;
if (x < 0) x = width - 1;
else if (x >= width) x = 0;
float worldX = x * tileSize;
float worldY = -y * tileSize;
return new Vector3(worldX, worldY, -1f) + mazeOffset;
}
void Log(string msg)
{
Debug.Log(msg);
if (logWriter != null)
logWriter.WriteLine($"[{System.DateTime.Now:HH:mm:ss}] {msg}");
}
void OnApplicationQuit()
{
if (logWriter != null)
{
logWriter.Close();
logWriter = null;
}
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79692025/how-to-move-the-pacman-in-unity2d-automatic-through-the-path[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия