Unity Community


Results 1 to 18 of 18

  1. Posts
    29

    Unity Javascript - Basic AI

    Hiya,

    Sorry to post another question but I require one last scripting assistance!
    I just really need a very basic AI script, as I don't understand AI very well. All the script needs to do is have the enemy object move towards the FPS Controller when in range, and when the enemy is within very close range, deal regular damage every 1 or 2 seconds.

    Any help would be greatly appreciated! I'm not concerned with animations just yet!

    Thanks
    Kira


  2. Location
    Chicagoland, USA
    Posts
    165
    Grab the FPS tutorial from the Resources section here on the site - grab the scripts off the Robot. They do exactly what you are looking for and are in javascript as well.
    ------

    The right answer is usually the one that gets the job Done!


  3. Posts
    29
    Hi, thanks for the reply. I tried looking at the scripts and fashioned something myself as it was getting a bit messy (they're using projectiles and have animations) but it needs work. I can't get rotation to work at the moment though.

    Code:  
    1. var speed = 3.0;
    2. var range = 20.0;
    3. var hitRange = 3.0;
    4. var enemyDamage = 100.0;
    5.  
    6. function Start ()
    7. {
    8.      player = GameObject.FindGameObjectWithTag("1Player");
    9. }
    10.  
    11. function Update()
    12. {
    13.         //move towards player
    14.     var distance = Vector3.Distance( player.transform.position, transform.position);
    15.     if (distance > range)
    16.     {
    17.         return;
    18.     }
    19.    
    20.     else
    21.     {   
    22.     var delta = player.transform.position - transform.position;
    23.     delta.Normalize();
    24.     var moveSpeed = speed * Time.deltaTime;
    25.     transform.position = transform.position + (delta * moveSpeed);
    26.     if (distance < hitRange)
    27.     {
    28.     ("ApplyDamage", enemyDamage, SendMessageOptions.DontRequireReceiver);
    29.     }
    30.     }
    31. }

    Also, I've set it to do the damage within a smaller range. It is, obviously, calling it every update (which is probably very frame). Is there an easy way to reduce the frequency of that check being made whilst keep it regularly updated?


  4. Posts
    29
    Ok so I've made SOME progress with the rotation, but now for some reason when you get within range, he rotates 90 degrees on the x axis so that he's flying head first at me. =S Not sure how to change this. (I'll admit, I just adapted the code from the tutorial). Also, still not sure how to make the damage occur fewer times than once every frame (perhaps down to once every 1.5 seconds while within range?) I've tried WaitForSeconds(1.5); within the damage receiving script but it didn't agree.

    Any advances please? =]

    Ooo yea and here's my code thus far:

    Code:  
    1. var speed = 6.0;
    2. var range = 10.0;
    3. var hitRange = 5.0;
    4. var enemyDamage = 10.0;
    5. var rotationSpeed = 5.0;
    6.  
    7. function Start ()
    8. {
    9.      player = GameObject.FindGameObjectWithTag("1Player");
    10. }
    11.  
    12. function Update()
    13. {
    14.         //move towards player
    15.     var distance = Vector3.Distance( player.transform.position, transform.position);
    16.     if (distance > range)
    17.     {
    18.         return;
    19.     }
    20.    
    21.     else
    22.     {   
    23.     var delta = player.transform.position - transform.position;
    24.     delta.Normalize();
    25.     delta.y = 0;
    26.     var moveSpeed = speed * Time.deltaTime;
    27.     transform.position = transform.position + (delta * moveSpeed);
    28.    
    29.     delta.y = 0;
    30.     rotationSpeed * Time.deltaTime);
    31.     transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0);
    32.    
    33.     if (distance < hitRange)
    34.     {
    35.     ("ApplyDamage", enemyDamage, SendMessageOptions.DontRequireReceiver);
    36.     }
    37.     }
    38. }


  5. Posts
    29
    Sorry to bump but any advances guys?! =]



  6. Posts
    14
    Mathematically, one of the best way to model 1 moving object A searching another moving object B is to do:
    x->x+sign(x'-x)*speed
    y->y+sign(y'-y)*speed
    z->z+sign(z'-z)*speed

    knowing A(x,y,z) and B(x',y',z')

    It is also very fast and elegant. Condition is obvious: speed of A must be higher than B.

    EDIT: sorry, but this is not really AI...


  7. Location
    Colorado, USA
    Posts
    21
    I am going to take a closer look at this code, but let me just say quickly that the conditional return branch is not necessary because there is no code following outside the conditional branches.

    Code:  
    1. function Update()
    2. {
    3.   if ( x > 10)
    4.   {
    5.     return;
    6.   }
    7.   else
    8.   {
    9.     // code
    10.   }
    11.   // no code
    12. }

    can be reduced to

    Code:  
    1. function Update()
    2. {
    3.   if ( x <= 10 )
    4.   {
    5.     // code
    6.   }
    7. }
    Last edited by Mike Stampone; 12-09-2010 at 03:59 PM.


  8. Location
    Colorado, USA
    Posts
    21
    Hopefully this is a bit closer to the code you were wanting. You can add your Start() in as well.

    Code:  
    1. var speed : float=6f;
    2. var range : float=10f;
    3. var hitRange : float=5f;
    4. var enemyDamage : float=10f;
    5. var rotationSpeed : float=5f;
    6. var damageTimer : float=0f;
    7.  
    8. function Update()
    9. {
    10.     //move towards player
    11.     var distance = Vector3.Distance(transform.position, player.transform.position);
    12.     if(distance<=range)
    13.     {   
    14.         var delta = player.transform.position - transform.position;
    15.         delta.Normalize();
    16.         delta.y = 0;
    17.         var moveSpeed = speed * Time.deltaTime;
    18.         transform.position = transform.position + (delta * moveSpeed);
    19.        
    20.         transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(delta),
    21.         rotationSpeed * Time.deltaTime);
    22.         transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0);
    23.    
    24.         damageTimer+=Time.deltaTime;
    25.         if (distance < hitRange && damageTimer>=1.5)
    26.         {
    27.             damageTimer=0f;
    28.             player.SendMessageUpwards
    29.                 ("ApplyDamage", enemyDamage, SendMessageOptions.DontRequireReceiver);
    30.         }
    31.     }
    32. }


  9. Posts
    29
    Hiya,

    Thank you ever so much! The damage timer works a treat now! Unfortunately though, the enemy is still rotating 90 degrees on the x axis so that he's flying head first at you, any ideas? I've tried a few things but I'm not sure if I'm going about it the right way).


  10. Posts
    29
    I've posted my rotation problem on Unity Answers but still no joy! Here's the link if you wish to look at the progress, any help is greatly appreciated!

    Rotation Problem


  11. Posts
    29
    Is there no one with the insight to find the more-than-likely simple problem that I am overlooking?


  12. Location
    Colorado, USA
    Posts
    21
    I will have another look. Is it possible that the MeshRenderer is rotated 90 or -90 on the x axis, but the parent GameObject is not?


  13. Posts
    29
    I am so sorry to all of you trying to help me! I can't believe I overlooked something so simple! Thank you for pointing me in the direction Mike Stampone, it was the fact that I had to rotate my model 270 degrees around the x to get him stood up right in Unity, so when transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0); was called it set it back to 0. Just changed that to transform.eulerAngles = Vector3(270, transform.eulerAngles.y, 0); and it works fine. Again, I sincerely apologise for being so idiotic!

    Thanks again for all of your help, I still learn a lot!
    Kira


  14. Location
    Colorado, USA
    Posts
    21
    Just thought I would add a couple comments, as it made it easier for me to read. You can take them or leave them. Anyway, your "enemy" should not be rotating in the x axis, because you throw away your x and z rotation with :

    transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0);

    One of your GameObjects within the "enemy" must be rotated 90 or -90 in the x axis.

    At the moment, the "enemy" will point it's +z axis toward the "player". I assume this is because forward is Vector3(0,0,1) in Unity.

    Code:  
    1. var speed : float=6f;
    2. var range : float=10f;
    3. var hitRange : float=5f;
    4. var enemyDamage : float=10f;
    5. var rotationSpeed : float=5f;
    6. var damageTimer : float=0f;
    7.  
    8. function Start()
    9. {
    10.     player = GameObject.FindGameObjectWithTag("1Player");
    11. }
    12.  
    13. function Update()
    14. {
    15.     // Move the Player
    16.     var distance = Vector3.Distance(transform.position, player.transform.position);
    17.     if(distance<=range)
    18.     {
    19.     // Translate
    20.         var delta = player.transform.position - transform.position;
    21.         delta.Normalize();
    22.         delta.y = 0;
    23.         var moveSpeed = speed * Time.deltaTime;
    24.         transform.position = transform.position + (delta * moveSpeed);
    25.  
    26.     // Rotate
    27.         transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(delta), rotationSpeed * Time.deltaTime);
    28.     transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0);
    29.  
    30.     // Apply damage every 1.5 seconds
    31.         damageTimer+=Time.deltaTime;
    32.         if (distance < hitRange && damageTimer>=1.5)
    33.         {
    34.             damageTimer=0f;
    35.             player.SendMessageUpwards
    36.             ("ApplyDamage", enemyDamage, SendMessageOptions.DontRequireReceiver);
    37.         }
    38.     }
    39. }


  15. Location
    Colorado, USA
    Posts
    21
    Ah, my bad. You posted while I was posting! Great, I am glad you solved it.


  16. Posts
    29
    Thank you for the help, sorry for making you go through all of that for pretty much nothing! Just a simple mistake made by myself! I really appreciate all of your help, this forum is a great place to go for help.

    EDIT: I was thinking that I would like to add some code to make the zombie stop moving towards you if say the distance is 1.5 so that it doesn't move inside you, but make it continue rotating towards you regardless of the distance. Could this be done with a simple check before the movement code? I think I need to start separating the things in to methods now to make the code cleaner.
    Last edited by KiraHoshi; 12-12-2010 at 05:47 AM.


  17. Posts
    29
    Sorry to post again but I'm quite chuffed with my code right now! It may not be "proper" AI, nor particularly advanced or have extended functionality but it works and does a simple job relatively well. I know that when I was first trying to get this script together, I was desperately looking for ANY starting point to work off of (I hit lucky and found a thread which started me off) and think that this may be helpful to those in a similar situation.

    So here's the code so far, it currently moves towards you (the game object with tag "1player") as well as rotate towards you. When it gets in to a certain range, it starts doing damage in regular time intervals and then when within a portion of that "hit range" it'll stop moving towards you, but will continue to rotate towards you and keeps damaging you.

    Code:  
    1. var speed : float=6f;
    2. var range : float=15f;
    3. var hitRange : float=6f;
    4. var enemyDamage : float=10f;
    5. var rotationSpeed : float=5f;
    6. var damageTimer : float=0f;
    7. var delta : Vector3;
    8. var distance;
    9.  
    10. function Start()
    11. {
    12.     player = GameObject.FindGameObjectWithTag("1Player");
    13. }
    14.  
    15. function Update()
    16. {
    17.     //calculate the enemy's distance from player and do a check to see if we should
    18.         //progress then call the necessary methods
    19.  
    20.     distance = Vector3.Distance(transform.position, player.transform.position);
    21.     if(distance<=range)
    22.     {   
    23.         MoveTowards();
    24.         RotateTowards();
    25.         AttackPlayer();
    26.     }
    27. }
    28.  
    29. function MoveTowards()
    30. {
    31.     delta = player.transform.position - transform.position;
    32.     delta.Normalize();
    33.     delta.y = 0;
    34.     if(distance<=(hitRange/1.5))
    35.     {
    36.         return;
    37.     }
    38.     var moveSpeed = speed * Time.deltaTime;
    39.     transform.position = transform.position + (delta * moveSpeed);
    40. }
    41.  
    42. function RotateTowards()
    43. {
    44.     transform.rotation = Quaternion.RotateTowards (transform.rotation, Quaternion.LookRotation(delta), rotationSpeed);
    45.     transform.rotation = Quaternion.Euler(0, transform.eulerAngles.y, 0);
    46. }
    47.  
    48. function AttackPlayer()
    49. {
    50.     damageTimer+=Time.deltaTime;
    51.     if (distance < hitRange && damageTimer>=1.5)
    52.     {
    53.         damageTimer=0f;
    54.         ("ApplyDamage", enemyDamage, SendMessageOptions.DontRequireReceiver);
    55.     }
    56. }
    Last edited by KiraHoshi; 12-14-2010 at 02:26 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •