using UnityEngine;
using System.Collections.Generic;
using System.Linq;
public class AIController : MonoBehaviour
{
public Transform player;
public LayerMask targetMask;
public LayerMask obstacleMask;
public GameObject bullet;
public Transform bulletPosition;
public int maxHealth = 100;
public float activeDist;
public float attackRange = 1;
public float shootDelayTime = 2f;
public float rotateSpeed = 5;
private NavMeshAgent navMesh;
private List<Transform> visibleTargets = new List<Transform>();
private Transform target;
private EnemyState enemyState;
private int currentHealth;
private float shootCountTime;
public enum EnemyState
{
IDLE,
MOVE,
ATTACK,
DIE
}
void Start()
{
navMesh = GetComponent<NavMeshAgent>();
enemyState = EnemyState.IDLE;
currentHealth = maxHealth;
}
void Update()
{
// ทำการย้าย CheckTargetArea จาก IDLE State มาไว้ที่ Update()
CheckTargetArea();
if (currentHealth <= 0)
{
currentHealth = 0;
enemyState = EnemyState.DIE;
}
CheckState();
}
private void CheckState()
{
switch (enemyState)
{
case EnemyState.IDLE:
ProcessIdle();
break;
case EnemyState.MOVE:
ProcessMove();
break;
case EnemyState.ATTACK:
ProcessAttack();
break;
case EnemyState.DIE:
ProcessDie();
break;
}
}
private void ProcessIdle()
{
navMesh.Stop();
}
private void ProcessMove()
{
if (player == null)
{
return;
}
navMesh.updateRotation = true;
navMesh.destination = target.position;
navMesh.Resume();
}
private void ProcessAttack()
{
// หยุดเมื่อยู่ในระยะโจมตี
navMesh.Stop();
float dist = Vector3.Distance(target.position, transform.position);
if (dist >= attackRange)
{
enemyState = EnemyState.MOVE;
return;
}
navMesh.updateRotation = false;
UpdateRotation();
// attack
shootCountTime -= Time.deltaTime;
if (shootCountTime > 0)
{
return;
}
GameObject obj = ObjectPooling.current.GetPooledObject();
if (obj == null)
{
return;
}
obj.transform.position = bulletPosition.position;
obj.transform.rotation = bulletPosition.rotation;
obj.SetActive(true);
shootCountTime = shootDelayTime;
}
// แนะนำให้ทำการสร้าง Base Class และให้ Player และ AI ทำการ Inheritance
// เพื่อ Reuse Variables และ Function นะครับ
private void UpdateRotation()
{
Vector3 rot = target.position - transform.position;
Quaternion lookAt = Quaternion.LookRotation(rot);
transform.rotation = Quaternion.Lerp(transform.rotation, lookAt, Time.deltaTime * rotateSpeed);
}
private void ProcessDie()
{
// player ie animation
Destroy(gameObject);
}
private void CheckTargetArea()
{
visibleTargets.Clear();
Collider[] colliders = Physics.OverlapSphere(transform.position, activeDist, targetMask);
for (int i = 0; i < colliders.Length; i++)
{
Transform targetArea = colliders[i].transform;
Vector3 dirToTarget = (targetArea.position - transform.position).normalized;
if (Vector3.Angle(transform.forward, dirToTarget) < (360 * 0.5f))
{
float distToTarget = Vector3.Distance(transform.position, targetArea.position);
if (!Physics.Raycast(transform.position, dirToTarget, distToTarget, obstacleMask))
{
visibleTargets.Add(targetArea);
}
}
}
if (visibleTargets.Count > 0)
{
target = visibleTargets.First();
float dist = Vector3.Distance(target.position, transform.position);
if (dist < attackRange)
{
enemyState = EnemyState.ATTACK;
return;
}
}
else
{
if (target == null)
{
enemyState = EnemyState.IDLE;
return;
}
}
enemyState = EnemyState.MOVE;
}
void OnTriggerEnter(Collider hit)
{
if (hit.CompareTag("Bullet"))
{
currentHealth -= 25;
}
}
}
using System.Collections;
using System.Reflection;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
[RequireComponent(typeof(Rigidbody))]
public class PlayerMovment : MonoBehaviour
{
public int playerHelath = 100;
public float moveSpeed = 5.0f;
public float rotateSpeed = 5.0f;
public float shootDelayTime = 0.5f;
public float delay = 1.0f;
public float autoLockDist = 7f;
public GameObject bullet;
public Transform bulletPosition;
public Transform target;
public UIController uiController;
public int currentBullet;
public int bulletPerMag = 15;
private Vector3 moveDirection;
private Rigidbody rb;
private float shootCountTime = 0.0f;
private bool isReadyToShoot;
private bool isReload;
private bool isLockTarget;
void Start()
{
rb = GetComponent<Rigidbody>();
currentBullet = bulletPerMag;
}
void Update()
{
shootCountTime -= Time.deltaTime;
isReadyToShoot = shootCountTime <= 0f;
if (currentBullet <= 0)
{
// reload
StartCoroutine(Reload());
return;
}
if (CrossPlatformInputManager.GetButton("Fire") && isReadyToShoot && !isReload)
{
GameObject obj = ObjectPooling.current.GetPooledObject();
if (obj == null)
{
return;
}
obj.transform.position = bulletPosition.position;
obj.transform.rotation = bulletPosition.rotation;
obj.SetActive(true);
shootCountTime = shootDelayTime;
--currentBullet;
}
if (CrossPlatformInputManager.GetButtonDown("Reload") && !isReload)
{
// reload
StartCoroutine(Reload());
}
uiController.SetPlayerHealth(playerHelath);
uiController.SetBullet(currentBullet, bulletPerMag);
CheckAutoLockTarget();
}
private void CheckAutoLockTarget()
{
if (!target)
{
return;
}
float dist = Vector3.Distance(transform.position, target.position);
if (dist <= autoLockDist)
{
isLockTarget = true;
LockTarget();
}
else
{
isLockTarget = false;
}
}
// แนะนำให้ทำการสร้าง Base Class และให้ Player และ AI ทำการ Inheritance
// เพื่อ Reuse Variables และ Function นะครับ
private void LockTarget()
{
Vector3 rot = target.position - transform.position;
Quaternion lookAt = Quaternion.LookRotation(rot);
transform.rotation = Quaternion.Lerp(transform.rotation, lookAt, Time.deltaTime * rotateSpeed);
}
private IEnumerator Reload()
{
if (!isReload)
{
isReload = true;
yield return new WaitForSeconds(delay);
currentBullet = bulletPerMag;
isReload = false;
}
}
void FixedUpdate()
{
#if UNITY_EDITOR
moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0 , Input.GetAxis("Vertical"));
#else
moveDirection = new Vector3(CrossPlatformInputManager.GetAxis("Horizontal"), 0 , CrossPlatformInputManager.GetAxis("Vertical"));
#endif
Move();
Turn();
}
void Move()
{
moveDirection = moveDirection.normalized * moveSpeed * Time.deltaTime;
rb.MovePosition(transform.position + moveDirection);
}
void Turn()
{
if (isLockTarget)
{
return;
}
if (moveDirection.x != 0 || moveDirection.z != 0)
{
//rotate player
Vector3 faceDirection = moveDirection + transform.position;
faceDirection.y = transform.position.y;
if ((faceDirection - transform.position) == Vector3.zero)
{
return;
}
Quaternion rotation = Quaternion.LookRotation(faceDirection - transform.position);
transform.rotation = Quaternion.Lerp(transform.rotation, rotation, rotateSpeed * Time.deltaTime);
}
}
ปล. แนะนำได้นะครับ
NO GAME NO DREAM !!!!