Unity弓箭手敌人箭矢朝向玩家初始位置移动问题求助
Unity弓箭手箭矢朝向玩家当前位置的问题解决与优化
问题根源分析
你的代码存在三个核心问题:
- 箭矢脚本致命赋值错误:
Start()方法里错误地将playerpos赋值为弓箭手的Transform(playerpos = archer.GetComponent<Transform>()),导致方向计算完全偏离。场景中直接放箭矢能正常工作,应该是你手动修正了这个赋值,但预制体保留了错误代码。 - 实例化脚本销毁逻辑错误:
Destroy(arrow, 1)是销毁箭矢预制体本身,而非生成的箭矢实例,会导致后续无法再生成箭矢。 - 方向计算冗余易出错:手动计算绝对值相加的方式不仅复杂,还可能在方向向量为零时触发除零错误。
修正后的代码实现
1. 实例化脚本修正
void Update() { if(Input.GetKeyDown("t")) { // 实例化箭矢并保存实例引用 GameObject spawnedArrow = Instantiate(arrow, archerpos.position, Quaternion.identity); // 1秒后销毁生成的箭矢实例,而非预制体 Destroy(spawnedArrow, 1); } }
2. 箭矢飞行脚本修正(简化版)
using UnityEngine; // 类名遵循C#大写规范 public class Flight : MonoBehaviour { public float arrowSpeed; // 确保预制体中已正确引用场景内的玩家对象 public GameObject player; private Rigidbody2D rb; void Start() { rb = GetComponent<Rigidbody2D>(); // 防御性检查,避免空引用报错 if (player == null) { Debug.LogError("箭矢未设置玩家引用!"); return; } // 计算从箭矢位置指向玩家的单位方向向量 Vector2 direction = (player.transform.position - transform.position).normalized; // 设置刚体速度,保证移动方向正确且速度恒定 rb.velocity = direction * arrowSpeed; } }
更优实现方案(无需依赖Public引用)
为避免预制体引用丢失的问题,可在实例化时直接传递玩家当前位置给箭矢脚本,更灵活可靠:
实例化脚本修改
// 引用场景中的玩家对象 public GameObject player; void Update() { if(Input.GetKeyDown("t")) { GameObject spawnedArrow = Instantiate(arrow, archerpos.position, Quaternion.identity); Flight flight = spawnedArrow.GetComponent<Flight>(); if (flight != null) { // 传递玩家当前位置给箭矢 flight.SetTarget(player.transform.position); } Destroy(spawnedArrow, 1); } }
箭矢飞行脚本修改
using UnityEngine; public class Flight : MonoBehaviour { public float arrowSpeed; private Rigidbody2D rb; void Awake() { // 提前获取刚体组件 rb = GetComponent<Rigidbody2D>(); } // 外部调用的目标设置方法 public void SetTarget(Vector3 targetPosition) { Vector2 direction = (targetPosition - transform.position).normalized; rb.velocity = direction * arrowSpeed; } }
内容的提问来源于stack exchange,提问作者Ondřej Čížek
相关产品推荐
相关产品推荐

