(サンプルコード)
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.AI;
public class EnemyManager : MonoBehaviour
{
private float moveSpeed;
private NavMeshAgent agent;
private GameObject player;
public GameObject bulletPrefb;
public Transform firePoint;
private int count;
public GameObject effectPrefab1;
public GameObject effectPrefab2;
private int HP;
private float searchRange;
private GameObject[] safeZone;
private GameObject[] enemies;
public enum State
{
Normal,
Attack,
Escape,
}
public State mode;
void Start()
{
moveSpeed = 1.5f;
agent = GetComponent<NavMeshAgent>();
player = GameObject.Find("Player");
HP = 5;
StartCoroutine(HPRecovery());
searchRange = 10;
safeZone = GameObject.FindGameObjectsWithTag("SafeZone");
// ゲーム開始時点はノーマルモード
mode = State.Normal;
}
void Update()
{
switch (mode)
{
default:
// ノーマルモードの時にやること
case State.Normal:
MoveAround();
Search();
break;
// 攻撃モードの時にやること
case State.Attack:
FireBullet();
Chase();
Call();
break;
// 離脱モードの時にやること
case State.Escape:
RunAway();
break;
}
}
// 追跡
void Chase()
{
agent.destination = player.transform.position;
agent.stoppingDistance = 5f;
}
// 巡回
void MoveAround()
{
transform.Translate(Vector3.forward * Time.deltaTime * moveSpeed);
RaycastHit hit;
Ray ray = new Ray(transform.position, transform.forward);
if (Physics.Raycast(ray, out hit, 1))
{
GameObject target = hit.collider.gameObject;
if (target.CompareTag("UTurn"))
{
transform.localRotation = Quaternion.Euler(0, transform.eulerAngles.y + 180, 0);
}
else if (target.CompareTag("LTurn"))
{
transform.localRotation = Quaternion.Euler(0, transform.eulerAngles.y + 270, 0);
}
else if (target.CompareTag("RTurn"))
{
transform.localRotation = Quaternion.Euler(0, transform.eulerAngles.y + 90, 0);
}
}
}
// 攻撃(ショット)
void FireBullet()
{
transform.LookAt(player.transform.position);
count += 1;
if (count % 250 == 0)
{
GameObject bullet = Instantiate(bulletPrefb, firePoint.position, Quaternion.identity);
Rigidbody bulletRb = bullet.GetComponent<Rigidbody>();
bulletRb.AddForce(transform.forward * 1000);
Destroy(bullet, 5.0f);
}
}
// 体力(HP)
void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Omizu"))
{
HP -= 1;
// HPが2以下になったら離脱モードに移行する
if (HP < 3)
{
mode = State.Escape;
}
if (HP > 0)
{
GameObject effect1 = Instantiate(effectPrefab1, transform.position, Quaternion.identity);
Destroy(effect1, 0.75f);
}
else
{
GameObject effect2 = Instantiate(effectPrefab2, transform.position, Quaternion.identity);
Destroy(effect2, 0.75f);
Destroy(gameObject);
}
}
}
// 体力回復
private IEnumerator HPRecovery()
{
while (true)
{
HP += 1;
if (HP > 5)
{
HP = 5;
}
yield return new WaitForSeconds(3);
}
}
// 索敵
void Search()
{
RaycastHit hit;
Ray ray = new Ray(transform.position, transform.forward);
if (Physics.Raycast(ray, out hit, searchRange))
{
GameObject target = hit.collider.gameObject;
if (target.CompareTag("PlayerBody"))
{
// プレーヤーを発見したら攻撃モードに移行
mode = State.Attack;
}
}
}
// 逃げる
void RunAway()
{
GameObject farthestZone = null;
float maxDistance = 0f;
// すべてのSafeZoneをチェックして、一番遠いものを探す
foreach (GameObject zone in safeZone)
{
// 自分とsafezoneの距離をチェックして、一番遠いものを探す
float distance = Vector3.Distance(transform.position, zone.transform.position);
// 今までの最大距離より遠ければ、それを暫定1位にする
if (distance > maxDistance)
{
maxDistance = distance;
farthestZone = zone;
}
}
// 見つかった一番遠いZoneを目的地に設定
agent.destination = farthestZone.transform.position;
agent.stoppingDistance = 0f;
// 10秒経過したら「攻撃モード」に戻す
Invoke("AttackMode", 10f);
}
// 仲間を呼ぶ
void Call()
{
enemies = GameObject.FindGameObjectsWithTag("Enemy");
foreach (GameObject g in enemies)
{
EnemyManager em = g.GetComponent<EnemyManager>();
em.mode = State.Attack;
}
}
// 攻撃モードに戻る
void AttackMode()
{
mode = State.Attack;
}
}