Testing my mob spawn generator and aggro radius
kxmode
Supporting Member
Joined: 14 Oct 2007
Gender: Male
Posts: 2,613
Location: In your neighborhood, knocking on your door. :)
[youtube]http://www.youtube.com/watch?v=QzbEpAmKq6A[/youtube]
Working progress...
Here's the code for handling the Mob's AI via a Finite State Machine
using System.Collections;
[RequireComponent (typeof(AdvancedMovement))]
[RequireComponent (typeof(SphereCollider))]
public class AI : MonoBehaviour {
private enum State {
Idle, // do nothing
Init, // make sure that everything needed is present
Setup, // assign values to needed things
Search, // find the player
Attack, // attack the player
Retreat, // retreat to spawn point
Flee // run to the spawn point with another mob
}
public float aggroRadius = 10;
public float baseMeleeRange = 3.5f;
public Transform target;
private Transform _myTransform;
private const float ROTATION_DAMP = .3f;
private const float FORWARD_DAMP = .9f;
private Transform _home;
private State _state;
private bool _alive = true;
private SphereCollider _sphereCollider;
void Start() {
_state = AI.State.Init;
StartCoroutine("FSM");
}
// Finite State Machine (Mob's AI)
private IEnumerator FSM() {
while(_alive) {
Debug.Log("Alive: " + _alive);
switch (_state) {
case State.Init:
Init();
break;
case State.Setup:
Setup();
break;
case State.Search:
Search();
break;
case State.Attack:
Attack();
break;
case State.Retreat:
Retreat();
break;
case State.Flee:
Flee();
break;
}
yield return null;
}
}
private void Init() {
Debug.Log("*** Init ***");
_myTransform = transform;
_home = transform.parent.transform;
_sphereCollider = GetComponent<SphereCollider>();
if (_sphereCollider == null) {
Debug.LogError("SphereCollider doesn't exist");
return;
}
_state = AI.State.Setup;
}
private void Setup() {
Debug.Log("*** Setup ***");
_sphereCollider.center = GetComponent<CharacterController>().center;
_sphereCollider.radius = aggroRadius;
_sphereCollider.isTrigger = true;
_state = AI.State.Search;
_alive = false;
}
private void Search() {
Debug.Log("*** Search ***");
Move();
_state = AI.State.Attack;
}
private void Attack() {
Debug.Log("*** Attack ***");
Move();
_state = AI.State.Retreat;
}
private void Retreat() {
Debug.Log("*** Retreat ***");
_myTransform.LookAt(target);
Move();
_state = AI.State.Search;
}
private void Flee() {
Debug.Log("*** Flee ***");
Move();
_state = AI.State.Search;
}
private void Move() {
if (target) {
// Mob runs forward
Vector3 dir = (target.position - _myTransform.position).normalized;
float direction = Vector3.Dot(dir, transform.forward);
float dist = Vector3.Distance(target.position, _myTransform.position);
if (direction > FORWARD_DAMP && dist > baseMeleeRange) {
SendMessage("MoveMeForward", AdvancedMovement.Forward.forward);
}
else {
SendMessage("MoveMeForward", AdvancedMovement.Forward.none);
}
// Mob rotates towards character
dir = (target.position - _myTransform.position).normalized;
direction = Vector3.Dot(dir, transform.right);
if (direction > ROTATION_DAMP) {
SendMessage("RotateMe", AdvancedMovement.Turn.right);
}
else if (direction < -ROTATION_DAMP) {
SendMessage("RotateMe", AdvancedMovement.Turn.left);
}
else {
SendMessage("RotateMe", AdvancedMovement.Turn.none);
}
} else { // Mob doesn't do anything
SendMessage("MoveMeForward", AdvancedMovement.Forward.none);
SendMessage("RotateMe", AdvancedMovement.Turn.none);
}
}
// Player is in mob's aggro range
public void OnTriggerEnter(Collider other) {
if (other.CompareTag("Player")) {
target = other.transform;
_alive = true;
StartCoroutine("FSM");
}
}
// Player is out of mob's aggro range
public void OnTriggerExit(Collider other) {
if (other.CompareTag("Player")) { // Mob returns to spawnpoint
target = _home;
}
}
}
kxmode
Supporting Member
Joined: 14 Oct 2007
Gender: Male
Posts: 2,613
Location: In your neighborhood, knocking on your door. :)
kxmode
Supporting Member
Joined: 14 Oct 2007
Gender: Male
Posts: 2,613
Location: In your neighborhood, knocking on your door. :)
I wanted at least one underground dungeon on my map. Unfortunately the terrain tools in Unity 3D do not offer any way to make terrain holes. But I figured out how to do this with a combination of transparency materials and ignore terrain scripting. All in all about 6 hours to create this...
[youtube]http://www.youtube.com/watch?v=fRQnpwf09H8[/youtube]I like the results. ![]()
