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

Working on a AI Steering Behavior script

Discussion in 'Assets and Asset Store' started by Attila7894, Mar 13, 2012.

  1. Attila7894

    Attila7894

    Joined:
    Mar 11, 2011
    Posts:
    31
    Hi there ;)

    I'm not sure it's the right section as I'm not putting this script in the Asset store, or at least not yet.

    I started working on a script for defining AI Steering Behaviors and I thought it would be cool to share it, either for helping others and improving it.

    It's quite basic, I only worked on it a couple of hours, and it's written in Javascript. At the moment it uses transforms instead of rigidbodies, may be useful to create a script for both.

    The target object has a Move script attached to it. which I also used to calculate instant velocity:

    Code (csharp):
    1.  
    2.  
    3. #pragma strict
    4.  
    5. public var moveSpeed : int = 10;
    6.  
    7. var instantVelocity : Vector3;
    8.  
    9. function Start () {
    10.     instantVelocity = Vector3.zero;
    11. }
    12.  
    13. function Update () {
    14.     var pos : Vector3 = transform.position;
    15.    
    16.     var horMovement = Input.GetAxis("Horizontal");
    17.     var forwardMovement = Input.GetAxis("Vertical");
    18.  
    19.     if (horMovement) {
    20.         transform.Translate(transform.right * horMovement * Time.deltaTime * moveSpeed);
    21.     }
    22.  
    23.     if (forwardMovement) {
    24.         transform.Translate(transform.forward * forwardMovement * Time.deltaTime * moveSpeed);
    25.     }
    26.    
    27.     instantVelocity = transform.position - pos;
    28. }
    29.  
    30.  
    Then, the current AI script. Currently it has Seek, Flee, Arrive, Pursuit and Evade behaviors. The methods work, but I think some of them still need tweaking.

    I think the next step is to get rid of the switch case.

    Code (csharp):
    1.  
    2.  
    3. /*
    4.  
    5. AI Steering Behavior Script by Attilio Carotenuto - 2012 - All Rights Reserved
    6. http://www.attiliocarotenuto.com
    7.  
    8. */
    9.  
    10. #pragma strict
    11.  
    12. public var target : Transform;
    13.  
    14. public var moveSpeed : float = 6.0;
    15. public var rotationSpeed : float = 1.0;
    16.  
    17. private var minDistance : int = 5;
    18. private var safeDistance : int = 60;
    19.  
    20. enum AIState {Idle, Seek, Flee, Arrive, Pursuit, Evade}
    21. public var currentState : AIState;
    22.  
    23. function Update () {
    24.     switch(currentState){
    25.         case AIState.Idle:
    26.             break;
    27.         case AIState.Seek:
    28.             Seek();
    29.             break;
    30.         case AIState.Flee:
    31.             Flee();
    32.             break;
    33.         case AIState.Arrive:
    34.             Arrive();
    35.             break;
    36.         case AIState.Pursuit:
    37.             Pursuit();
    38.             break;
    39.         case AIState.Evade:
    40.             Evade();
    41.             break;
    42.     }
    43. }
    44.  
    45. function Seek () : void{
    46.     var direction : Vector3 = target.position - transform.position;
    47.    direction.y = 0;
    48.  
    49.    transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
    50.  
    51.    if(direction.magnitude > minDistance){
    52.  
    53.       var moveVector : Vector3 = direction.normalized * moveSpeed * Time.deltaTime;
    54.  
    55.       transform.position += moveVector;
    56.  
    57.    }
    58. }
    59.  
    60. function Flee () : void{
    61.     var direction : Vector3 = transform.position - target.position;
    62.    direction.y = 0;
    63.    
    64.    if(direction.magnitude < safeDistance){
    65.       transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
    66.       var moveVector : Vector3 = direction.normalized * moveSpeed * Time.deltaTime;
    67.       transform.position += moveVector;
    68.    }
    69. }
    70.  
    71. function Arrive () : void{
    72.     var direction : Vector3 = target.position - transform.position;
    73.     direction.y = 0;
    74.    
    75.     var distance : float = direction.magnitude;
    76.    
    77.     var decelerationFactor : float = distance / 5;
    78.    
    79.     var speed : float = moveSpeed * decelerationFactor;
    80.    
    81.     transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
    82.  
    83.     var moveVector : Vector3 = direction.normalized * Time.deltaTime * speed;
    84.     transform.position += moveVector;
    85. }
    86.  
    87. function Pursuit () : void{
    88.     var iterationAhead : int = 30;
    89.    
    90.     var targetSpeed = target.gameObject.GetComponent(Move).instantVelocity;
    91.    
    92.     var targetFuturePosition : Vector3 = target.transform.position + (targetSpeed * iterationAhead);
    93.    
    94.     var direction : Vector3 = targetFuturePosition - transform.position;
    95.     direction.y = 0;
    96.  
    97.    transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
    98.  
    99.    if(direction.magnitude > minDistance){
    100.  
    101.       var moveVector : Vector3 = direction.normalized * moveSpeed * Time.deltaTime;
    102.  
    103.       transform.position += moveVector;
    104.  
    105.    }
    106. }
    107.  
    108. function Evade () : void{
    109.     var iterationAhead : int = 30;
    110.    
    111.     var targetSpeed = target.gameObject.GetComponent(Move).instantVelocity;
    112.    
    113.     var targetFuturePosition : Vector3 = target.position + (targetSpeed * iterationAhead);
    114.    
    115.     var direction : Vector3 = transform.position - targetFuturePosition;
    116.     direction.y = 0;
    117.  
    118.    transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
    119.  
    120.    if(direction.magnitude < safeDistance){
    121.  
    122.       var moveVector : Vector3 = direction.normalized * moveSpeed * Time.deltaTime;
    123.  
    124.       transform.position += moveVector;
    125.  
    126.    }
    127. }
    128.  
    129.  
    The script already works, just attach it to a game object, set a target game object and attach the Move script to it.

    Looking forward for comments ;)
     
    Last edited: Mar 13, 2012
  2. ahengine

    ahengine

    Joined:
    Jul 5, 2012
    Posts:
    10
    Hey guy , good job
     
  3. mecha-box

    mecha-box

    Joined:
    Dec 13, 2012
    Posts:
    3
    Thanks!!
     
  4. vicenterusso

    vicenterusso

    Joined:
    Jan 8, 2013
    Posts:
    130
    Any update on this? :))
     
  5. Edgyr45

    Edgyr45

    Joined:
    Mar 30, 2014
    Posts:
    3
    This code looks like (is) an adaptation from "Programming Game AI by Example" book from Mat Buckland.
     
  6. tanoshimi

    tanoshimi

    Joined:
    May 21, 2013
    Posts:
    297
    @Edgyr45 I don't think so - it's an implementation of the widely-used Steering Behaviours for autonomous characters described by Craig Reynolds (which is described in Buckland's book, and pretty much every other book on Game A.I.).
     
  7. Edgyr45

    Edgyr45

    Joined:
    Mar 30, 2014
    Posts:
    3
    @tanoshimi you're right! thanks for the link, that's a very nice reading. My point in mentioning this was to reply to vicenterusso that "wanted an update on this". Both the book and tanoshimi's link should be next! ;)
     
  8. AttilioC

    AttilioC

    Joined:
    Jun 29, 2014
    Posts:
    86
    @Edgyr45 Not really an adaptation, but "Programming Game AI by Example" is where I learned about steering behaviours, so it's definitely a reference for this script
     
  9. Seyed_Morteza_Kamaly

    Seyed_Morteza_Kamaly

    Joined:
    Nov 18, 2015
    Posts:
    80
    thanks but this code not work for me!

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Move : MonoBehaviour {
    6.  
    7. public int moveSpeed = 10;
    8. public Vector3 instantVelocity;
    9. void Start () {
    10. instantVelocity = Vector3.zero;
    11. }
    12. void Update () {
    13. Vector3 pos = transform.position;
    14. var horMovement = Input.GetAxis("Horizontal");
    15. var forwardMovement = Input.GetAxis("Vertical");
    16. if (horMovement == 1) {
    17. transform.Translate(transform.right * horMovement * Time.deltaTime * moveSpeed);
    18. }
    19. if (forwardMovement == 1) {
    20. transform.Translate(transform.forward * forwardMovement * Time.deltaTime * moveSpeed);
    21. }
    22. instantVelocity = transform.position - pos;
    23. }
    24. }
    25.  
    Code (CSharp):
    1.  
    2.  
    3.  
    4.  
    5. using System.Collections;
    6. using System.Collections.Generic;
    7. using UnityEngine;
    8.  
    9. public class SteeringBehaviours : MonoBehaviour {
    10.  
    11. public Transform target;
    12. public float moveSpeed = 6.0f;
    13. public float rotationSpeed = 1.0f;
    14. private int minDistance = 5;
    15. private int safeDistance = 60;
    16. public enum AIState {Idle, Seek, Flee, Arrive, Pursuit, Evade}
    17. public AIState currentState;
    18. void Update () {
    19. switch(currentState){
    20. case AIState.Idle:
    21. break;
    22. case AIState.Seek:
    23. Seek();
    24. break;
    25. case AIState.Flee:
    26. Flee();
    27. break;
    28. case AIState.Arrive:
    29. Arrive();
    30. break;
    31. case AIState.Pursuit:
    32. Pursuit();
    33. break;
    34. case AIState.Evade:
    35. Evade();
    36. break;
    37. }
    38. }
    39. void Seek (){
    40. Vector3 direction = target.position - transform.position;
    41. direction.y = 0;
    42. transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
    43. if(direction.magnitude > minDistance){
    44. Vector3 moveVector = direction.normalized * moveSpeed * Time.deltaTime;
    45. transform.position += moveVector;
    46. }
    47. }
    48. void Flee () {
    49. Vector3 direction = transform.position - target.position;
    50. direction.y = 0;
    51. if(direction.magnitude < safeDistance){
    52. transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
    53. Vector3 moveVector = direction.normalized * moveSpeed * Time.deltaTime;
    54. transform.position += moveVector;
    55. }
    56. }
    57. void Arrive (){
    58. Vector3 direction = target.position - transform.position;
    59. direction.y = 0;
    60. float distance = direction.magnitude;
    61. float decelerationFactor = distance / 5;
    62. float speed = moveSpeed * decelerationFactor;
    63. transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
    64. Vector3 moveVector = direction.normalized * Time.deltaTime * speed;
    65. transform.position += moveVector;
    66. }
    67. void Pursuit (){
    68. int iterationAhead = 30;
    69. var targetSpeed = target.gameObject.GetComponent<Move>().instantVelocity;
    70. Vector3 targetFuturePosition = target.transform.position + (targetSpeed * iterationAhead);
    71. Vector3 direction = targetFuturePosition - transform.position;
    72. direction.y = 0;
    73. transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
    74. if(direction.magnitude > minDistance){
    75. Vector3 moveVector = direction.normalized * moveSpeed * Time.deltaTime;
    76. transform.position += moveVector;
    77. }
    78. }
    79. void Evade (){
    80. int iterationAhead = 30;
    81. var targetSpeed = target.gameObject.GetComponent<Move>().instantVelocity;
    82. Vector3 targetFuturePosition = target.position + (targetSpeed * iterationAhead);
    83. Vector3 direction = transform.position - targetFuturePosition;
    84. direction.y = 0;
    85. transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
    86. if(direction.magnitude < safeDistance){
    87. Vector3 moveVector = direction.normalized * moveSpeed * Time.deltaTime;
    88. transform.position += moveVector;
    89. }
    90. }
    91. }
    92.  
    93.  
     
  10. Seyed_Morteza_Kamaly

    Seyed_Morteza_Kamaly

    Joined:
    Nov 18, 2015
    Posts:
    80
    thanks but this code not work for me!

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Move : MonoBehaviour {
    6.  
    7. public int moveSpeed = 10;
    8. public Vector3 instantVelocity;
    9. void Start () {
    10. instantVelocity = Vector3.zero;
    11. }
    12. void Update () {
    13. Vector3 pos = transform.position;
    14. var horMovement = Input.GetAxis("Horizontal");
    15. var forwardMovement = Input.GetAxis("Vertical");
    16. if (horMovement == 1) {
    17. transform.Translate(transform.right * horMovement * Time.deltaTime * moveSpeed);
    18. }
    19. if (forwardMovement == 1) {
    20. transform.Translate(transform.forward * forwardMovement * Time.deltaTime * moveSpeed);
    21. }
    22. instantVelocity = transform.position - pos;
    23. }
    24. }
    25.  
    Code (CSharp):
    1.  
    2.  
    3.  
    4.  
    5. using System.Collections;
    6. using System.Collections.Generic;
    7. using UnityEngine;
    8.  
    9. public class SteeringBehaviours : MonoBehaviour {
    10.  
    11. public Transform target;
    12. public float moveSpeed = 6.0f;
    13. public float rotationSpeed = 1.0f;
    14. private int minDistance = 5;
    15. private int safeDistance = 60;
    16. public enum AIState {Idle, Seek, Flee, Arrive, Pursuit, Evade}
    17. public AIState currentState;
    18. void Update () {
    19. switch(currentState){
    20. case AIState.Idle:
    21. break;
    22. case AIState.Seek:
    23. Seek();
    24. break;
    25. case AIState.Flee:
    26. Flee();
    27. break;
    28. case AIState.Arrive:
    29. Arrive();
    30. break;
    31. case AIState.Pursuit:
    32. Pursuit();
    33. break;
    34. case AIState.Evade:
    35. Evade();
    36. break;
    37. }
    38. }
    39. void Seek (){
    40. Vector3 direction = target.position - transform.position;
    41. direction.y = 0;
    42. transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
    43. if(direction.magnitude > minDistance){
    44. Vector3 moveVector = direction.normalized * moveSpeed * Time.deltaTime;
    45. transform.position += moveVector;
    46. }
    47. }
    48. void Flee () {
    49. Vector3 direction = transform.position - target.position;
    50. direction.y = 0;
    51. if(direction.magnitude < safeDistance){
    52. transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
    53. Vector3 moveVector = direction.normalized * moveSpeed * Time.deltaTime;
    54. transform.position += moveVector;
    55. }
    56. }
    57. void Arrive (){
    58. Vector3 direction = target.position - transform.position;
    59. direction.y = 0;
    60. float distance = direction.magnitude;
    61. float decelerationFactor = distance / 5;
    62. float speed = moveSpeed * decelerationFactor;
    63. transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
    64. Vector3 moveVector = direction.normalized * Time.deltaTime * speed;
    65. transform.position += moveVector;
    66. }
    67. void Pursuit (){
    68. int iterationAhead = 30;
    69. var targetSpeed = target.gameObject.GetComponent<Move>().instantVelocity;
    70. Vector3 targetFuturePosition = target.transform.position + (targetSpeed * iterationAhead);
    71. Vector3 direction = targetFuturePosition - transform.position;
    72. direction.y = 0;
    73. transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
    74. if(direction.magnitude > minDistance){
    75. Vector3 moveVector = direction.normalized * moveSpeed * Time.deltaTime;
    76. transform.position += moveVector;
    77. }
    78. }
    79. void Evade (){
    80. int iterationAhead = 30;
    81. var targetSpeed = target.gameObject.GetComponent<Move>().instantVelocity;
    82. Vector3 targetFuturePosition = target.position + (targetSpeed * iterationAhead);
    83. Vector3 direction = transform.position - targetFuturePosition;
    84. direction.y = 0;
    85. transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
    86. if(direction.magnitude < safeDistance){
    87. Vector3 moveVector = direction.normalized * moveSpeed * Time.deltaTime;
    88. transform.position += moveVector;
    89. }
    90. }
    91. }
    92.  
    93.  
     
  11. Seyed_Morteza_Kamaly

    Seyed_Morteza_Kamaly

    Joined:
    Nov 18, 2015
    Posts:
    80
    thanks but this code not work for me!

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Move : MonoBehaviour {
    6.  
    7. public int moveSpeed = 10;
    8. public Vector3 instantVelocity;
    9. void Start () {
    10. instantVelocity = Vector3.zero;
    11. }
    12. void Update () {
    13. Vector3 pos = transform.position;
    14. var horMovement = Input.GetAxis("Horizontal");
    15. var forwardMovement = Input.GetAxis("Vertical");
    16. if (horMovement == 1) {
    17. transform.Translate(transform.right * horMovement * Time.deltaTime * moveSpeed);
    18. }
    19. if (forwardMovement == 1) {
    20. transform.Translate(transform.forward * forwardMovement * Time.deltaTime * moveSpeed);
    21. }
    22. instantVelocity = transform.position - pos;
    23. }
    24. }
    25.  
    Code (CSharp):
    1.  
    2.  
    3.  
    4.  
    5. using System.Collections;
    6. using System.Collections.Generic;
    7. using UnityEngine;
    8.  
    9. public class SteeringBehaviours : MonoBehaviour {
    10.  
    11. public Transform target;
    12. public float moveSpeed = 6.0f;
    13. public float rotationSpeed = 1.0f;
    14. private int minDistance = 5;
    15. private int safeDistance = 60;
    16. public enum AIState {Idle, Seek, Flee, Arrive, Pursuit, Evade}
    17. public AIState currentState;
    18. void Update () {
    19. switch(currentState){
    20. case AIState.Idle:
    21. break;
    22. case AIState.Seek:
    23. Seek();
    24. break;
    25. case AIState.Flee:
    26. Flee();
    27. break;
    28. case AIState.Arrive:
    29. Arrive();
    30. break;
    31. case AIState.Pursuit:
    32. Pursuit();
    33. break;
    34. case AIState.Evade:
    35. Evade();
    36. break;
    37. }
    38. }
    39. void Seek (){
    40. Vector3 direction = target.position - transform.position;
    41. direction.y = 0;
    42. transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
    43. if(direction.magnitude > minDistance){
    44. Vector3 moveVector = direction.normalized * moveSpeed * Time.deltaTime;
    45. transform.position += moveVector;
    46. }
    47. }
    48. void Flee () {
    49. Vector3 direction = transform.position - target.position;
    50. direction.y = 0;
    51. if(direction.magnitude < safeDistance){
    52. transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
    53. Vector3 moveVector = direction.normalized * moveSpeed * Time.deltaTime;
    54. transform.position += moveVector;
    55. }
    56. }
    57. void Arrive (){
    58. Vector3 direction = target.position - transform.position;
    59. direction.y = 0;
    60. float distance = direction.magnitude;
    61. float decelerationFactor = distance / 5;
    62. float speed = moveSpeed * decelerationFactor;
    63. transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
    64. Vector3 moveVector = direction.normalized * Time.deltaTime * speed;
    65. transform.position += moveVector;
    66. }
    67. void Pursuit (){
    68. int iterationAhead = 30;
    69. var targetSpeed = target.gameObject.GetComponent<Move>().instantVelocity;
    70. Vector3 targetFuturePosition = target.transform.position + (targetSpeed * iterationAhead);
    71. Vector3 direction = targetFuturePosition - transform.position;
    72. direction.y = 0;
    73. transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
    74. if(direction.magnitude > minDistance){
    75. Vector3 moveVector = direction.normalized * moveSpeed * Time.deltaTime;
    76. transform.position += moveVector;
    77. }
    78. }
    79. void Evade (){
    80. int iterationAhead = 30;
    81. var targetSpeed = target.gameObject.GetComponent<Move>().instantVelocity;
    82. Vector3 targetFuturePosition = target.position + (targetSpeed * iterationAhead);
    83. Vector3 direction = transform.position - targetFuturePosition;
    84. direction.y = 0;
    85. transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
    86. if(direction.magnitude < safeDistance){
    87. Vector3 moveVector = direction.normalized * moveSpeed * Time.deltaTime;
    88. transform.position += moveVector;
    89. }
    90. }
    91. }
    92.  
    93.