如何解决如何使用 Vector2/3.MoveTowards 使 NPC 仅垂直和水平移动而不是对角线移动,以及如何使 NPC 仅通过瓷砖移动
所以我试图制作一款游戏只是为了好玩,并学习以备将来使用。所以我在制作敌方NPC时遇到了这个问题。我希望它跟随我或追逐我,但我希望 NPC 只能水平和垂直移动,而且我希望 NPC 也能像我的玩家一样移动每块瓷砖。
这是它的外观视频 https://www.youtube.com/watch?v=CB_vdt1Z3nA
这里是NPC脚本
public class ChaseScript : MonoBehaviour
{
public float speed;
private GameObject player;
private Transform player_transform;
void Start()
{
player = GameObject.Find("Player");
}
void Update()
{
player_transform = player.GetComponent<Transform>();
transform.position = Vector3.MoveTowards(transform.position,player_transform.position,speed * Time.deltaTime);
}
}
这是我的播放器控制器
public void InputMove()
{
if (!isMoving)
{
input.x = Input.GetAxisRaw("Horizontal");
input.y = Input.GetAxisRaw("Vertical");
if (input.x != 0) input.y = 0;
if (input != Vector2.zero)
{
playerAnimation.SetParameterValue(animator);
var movePos = transform.position;
movePos.x += input.x;
movePos.y += input.y;
FacingForward.transform.position = movePos;
if (IsWalkable(movePos))
StartCoroutine(Move(movePos));
}
playerAnimation.SetParameterValueisMoving(animator);
}
if (Input.GetKey(KeyCode.LeftShift))
{
moveSpeed = 6f;
animator.speed = 1.5f;
}
else
{
moveSpeed = 4f;
animator.speed = 1f;
}
}
IEnumerator Move(Vector3 movePos)
{
isMoving = true;
while ((movePos - transform.position).sqrMagnitude > Mathf.Epsilon)
{
transform.position = Vector3.MoveTowards(transform.position,movePos,moveSpeed * Time.deltaTime);
yield return null;
}
transform.position = movePos;
isMoving = false;
}
private bool IsWalkable(Vector3 movePos)
{
if (Physics2D.OverlapCircle(movePos,0.1f,SolidObjectLayer | NPC) != null)
{
return false;
}
return true;
}
我对我的播放器所做的每块移动是我只添加 1 来转换,所以这将是一个持续的移动,但我不知道如何使用 Vector3.MoveTowards 将它应用到 NPC 上,但如果不是可以做就可以了
解决方法
检查这是否可行(您可以使其适应您的 2D 案例)
using UnityEngine;
public class ChaseOrthoScript : MonoBehaviour
{
public float speed;
private GameObject player;
private Transform player_transform;
bool isMoving = false;
void Start()
{
player = GameObject.Find("Player");
player_transform = player.GetComponent<Transform>();
transform.LookAt(player_transform.position);
}
void Update()
{
if (transform.InverseTransformPoint(player_transform.position).z > 0) {
transform.position += transform.forward * speed * Time.deltaTime;
isMoving = true;
} else {
if (isMoving) {
float angle = Vector3.Angle(transform.forward,player_transform.position - transform.position);
transform.Rotate(Vector3.up,Mathf.Sign(angle) * 90);
isMoving = false;
} else if (transform.InverseTransformPoint(player_transform.position).z <= 0) { //player is back
transform.Rotate(Vector3.up,180);
}
}
}
}
请注意,player_transform = player.GetComponent<Transform>();
已移至 Start()
。通常您不希望 GetComponents
出现在更新中,因为您只需要获取一次。在脚本中有一个 public GameObject player;
变量并在编辑器中附加 player = GameObject.Find("Player");
.通常,您不希望通过代码中的硬编码魔术值找到场景元素。
希望有所帮助。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。