Unity 2D俯视角敌人追踪玩家并避障脚本问题求助
Unity 2D俯视角敌人追踪玩家并避障脚本问题求助
嘿,别慌!新手刚接触Unity脚本遇到问题太正常啦,我来帮你把这个脚本补全优化,让敌人既能稳稳追踪玩家,又能聪明躲开障碍物。
先看看你的需求和未完成的代码:
I'm having a problem using this script. Could you help a newbie?
I need the enemy to chase the player and avoid obstacles. Game from aboveusing System.Collections; using System.Collections.Generic; using UnityEngine; public class enemy : MonoBehaviour { public float speed = 5f; public float maxSpeed = 10f; public float avoidanceForceMultiplier = 5f; public float raySpacing = 0.5f; public LayerMask obstacleLayerMask; private Rigidbody2D rb; private Transform Player; private void Start() { rb = GetComponent<Rigidbody2D>(); Player = GameObject.FindGameObjectWithTag("Player").GetComponent<Transform>(); } private void Update() { // Determine direction of movement Vector2 playerDirection = (Player.position - transform.position).normalized; // Cast rays to detect obstacles RaycastHit2D[] hits = new RaycastHit2D[3]; Vector2 rayStart = transform.position * pla...
你的代码在Update方法里截断了,而且还有几个可以调整的细节,比如物理逻辑的时机、空值判断这些。下面是补全并优化后的完整脚本,我会逐段给你解释:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Enemy : MonoBehaviour // 类名首字母大写是C#规范,方便后续维护 { public float speed = 5f; public float maxSpeed = 10f; public float avoidanceForceMultiplier = 5f; public float raySpacing = 0.5f; public float rayLength = 1.5f; // 新增射线长度,控制障碍物检测的距离 public LayerMask obstacleLayerMask; private Rigidbody2D rb; private Transform player; // 变量名首字母小写更符合编码习惯 private void Start() { rb = GetComponent<Rigidbody2D>(); // 增加空值判断,避免找不到Player时直接报错崩溃 GameObject playerObj = GameObject.FindGameObjectWithTag("Player"); if (playerObj != null) { player = playerObj.GetComponent<Transform>(); } else { Debug.LogError("场景里找不到标签为Player的物体哦!"); } } // 物理相关逻辑用FixedUpdate更合适,和Unity的物理更新帧同步,移动会更平滑 private void FixedUpdate() { if (player == null) return; // 找不到玩家就不执行后续逻辑 // 1. 计算朝向玩家的基础方向 Vector2 playerDirection = (player.position - transform.position).normalized; // 2. 计算避障需要修正的方向 Vector2 avoidanceDirection = CalculateAvoidanceDirection(); // 3. 合并追踪方向和避障方向,得到最终移动方向 Vector2 finalDirection = (playerDirection + avoidanceDirection).normalized; // 4. 给刚体施加力控制移动,同时限制最大速度 rb.AddForce(finalDirection * speed); rb.velocity = Vector2.ClampMagnitude(rb.velocity, maxSpeed); } private Vector2 CalculateAvoidanceDirection() { Vector2 avoidanceDir = Vector2.zero; int hitObstacleCount = 0; // 发射三条射线:正前方、左前方、右前方(适配俯视角的检测范围) Vector2[] rayDirections = new Vector2[] { transform.right, // 敌人自身正前方(如果你的游戏用Y轴当前方,改成transform.up即可) transform.right + transform.up * raySpacing, // 右前方偏移 transform.right - transform.up * raySpacing // 左前方偏移 }; foreach (Vector2 dir in rayDirections) { RaycastHit2D hit = Physics2D.Raycast(transform.position, dir, rayLength, obstacleLayerMask); if (hit) { // 编辑器里绘制红色射线,方便调试时看到检测到障碍物的区域 Debug.DrawRay(transform.position, dir * rayLength, Color.red); // 计算远离障碍物的方向 avoidanceDir += (Vector2)transform.position - hit.point; hitObstacleCount++; } else { // 没检测到障碍物时绘制绿色射线 Debug.DrawRay(transform.position, dir * rayLength, Color.green); } } if (hitObstacleCount > 0) { // 归一化方向后乘以力度系数,控制避障的强度 return avoidanceDir.normalized * avoidanceForceMultiplier; } return Vector2.zero; // 没有障碍物时返回零向量,不影响追踪 } }
最后给你几个使用时的小提醒:
- 确保你的障碍物所在的图层,和脚本里
obstacleLayerMask选择的图层完全一致,不然射线检测不到障碍物。 - 可以在Unity编辑器里调整
rayLength、avoidanceForceMultiplier这些参数,找到最适合你游戏的手感。 - 如果你的游戏里敌人的前方是
transform.up(比如2D游戏常用Y轴朝上),记得把rayDirections里的transform.right改成transform.up。
备注:内容来源于stack exchange,提问作者Kokotrek Youtube
相关产品推荐
相关产品推荐

