Что мне нужно, так это то, что NPC, который движется по пути по сценарию, останавливается перед игроком, если игрок стоит на пути.Это 2D игра сверху вниз с движением сетки.NPC все время перемещает 4 клетки вниз, 2 клетки влево, 4 клетки вверх и 2 клетки вправо.Мне нужно, чтобы, если игрок мешал, он останавливался впереди и продолжал, когда игрок покидает сетку.Я не хочу использовать коллайдер на плеере, потому что тогда мне нужен rigitbody2d, и с этим мой скрипт движения не работает.
Вот TileMovementController.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class TileMovementController : MonoBehaviour {
public enum Direction { Left, Right, Up, Down }; // Direction of movement
protected Vector3 newPosition; // For movement
protected virtual Vector3 move(Direction dir, int steps) {
if (dir == Direction.Left && transform.position == newPosition)
newPosition += new Vector3(steps * (-1), 0, 0);
else if (dir == Direction.Right && transform.position == newPosition)
newPosition += new Vector3(steps, 0, 0);
else if (dir == Direction.Up && transform.position == newPosition)
newPosition += new Vector3(0, steps, 0);
else if (dir == Direction.Down && transform.position == newPosition)
newPosition += new Vector3(0, steps * (-1), 0);
return newPosition;
}
}
PlayerMovementController.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovementController : TileMovementController {
public float moveSpeed = 2.0f;
void Start () {
newPosition = transform.position; // Take the initial position
}
private void FixedUpdate() {
// RayCasts for collisions, ignoring layer 2 (Ignore Raycast)
if (Input.GetKey(KeyCode.A) && Physics2D.Raycast(transform.position, Vector2.left, 1, ~(1 << 2)).collider == null) { // Left
newPosition = move(Direction.Left, 1);
}
if (Input.GetKey(KeyCode.D) && Physics2D.Raycast(transform.position, Vector2.right, 1, ~(1 << 2)).collider == null) { // Right
newPosition = move(Direction.Right, 1);
}
if (Input.GetKey(KeyCode.W) && Physics2D.Raycast(transform.position, Vector2.up, 1, ~(1 << 2)).collider == null) { // Up
newPosition = move(Direction.Up, 1);
}
if (Input.GetKey(KeyCode.S) && Physics2D.Raycast(transform.position, Vector2.down, 1, ~(1 << 2)).collider == null) { // Down
newPosition = move(Direction.Down, 1);
}
transform.position = Vector3.MoveTowards(transform.position, newPosition, Time.deltaTime * moveSpeed); // Move there
}
}
И NpcMovementController.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NpcMovementController : TileMovementController {
// Defines the direction and number of steps in that direction has to move
[System.Serializable]
public struct MoveStep {
public Direction direction;
public int steps; // Each step is a grid square. 1 step = 1 unit in the grid position
public MoveStep(Direction direction, int steps) {
this.direction = direction;
this.steps = steps;
}
}
public List<MoveStep> path = new List<MoveStep>();
public float moveSpeed = 2.0f;
private int nextStepIndex = 0;
private bool waiting = false;
void Start () {
newPosition = transform.position; // Take the initial position
}
private void FixedUpdate() {
if (path.Count > 0) {
if (Vector3.Distance(transform.position, newPosition) < 0.05f && !waiting) {
transform.position = newPosition; // Adjust the position to be exactly what it should be
waiting = true;
StartCoroutine("wait", 2f);
} else {
if (Vector3.Distance(transform.position, newPosition) > 0.05f)
transform.position = Vector3.MoveTowards(transform.position, newPosition, Time.deltaTime * moveSpeed);
}
}
}
IEnumerator wait(float seconds) {
yield return new WaitForSecondsRealtime(seconds);
newPosition = move(path[nextStepIndex].direction, path[nextStepIndex].steps);
if (nextStepIndex == path.Count - 1)
nextStepIndex = 0;
else
nextStepIndex++;
waiting = false;
}
}
В NPCMovementController я пытался сделать raycast для игрока, но без коллайдера / ригтела это делаетне работает, очевидно.Если я присоединяю коллайдер / ригтело, он обнаруживает игрока, но я не могу двигаться.