75 lines
2.8 KiB
C#
75 lines
2.8 KiB
C#
using UnityEngine;
|
|
|
|
/// <summary>
|
|
/// 每隔 x 秒,在自身半径 n 米的范围内随机生成一个预制体,并把追踪目标递给它。
|
|
///
|
|
/// 用法:挂在场景里任意物体上,把要生成的预制体拖到 prefab 字段,把玩家根节点拖到 target 字段,
|
|
/// 再填间隔和半径。
|
|
/// 生成位置在以自身为圆心、半径 n 米的**水平圆面**内(Y 跟自身一致),不会掉到地下或飘到天上。
|
|
/// 生成的物体放在场景根节点下,朝向用 Identity。
|
|
///
|
|
/// 目标传递:生成出来的敌人拿不到场景里的玩家引用(预制体资产存不下场景对象),
|
|
/// 所以在 Instantiate 之后把 target 赋给它身上的 EnemyChaseController。
|
|
/// </summary>
|
|
[DisallowMultipleComponent]
|
|
public class PrefabSpawner : MonoBehaviour
|
|
{
|
|
[Header("敌人引用(必须在 Inspector / 预制体里指定)")]
|
|
[Tooltip("要生成的预制体,根节点上必须有 EnemyChaseController")]
|
|
[SerializeField] private GameObject prefab;
|
|
|
|
[Tooltip("生成后赋给敌人的追踪目标,拖玩家根节点进来")]
|
|
[SerializeField] private Transform target;
|
|
|
|
[Header("生成")]
|
|
[Tooltip("生成间隔(秒),必须大于 0")]
|
|
[SerializeField] private float interval = 1f;
|
|
|
|
[Tooltip("随机范围半径(米),以自身位置为圆心")]
|
|
[SerializeField] private float radius = 5f;
|
|
|
|
private float _timer;
|
|
|
|
private void Awake()
|
|
{
|
|
if (prefab == null)
|
|
{
|
|
Debug.LogError("[PrefabSpawner] 没有指定要生成的预制体(prefab),请在 Inspector 里拖入。", this);
|
|
return;
|
|
}
|
|
|
|
if (target == null)
|
|
Debug.LogError("[PrefabSpawner] 没有指定目标(target),生成出来的敌人不会有追踪目标。", this);
|
|
|
|
if (prefab.GetComponent<EnemyChaseController>() == null)
|
|
Debug.LogError("[PrefabSpawner] 这个预制体上没有 EnemyChaseController,目标传不进去。", this);
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (prefab == null)
|
|
return; // Awake 已经报过错
|
|
|
|
_timer += Time.deltaTime;
|
|
if (_timer < interval)
|
|
return;
|
|
|
|
_timer -= interval;
|
|
Spawn();
|
|
}
|
|
|
|
/// <summary>在自身半径 radius 米的水平圆面内随机取一点,生成预制体。</summary>
|
|
private void Spawn()
|
|
{
|
|
Vector2 offset = Random.insideUnitCircle * radius;
|
|
Vector3 position = transform.position + new Vector3(offset.x, 0f, offset.y);
|
|
|
|
GameObject instance = Instantiate(prefab, position, Quaternion.identity);
|
|
|
|
// 实例拿不到场景里的玩家引用,这里递进去
|
|
EnemyChaseController enemy = instance.GetComponent<EnemyChaseController>();
|
|
if (enemy != null)
|
|
enemy.SetTarget(target);
|
|
}
|
|
}
|