Unity 攻击槽系统教程之四 Enemy的槽位排列实现

2025-04-10 17:42:06

1、在场景中,拷贝多个 Enemy,运行场景,多个 Enemy 都围绕 Player 移动,具体如下图

Unity 攻击槽系统教程之四 Enemy的槽位排列实现
Unity 攻击槽系统教程之四 Enemy的槽位排列实现
Unity 攻击槽系统教程之四 Enemy的槽位排列实现

2、在工程中,新建一个脚本SlotManager,双击打开或右键“Open C# Project”进行编辑,具体如下图

Unity 攻击槽系统教程之四 Enemy的槽位排列实现

3、SlotManager 脚本的具体代码和代码说明如下图

Unity 攻击槽系统教程之四 Enemy的槽位排列实现
Unity 攻击槽系统教程之四 Enemy的槽位排列实现
Unity 攻击槽系统教程之四 Enemy的槽位排列实现
Unity 攻击槽系统教程之四 Enemy的槽位排列实现

4、SlotManager 脚本的具体内容如下:using System.Collections;using System.Coll髫潋啜缅ections.Generic;using UnityEngine;public class SlotManager : MonoBehaviour{ //储存Enemy的槽列表,槽的个数以及Enemy与Player的距离 private List<GameObject> slots; public int count = 6; public float distance = 0.8f; void Start() { ///初始化槽列表,存储null slots = new List<GameObject>(); for (int index = 0; index < count; ++index) { slots.Add(null); } } /// <summary> /// 获取对应索引操的位置 /// </summary> /// <param name="index"></param> /// <returns></returns> public Vector3 GetSlotPosition(int index) { //每个操的角度间距,计算出槽相对Player的具体位置,并返回 float degreesPerIndex = 360f / count; Vector3 pos = transform.position; Vector3 offset = new Vector3(0f, 0f, distance); return pos + (Quaternion.Euler(new Vector3(0f, degreesPerIndex * index, 0f)) * offset); } /// <summary> /// 储存Enemy,并返回当前的槽位数 /// </summary> /// <param name="attacker"></param> /// <returns></returns> public int Reserve(GameObject attacker) { //计算当前Enemy和Player的normalized * distance位置 Vector3 bestPosition = transform.position; Vector3 offset = (attacker.transform.position - bestPosition).normalized * distance; bestPosition += offset; //初始化bestSlot和bestDist int bestSlot = -1; float bestDist = 99999f; //遍历槽,把Enemy存到 对应空槽上 for (int index = 0; index < slots.Count; ++index) { if (slots[index] != null) continue; float dist = (GetSlotPosition(index) - bestPosition).sqrMagnitude; if (dist < bestDist) { bestSlot = index; bestDist = dist; } } //把Enemy存到 对应空槽上,并返回当前槽位数 if (bestSlot != -1) slots[bestSlot] = attacker; return bestSlot; } /// <summary> /// 释放槽上的Enemy /// </summary> /// <param name="slot"></param> public void Release(int slot) { slots[slot] = null; } //在场景中画出Player周围的对应槽 void OnDrawGizmosSelected() { //遍历所有槽,根据是否为空槽,画出对应半径0.3f的WireSphere for (int index = 0; index < count; ++index) { if (slots == null || slots.Count <= index || slots[index] == null) Gizmos.color = Color.white; else Gizmos.color = Color.red; Gizmos.DrawWireSphere(GetSlotPosition(index), 0.3f); } }}

5、更新 Enemy 脚本的内容,具体的代码好代码说明如下图

Unity 攻击槽系统教程之四 Enemy的槽位排列实现
Unity 攻击槽系统教程之四 Enemy的槽位排列实现

6、Enemy 脚本的具体内容如下:using 曷决仙喁UnityEngine;using UnityEngine.AI;public class Enemy : MonoBehaviour{ //追随目标设置和刷新位置事件介个设置 GameObject target = null; float pathTime = 0f; //槽位数初始化 int slot = -1; // Use this for initialization void Start() { //获取追随目标 target = GameObject.Find("Player"); } // Update is called once per frame void Update() { //每0.5秒刷新进入If分支 pathTime += Time.deltaTime; if (pathTime > 0.5f) { pathTime = 0f; //获得 SlotManager 脚本,为空怎不进入下面If分支 SlotManager slotManager = target.GetComponent<SlotManager>(); if (slotManager != null) { //存储获取槽位数 if (slot == -1) slot = slotManager.Reserve(gameObject); //如果没有槽了即返回 if (slot == -1) return; //获取 NvaMeshAgent,没有则返回,否则设置目标位置移动 var agent = GetComponent<NavMeshAgent>(); if (agent == null) return; agent.destination = slotManager.GetSlotPosition(slot); } } }}

7、脚本编译正确,回到Unity界面,把 SlotManager 脚本挂载到 Player 物体上,参数根据自己的建模和合理设置即可,具体如下图

Unity 攻击槽系统教程之四 Enemy的槽位排列实现

8、运行场景,Enemy 跟随 Player 在槽位上围绕 Player,具体如下图

Unity 攻击槽系统教程之四 Enemy的槽位排列实现
Unity 攻击槽系统教程之四 Enemy的槽位排列实现

9、其中,在 Scene 中的 WireSphere,绘制如下图

Unity 攻击槽系统教程之四 Enemy的槽位排列实现

10、到此,《Unity 攻击槽系统教程之四 Enemy的槽位排列实现》讲解结束,谢谢

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢