MiniGames/Assets/Scripts/BlockDrop/BlockDrop_BunnyAI3D.cs

124 lines
3.6 KiB
C#

using UnityEngine;
using System.Collections;
[RequireComponent(typeof(Rigidbody))]
public class BlockDrop_BunnyAI3D : MonoBehaviour
{
[Header("Movement")]
public float moveSpeed = 2.5f;
public bool horizontalPatrol = true; // true = X axis, false = Y axis
public float patrolRange = 6f;
public float planeZ = 0f;
[Header("Cloning & Traps")]
public float cloneEverySeconds = 20f;
public GameObject carrotTrapPrefab;
public float trapInterval = 7f;
[Header("Collision Spawning")]
public float spawnCooldown = 5f; // seconds between collision spawns
public int maxBunnies = 30; // population cap
private Rigidbody rb;
private Vector3 startPos;
private int dir = 1;
private float lastSpawnTime;
void Awake()
{
rb = GetComponent<Rigidbody>();
rb.useGravity = false;
rb.constraints = RigidbodyConstraints.FreezeRotation | RigidbodyConstraints.FreezePositionZ;
startPos = transform.position;
// snap bunny to plane Z
Vector3 p = transform.position;
p.z = planeZ;
transform.position = p;
}
void OnEnable()
{
// If you want timed cloning, enable this:
// StartCoroutine(CloneRoutine());
if (carrotTrapPrefab) StartCoroutine(TrapRoutine());
}
void FixedUpdate()
{
float axis = dir * moveSpeed;
// Patrol horizontally or vertically
Vector3 vel = horizontalPatrol
? new Vector3(axis, 0f, 0f)
: new Vector3(0f, axis, 0f);
rb.velocity = vel;
// Distance from starting position
float d = horizontalPatrol
? Mathf.Abs(transform.position.x - startPos.x)
: Mathf.Abs(transform.position.y - startPos.y);
// Reverse direction when reaching patrol range
if (d >= patrolRange)
{
startPos = transform.position;
dir *= -1;
}
}
void OnCollisionEnter(Collision col)
{
if (col.collider.CompareTag("Bunny"))
{
// prevent exponential spawning
if (Time.time - lastSpawnTime >= spawnCooldown)
{
lastSpawnTime = Time.time;
// population cap
if (BlockDrop_GameManager3D.Instance != null &&
BlockDrop_GameManager3D.Instance.bunnyParent.childCount < maxBunnies)
{
BlockDrop_GameManager3D.Instance.SpawnBunny(
transform.position + new Vector3(Random.Range(-2.5f, 2.5f), Random.Range(-2.5f, 2.5f), 0)
);
}
}
}
}
IEnumerator CloneRoutine()
{
var wait = new WaitForSeconds(cloneEverySeconds);
while (true)
{
yield return wait;
if (BlockDrop_GameManager3D.Instance != null &&
BlockDrop_GameManager3D.Instance.bunnyParent.childCount < maxBunnies)
{
BlockDrop_GameManager3D.Instance.SpawnBunny(
transform.position + new Vector3(Random.Range(-1f, 1f), 0f, 0f)
);
}
}
}
IEnumerator TrapRoutine()
{
var wait = new WaitForSeconds(trapInterval);
while (true)
{
yield return wait;
if (carrotTrapPrefab != null)
{
Vector3 trapPos = new Vector3(transform.position.x, transform.position.y + 0.1f, 0f);
Instantiate(carrotTrapPrefab, trapPos, carrotTrapPrefab.transform.rotation);
}
}
}
}