我需要的是,如果玩家挡路的话,通过脚本在路径中移动的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中,我尝试对玩家进行光线投射,但没有碰撞器/装配体,它显然不起作用。如果我连接对撞机/ rigitbody它会检测到播放器,但我无法移动。
答案 0 :(得分:1)
我曾做过类似的事情,我通过检查玩家的位置是否在代表npc路径的网格方格内来解决。例如。
让我们想象一下npc会这样移动:
(0,0) - &gt; (0,1) - &gt; (0,2) - &gt; (0,3) - &gt; (1,3) - &gt; (2,3) - &gt; (2,2) - &gt; (2,1) - &gt; (2,0) - &gt; (1,0) - &gt; (0,0)循环
因此,根据我的理解,如果npc在(0,0)中,它将在(0,1),(0,2)和(0,3)中检测到播放器。因此,您可以检查网格中的这三个位置,并将它们与玩家的当前位置进行比较,如果匹配,则该玩家位于路径中。
除此之外,还可以使用刚体来移动您的播放器(这样您就可以继续使用光线投射方法)。您可以使用刚体的速度将npc向一个方向移动。
//moveHorizontal and moveVertical can have +1 or -1 values depending on the inputs of the player:
Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);
rigidbody.velocity = movement * speed;