Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Wandering

Discussion in 'Scripting' started by Custardcs, Mar 3, 2016.

  1. Custardcs

    Custardcs

    Joined:
    Aug 26, 2015
    Posts:
    57
    Hey :rolleyes:

    been having issues... my AI script

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Enemy_AI : MonoBehaviour
    5. {
    6.     public float enemyLookDistance;
    7.     public float attackDistance;
    8.     public float enemyMoveSpeed;
    9.     public float enemyRotSpeed;
    10.  
    11.     //zombie health
    12.     public float ZomMaxHealth = 100;
    13.     public float ZomCurHealth = 100;
    14.  
    15.  
    16.     //brainPrefab.
    17.     public GameObject zombieBrain;
    18.  
    19.  
    20.     private Transform target;
    21.     //private Renderer myRender;
    22.     private Animator anim;
    23.  
    24.  
    25.     void Awake()
    26.     {
    27.         anim = GetComponent<Animator> ();
    28.         //myRender = GetComponent<Renderer> ();
    29.         ZomCurHealth = ZomMaxHealth;
    30.     }
    31.  
    32.     public void Damage(float amount)
    33.     {
    34.         ZomCurHealth -= amount;
    35.  
    36.         if (ZomCurHealth <= 0)
    37.         {
    38.             GameObject brains = GameObject.Instantiate<GameObject> (zombieBrain);
    39.             brains.transform.position = transform.position;
    40.             brains.transform.rotation = Quaternion.identity;
    41.             GameObject.Destroy(brains,20);
    42.  
    43.  
    44.             Destroy (gameObject);
    45.         }
    46.     }
    47.  
    48.     // Update is called once per frame
    49.     void Update ()
    50.     {
    51.         //make sure the player exists
    52.         if (target == null)
    53.         {
    54.             target = Player.GetTransform();
    55.  
    56.             if (target == null)
    57.             {
    58.                 //default to wander aimlessly if there is no player
    59.                 Wander();
    60.                 return;
    61.             }
    62.         }
    63.  
    64.         float fpsTargetDistance = Vector3.Distance (target.position, transform.position);
    65.  
    66.         if (fpsTargetDistance < attackDistance)
    67.         {
    68.             ChasePlayer ();
    69.             return;
    70.         }
    71.  
    72.         if (fpsTargetDistance < enemyLookDistance)
    73.         {
    74.             Alerted();
    75.             return;
    76.         }
    77.            
    78.         //default to Wander mode
    79.         Wander ();
    80.     }
    81.  
    82.     void Alerted()
    83.     {
    84.         anim.Play ("Walk1", 0);
    85.         //myRender.material.color = Color.yellow;
    86.         Quaternion rotation = Quaternion.LookRotation (target.position - transform.position);
    87.         transform.rotation = Quaternion.Slerp (transform.rotation, rotation, Time.deltaTime * enemyRotSpeed);
    88.         transform.position += transform.forward * 1 * Time.deltaTime;
    89.  
    90.     }
    91.     //chase the player
    92.     void ChasePlayer ()
    93.     {
    94.         anim.Play ("Run2", 0);
    95.         //myRender.material.color = Color.red;
    96.         Quaternion rotation = Quaternion.LookRotation (target.position - transform.position);
    97.         transform.rotation = Quaternion.Slerp (transform.rotation, rotation, Time.deltaTime * enemyRotSpeed);
    98.         transform.position += transform.forward * enemyMoveSpeed * Time.deltaTime;
    99.  
    100.     }
    101.  
    102.     //wandering
    103.     void Wander ()
    104.     {
    105.        
    106.         //myRender.material.color = Color.blue;
    107.         //Play The Animation
    108.         anim.Play ("Idle", 0);
    109.     }
    110. }


    found this wandering script
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. /// <summary>
    5. /// Creates wandering behaviour for a CharacterController.
    6. /// </summary>
    7. [RequireComponent(typeof(CharacterController))]
    8. public class Wander : MonoBehaviour
    9. {
    10.     public float speed = 5;
    11.     public float directionChangeInterval = 1;
    12.     public float maxHeadingChange = 30;
    13.  
    14.     CharacterController controller;
    15.     float heading;
    16.     Vector3 targetRotation;
    17.  
    18.     void Awake ()
    19.     {
    20.         controller = GetComponent<CharacterController>();
    21.  
    22.         // Set random initial rotation
    23.         heading = Random.Range(0, 360);
    24.         transform.eulerAngles = new Vector3(0, heading, 0);
    25.  
    26.         StartCoroutine(NewHeading());
    27.     }
    28.  
    29.     void Update ()
    30.     {
    31.         transform.eulerAngles = Vector3.Slerp(transform.eulerAngles, targetRotation, Time.deltaTime * directionChangeInterval);
    32.         var forward = transform.TransformDirection(Vector3.forward);
    33.         controller.SimpleMove(forward * speed);
    34.     }
    35.  
    36.     /// <summary>
    37.     /// Repeatedly calculates a new direction to move towards.
    38.     /// Use this instead of MonoBehaviour.InvokeRepeating so that the interval can be changed at runtime.
    39.     /// </summary>
    40.     IEnumerator NewHeading ()
    41.     {
    42.         while (true) {
    43.             NewHeadingRoutine();
    44.             yield return new WaitForSeconds(directionChangeInterval);
    45.         }
    46.     }
    47.  
    48.     /// <summary>
    49.     /// Calculates a new direction to move towards.
    50.     /// </summary>
    51.     void NewHeadingRoutine ()
    52.     {
    53.         var floor = transform.eulerAngles.y - maxHeadingChange;
    54.         var ceil  = transform.eulerAngles.y + maxHeadingChange;
    55.         heading = Random.Range(floor, ceil);
    56.         targetRotation = new Vector3(0, heading, 0);
    57.     }
    58. }
    now i tried with this way before and it does not work the zombie spins in circles.. i have not tried with nav mesh and i cant because realtime placing of obstructions will cause issues :|

    so i need to script it in order for the zombie to wander aimlessly say walk for like 3 seconds then find a new direction..

    can anyone explain the process ?
     
  2. Custardcs

    Custardcs

    Joined:
    Aug 26, 2015
    Posts:
    57
    this is my code for now which makes the zombie spin 360 :|

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Enemy_AI : MonoBehaviour
    5. {
    6.     public float enemyLookDistance;
    7.     public float attackDistance;
    8.     public float enemyMoveSpeed;
    9.     public float enemyRotSpeed;
    10.  
    11.     //zombie health
    12.     public float ZomMaxHealth = 100;
    13.     public float ZomCurHealth = 100;
    14.  
    15.  
    16.     //brainPrefab.
    17.     public GameObject zombieBrain;
    18.  
    19.  
    20.     private Transform target;
    21.     //private Renderer myRender;
    22.     private Animator anim;
    23.  
    24.  
    25.     void Awake()
    26.     {
    27.         anim = GetComponent<Animator> ();
    28.         //myRender = GetComponent<Renderer> ();
    29.         ZomCurHealth = ZomMaxHealth;
    30.     }
    31.  
    32.     public void Damage(float amount)
    33.     {
    34.         ZomCurHealth -= amount;
    35.  
    36.         if (ZomCurHealth <= 0)
    37.         {
    38.             GameObject brains = GameObject.Instantiate<GameObject> (zombieBrain);
    39.             brains.transform.position = transform.position;
    40.             brains.transform.rotation = Quaternion.identity;
    41.             GameObject.Destroy(brains,20);
    42.  
    43.  
    44.             Destroy (gameObject);
    45.         }
    46.     }
    47.  
    48.     // Update is called once per frame
    49.     void Update ()
    50.     {
    51.         //make sure the player exists
    52.         if (target == null)
    53.         {
    54.             target = Player.GetTransform();
    55.  
    56.             if (target == null)
    57.             {
    58.                 //default to wander aimlessly if there is no player
    59.                 Wander();
    60.                 return;
    61.             }
    62.         }
    63.  
    64.         float fpsTargetDistance = Vector3.Distance (target.position, transform.position);
    65.  
    66.         if (fpsTargetDistance < attackDistance)
    67.         {
    68.             ChasePlayer ();
    69.             return;
    70.         }
    71.  
    72.         if (fpsTargetDistance < enemyLookDistance)
    73.         {
    74.             Alerted();
    75.             return;
    76.         }
    77.            
    78.         //default to Wander mode
    79.         Wander ();
    80.     }
    81.  
    82.     void Alerted()
    83.     {
    84.         anim.Play ("Walk1", 0);
    85.         //myRender.material.color = Color.yellow;
    86.         Quaternion rotation = Quaternion.LookRotation (target.position - transform.position);
    87.         transform.rotation = Quaternion.Slerp (transform.rotation, rotation, Time.deltaTime * enemyRotSpeed);
    88.         transform.position += transform.forward * 1 * Time.deltaTime;
    89.  
    90.     }
    91.     //chase the player
    92.     void ChasePlayer ()
    93.     {
    94.         anim.Play ("Run2", 0);
    95.         //myRender.material.color = Color.red;
    96.         Quaternion rotation = Quaternion.LookRotation (target.position - transform.position);
    97.         transform.rotation = Quaternion.Slerp (transform.rotation, rotation, Time.deltaTime * enemyRotSpeed);
    98.         transform.position += transform.forward * enemyMoveSpeed * Time.deltaTime;
    99.  
    100.     }
    101.  
    102.     //wandering
    103.     void Wander ()
    104.     {
    105.         //var
    106.         float heading;
    107.         Vector3 targetRotation;
    108.  
    109.         //script
    110.         heading = Random.Range(0, 360);
    111.         transform.eulerAngles = new Vector3(0, heading, 0);
    112.         targetRotation = new Vector3(0, heading, 0);
    113.  
    114.  
    115.         //Quaternion rotation = Quaternion.LookRotation (heading);
    116.         //transform.rotation = Quaternion.Slerp (transform.rotation, rotation, Time.deltaTime * enemyRotSpeed);
    117.         transform.eulerAngles = Vector3.Slerp(transform.eulerAngles, targetRotation, Time.deltaTime * 5);
    118.         transform.position += transform.forward * 1 * Time.deltaTime;
    119.  
    120.         //Play The Animation
    121.         anim.Play ("Idle", 0);
    122.     }
    123.  
    124. }
    also another question that someone might be able to help with...

    the zombie does not stay on the ground it kinda floats up and down? in the sky? if i use rigid body it drops thru floor even i dont know how to keep it against the ground. without frrezing stuff but the if the terrain is different it kinda goes floating again
     
  3. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    Hi,
    On my side, I tried the Wander script and the character moved in roughly one direction while slightly changing bearing.
    I had difficulties to understand what was going on, so I decided to rewrite this script and create a BT script that does what you are expecting. It's also an occasion to demonstrate a package I'm maintaining ;) (available here: http://www.pandabehaviour.com)

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using Panda;
    4.  
    5. /// <summary>
    6. /// BT Tasks for moving a CharacterController.
    7. /// </summary>
    8. [RequireComponent(typeof(CharacterController))]
    9. public class Wander : MonoBehaviour
    10. {
    11.     public float speed = 5.0f;
    12.     public float rotationSpeed = 2.0f*Mathf.PI;
    13.     public float wanderingRadius = 10.0f;
    14.  
    15.     CharacterController controller;
    16.     Vector3 destination;
    17.  
    18.     void Awake()
    19.     {
    20.         controller = GetComponent<CharacterController>();
    21.         destination = this.transform.position;
    22.     }
    23.  
    24.     [Task]
    25.     bool SetRandomDestination()
    26.     {
    27.         destination = this.transform.position + Random.insideUnitSphere * wanderingRadius;
    28.         destination.y = this.transform.position.y;
    29.         return true;
    30.     }
    31.  
    32.     [Task]
    33.     void MoveToDestination()
    34.     {
    35.         var destinationDelta = destination - this.transform.position;
    36.         var destinationDirection = destinationDelta.normalized;
    37.         var velocity = destinationDirection.normalized * speed;
    38.         var remainingDistance = destinationDelta.magnitude;
    39.  
    40.         this.controller.SimpleMove( velocity );
    41.         var newDir = Vector3.RotateTowards(this.transform.forward, destinationDirection, rotationSpeed*Time.deltaTime, 1.0f);
    42.         this.transform.rotation = Quaternion.LookRotation(newDir);
    43.  
    44.         if( remainingDistance < 0.1f )
    45.             Task.current.Succeed();
    46.     }
    47.  
    48. }
    And the BT script (Which should be new for you):
    Code (CSharp):
    1. tree "Root"
    2.     sequence
    3.         SetRandomDestination
    4.         MoveToDestination
    5.  
    Please ask me if you need clarifications.
    Also this wandering behaviour is independent to your AI. Though it should be easy to integrated it. Also, I think it should be easier to write your AI in a Behaviour Tree style. I would glad to help if you are interested.
     
    Last edited: Mar 3, 2016
  4. Custardcs

    Custardcs

    Joined:
    Aug 26, 2015
    Posts:
    57
    hey bud. im going to be honest i am not a coder.. i understand basic stuff and logic.. i am an artist. so when you start introducing plugins and stuff i dont even understand why i would need it yet alone how i would use it.
     
  5. Custardcs

    Custardcs

    Joined:
    Aug 26, 2015
    Posts:
    57
    I found a fix tho its kinda weird... i feel i might be doubling up on data being used... i created a nav mesh.. and appied a navmesh agent to the zombie.. it now sticks to the floor but obviously when i put a object down unless its baked it goes right thru it :|
     
  6. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    Sorry, I didn't know you was not a coder. I assumed you wrote the Enemey_AI script yourself.

    I made this package to actually simplify coding. Though it requires to know about Behaviour Tree, it does not requires advanced programming skills on the C# side. All you need to know is how to write a method and tag it with the [Task] attribute.
     
  7. Custardcs

    Custardcs

    Joined:
    Aug 26, 2015
    Posts:
    57
    I did write the code my self with tutorials and trial and error :p but i have no idea as to this method you speaking of
     
  8. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    Behaviour Tree is a technique used in AI. It can be a good alternative to Finite State Machine. It simplifies your work flow a lot. In fact since I learned about BT, I won't design anything complex using FSM anymore. What I am saying here is BT is a great tool to add to your tool box and it is worth learning about.

    But maybe it is a bit earlier for you to learn more about it and you need to focus on learning the fundamentals of programming first.
     
  9. Custardcs

    Custardcs

    Joined:
    Aug 26, 2015
    Posts:
    57
    its quite hectic doing the animation/3d/lighting/texturing/ coding etc :|
     
  10. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    You're a Jack of all trades! :)