Search Unity

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.