Testing my mob spawn generator and aggro radius

Page 1 of 1 [ 4 posts ] 

kxmode
Supporting Member
Supporting Member

User avatar

Joined: 14 Oct 2007
Gender: Male
Posts: 2,613
Location: In your neighborhood, knocking on your door. :)

04 Sep 2011, 5:44 am

[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

Code:
using UnityEngine;
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;
      }

   }
   
}



Reindeer
Deinonychus
Deinonychus

User avatar

Joined: 6 May 2011
Age: 31
Gender: Male
Posts: 372

04 Sep 2011, 9:35 am

MWHAHAHA I will sell the source code >:D

Looks really confusing to me but that's because I only can basic java :D


_________________
AS: 132
NT: 36
AQ: 40


kxmode
Supporting Member
Supporting Member

User avatar

Joined: 14 Oct 2007
Gender: Male
Posts: 2,613
Location: In your neighborhood, knocking on your door. :)

04 Sep 2011, 3:16 pm

Reindeer wrote:
MWHAHAHA I will sell the source code >:D


Image

;)



kxmode
Supporting Member
Supporting Member

User avatar

Joined: 14 Oct 2007
Gender: Male
Posts: 2,613
Location: In your neighborhood, knocking on your door. :)

05 Sep 2011, 3:42 pm

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. :)