Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by hellaeon · Jul 25, 2013 at 03:27 AM · c#enemyjumpingenemy aiwaypoints

AI pause and attack a player in c# (script included)

Hi all,

Just need a little help understanding how I should be doing this.

Currently, I have a prototype where I have a set of waypoints in my script for an AI object to move along. At some point when a player object enters a detection radius trigger, it will stop and for the moment - jump up in the air (using the attached rigidbody.)

The enemy object(monster) has its own collider so it can collide with objects in the scene, but it also has a parent game object

=>parent (script attached to here, sphere collider trigger here detects player, so any jumping is applied to this rigidbody)

===> monster (child, pretty much the model)

 using UnityEngine;
 using System.Collections;
 
 public class monster : MonoBehaviour {
 
     public Vector3[] waypoints;
     public float time;
     public float wait_time;
     private float time_till_attack;
     public bool smooth = false;
     
     private float node_radius = 0.5f;
     private float _t = 0;
     private Vector3 start, finish;
     private int index = 0;
     private float wait_timer = 0;
     private bool player_detected = false;
     private float attack_timer = 0;
     
     // Use this for initialization
     void Start () 
     {
         SetTargetPosition();
     }
     
     void Update()
     {
         // if no player detected, visit the waypoints
         if (!player_detected)
         {
             if (waypoints.Length > 1) 
             {
                 if (_t >= 1.0f) 
                 {    
                     // this is just a pause before moving to next waypoint
                     if (wait_timer < wait_time)
                         wait_timer += Time.deltaTime;
                     else
                     {
                         SetTargetPosition();
                         wait_timer = 0;
                     }
                 }
                 
                 float time_ratio = smooth ? Mathf.SmoothStep(0.0f, 1.0f, _t) : _t;
                 transform.position = Vector3.Lerp(start,finish, time_ratio);
                 _t += Time.deltaTime/time; 
                 
             }
         }
         else
         {
             // can this be done as a coroutine? 
             // I had all sorts of trouble trying to have a simple pause before jump
             if (attack_timer < time_till_attack)
                 attack_timer += Time.deltaTime;
             else
             {
                 // after pausing, jump at the player
                 // repeat this until the player is out of detection zone
                 // to continue back on waypoint path
             }
         }
     }
         
     void SetTargetPosition()
     {
         if (index > waypoints.Length - 1) index = 0;
         start = waypoints[index];
         index++;
         if (index > waypoints.Length - 1) index = 0;
         finish = waypoints[index];
         _t = 0;
     }
     
     void OnTriggerEnter(Collider other)
     {
         if (other.tag == "Player")
             player_detected = true;    
     }
     
     void OnTriggerExit(Collider other)
     {
         if (other.tag == "Player")
             player_detected = false;
     }
     
     public void OnDrawGizmos() 
     {
         if(waypoints == null)
             return;
 
         for(int i=0;i< waypoints.Length;i++) {
             Vector3 pos = waypoints[i];
             Gizmos.color = Color.yellow;
             Gizmos.DrawSphere(pos, node_radius);
             if(i>0) {
                 Vector3 prev = waypoints[i-1];
                 Gizmos.DrawLine(prev,pos);
             }
         }
     }
 }
         
 

Again - this is a prototype script! I'll fine tune it once I have the basics down: 1 ai walks along waypoints (done) 2 ai detects player (done) 3 ai stops waypoint movement when player detected (done) 4 ai pauses for a set time (see the comment in code, I could not get the coroutine to work) 5 ai jumps in the air to attempt to knock player (a flying kind of object) 6 repeat from 4 until player leaves detection radius.

ideally the monster will 'jump' in the direction of the player. The jump will always be the same amount on the current level. * with a jump animation, I could just detect when the animation finishes at step 5, but assume I dont have that luxury

Does anyone have any good ideas on how I can do this. It will help me going forward in producing other types on enemy scripts. Also any comments on improving the code (ahem coroutines) would be welcomed.

Cheers

Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image cdrandin · Jul 25, 2013 at 03:31 AM 0
Share

See if this article helps you out http://unitygems.com/basic-ai-character/#Range

avatar image hellaeon · Jul 25, 2013 at 09:50 AM 0
Share

great link, i'll go through it and report back where it helps

Cheers!

avatar image hellaeon · Jul 25, 2013 at 12:50 PM 0
Share

@cdrandin Thanks for the tip, I always forget unity gems, its a great site. In this case the NPC solution was not for my needs, though I did get some possible ideas about implementing more of a state model in my code - it would certainly clean it up (IS_ROTATING, PLAYER_DETECTED etc)

Thank you.

2 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by hellaeon · Jul 25, 2013 at 12:47 PM

Ok, turns out what I wrote in my original post kind of hinted towards an answer. By creating a jump animation, attaching it to the monster (child object), then calling it when I detected a player, all I had to do was check if it was still playing before either repeating a jump or continuing on my waypoint path. This works exactly to my needs. The only thing missing is making the monster jump towards the player, but its ok for now.

EDIT: this is the updated final draft of the source for now. In the end i went with the current rotation solution and brought in a little bit of a state machine.

 using UnityEngine;
 using System.Collections;
  
 public class AIMonster : MonoBehaviour {
  
     public Vector3[] waypoints;
     public float time;
     public float wait_time;
     public float time_till_attack;
     public bool smooth = false;
  
     private float lerp_ratio = 0;
     private Vector3 start, finish;
     private int index = 0;
     private float wait_timer = 0;
     private float attack_timer = 0;
     private Animation anim;
      private enum STATES { WALKING, TURNING, ATTACK };
     private STATES state = STATES.WALKING;      
 
     private float node_radius = 0.5f; // gizmo
 
     // Use this for initialization
     void Awake () 
     {
        anim = transform.GetChild(0).animation;
        SetTargetPosition();
     }
  
     void Update()
     {
         
         if (waypoints.Length == 0)
             return;
         
         switch (state)
         {
         case STATES.WALKING:
             if(!anim.isPlaying)
             {
                 if (lerp_ratio >= 1.0f) 
                 {  
                     // this is just a pause before moving to next waypoint
                     if (wait_timer < wait_time)
                         wait_timer += Time.deltaTime;
                     else
                     {
                            state = STATES.TURNING;
                            SetTargetPosition();
                            wait_timer = 0;
                     }    
                 }
                 
                 float time_ratio = smooth ? Mathf.SmoothStep(0.0f, 1.0f, lerp_ratio) : lerp_ratio;
                 transform.position = Vector3.Lerp(start,finish, time_ratio);
                 lerp_ratio += Time.deltaTime/time; 
             }
             break;
     
         case STATES.TURNING:
             Quaternion finish_rot = Quaternion.LookRotation(finish);
             transform.rotation = Quaternion.Lerp(transform.rotation, finish_rot, lerp_ratio);
             lerp_ratio += Time.deltaTime/time; 
             if (transform.rotation.eulerAngles.y == finish_rot.eulerAngles.y) 
             {
                  lerp_ratio = 0;
                  state = STATES.WALKING;                
             }
             break;
             
         case STATES.ATTACK:
             if (!anim.isPlaying)
             {
                 // pause before jumping
                 if (attack_timer < time_till_attack)
                     attack_timer += Time.deltaTime;
                 else
                 {
                     anim.Play("jump");
                     attack_timer = 0;
                 }
             }
             break;
         }
     }
  
     void SetTargetPosition()
     {
        if (index > waypoints.Length - 1) index = 0;
        start = waypoints[index];
        index++;
        if (index > waypoints.Length - 1) index = 0;
        finish = waypoints[index];
  
        lerp_ratio = 0;
     }
  
     void OnTriggerEnter(Collider other)
     {
        if (other.tag == "Player")
          state = STATES.ATTACK;  
     }
  
     void OnTriggerExit(Collider other)
     {
        if (other.tag == "Player")
          state = STATES.WALKING;
     }
  
     public void OnDrawGizmos() 
     {
         if(waypoints == null)
             return;
  
         for(int i=0;i< waypoints.Length;i++) {
             Vector3 pos = waypoints[i];
             Gizmos.color = Color.yellow;
          Gizmos.DrawSphere(pos, node_radius);
             if(i>0) {
                 Vector3 prev = waypoints[i-1];
                 Gizmos.DrawLine(prev,pos);
             }
         }
     }
 }
         
 
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by FreeTimeDev · Jul 25, 2013 at 04:57 AM

 spin_attacking = true;
 rigidbody.AddForce(Vector3.forward);

Which way is "Forward"? Is your Parent object facing/oriented the same as your model? Hopefully it's this simple.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image hellaeon · Jul 25, 2013 at 08:06 AM 0
Share

Hi FreeTimeDev, that code is just for testing and should not have been left in there to confuse people. Apologies for that, I have edited the original post with a few comments and removed any bogus code to keep the issue more clear...

Thanks

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

16 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Looping Between Waypoints 1 Answer

Enemy keeps moving in one direction. Help pls! 2 Answers

Enemy stopped at first waypoints. 1 Answer

The problem of Enemy scale when he follow the player (script) . How to fix? 0 Answers

How do I get enemies to only chase me in certain areas 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges