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 /
This question was closed May 25, 2012 at 11:08 PM by You! for the following reason:

No longer a problem

avatar image
0
Question by You! · Mar 24, 2012 at 05:12 AM · javascriptaienemybeginnerthird-person

Enemy AI Problem: Dancing?

Edit: The actual movement of the enemy has now been fixed with this script update. Now, the buggy, dance-like rotation needs to be fixed. Suggestions?

I have created an "AI" script for a third person game that is somewhat functional, but is buggy. I want the enemy to rotate to "look" at the player, go up to the player when the player has come within a certain distance, and attack the player at a certain distance. The enemy rotates properly at a distance, but moves crazily when closer. The movement is like a quick, erotic, jumpy dance that circles the player... It looks cool, but it isn't what I want.

Here is the AI script:

 //    #pragma strict
 
 // Set variables related to movement and individual states.
 
 var idleTime : float = 3.1;
 var marManMoveSpeed : float;
 var marManRotateSpeed : float;
 var gravity : float;
 var attackTarget : Transform;
 var chaseDistance : float;
 var attackDistance : float;
 private var moveDirection : Vector3 = Vector3.zero;
 private var wait : boolean = false;
 
 // Set variables for the states.
 private var idle : int = 0;
 private var walk : int = 1;
 private var attack : int = 2;
 private var status : int = idle;
 var controller : CharacterController;
 controller = GetComponent(CharacterController);
 
 
 function Update(){
     var controller : CharacterController = GetComponent(CharacterController);
     moveDirection.x = 0;
     moveDirection.z = 0;

     var aggro : float = Vector3.Distance(attackTarget.position,transform.position);    
     //print(aggro);    
     //Define what causes the states.
 
     if (aggro < chaseDistance && aggro > attackDistance){
         status = walk;
     }
 
     else if(aggro < attackDistance * 0.8){
         status = attack;
     }
 
     else if(aggro > chaseDistance){
 
         status = idle;
 
     }    
     
     
     
     //State what to do in each of the states.    
     if (controller.isGrounded){
         switch(status){
             case idle:
                 //Currently does nothing, but will hopefully have animation here.
                 break;
 
             case walk:
                 //Insert animation later.
                 //Rotation handled later in script.                
                 //Set the direction for movement.
                 moveDirection = Vector3(attackTarget.position.x - transform.position.x,0,attackTarget.position.z - transform.position.z);
                             moveDirection.Normalize();
                 break;
             case attack:
                 //Insert "attack" animation later. Required for end use.
                 //Rotation handled later in script.
                 break;
 
             default:
                 return;
         }
 
     }

     //Always apply gravity.    
     moveDirection[1] -= gravity * Time.deltaTime;
     
     Move();
 }
 
 
     function Move(){
         if(!wait){
             //Handle all movement in here.
             transform.LookAt(attackTarget);
             controller.Move(moveDirection * marManMoveSpeed * Time.deltaTime);
     }
 
     else{
     //Wait for assigned time and do nothing!
     Debug.LogWarning("Current status - waiting for "+idleTime);
         yield WaitForSeconds(idleTime);
         return;
         }
     }
     @script RequireComponent(CharacterController)

Here are the settings for this script in the inspector:

 Idle Time = 3.1
 Mar Man Move Speed = 5.291004
 Mar Man Rotate Speed = 360
 Gravity = 50
 Attack Target = Player (Transform)
 Chase Distance = 5
 Attack Distance = 1.75
 Controller = Enemy (Character Controller)
Comment
Add comment · Show 5
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 AlucardJay · Mar 24, 2012 at 05:32 AM 0
Share

is it possible that the player's Y is lower than the Enemy's Y ? This is just a guess / speculation.

other Qn on the topic : http://answers.unity3d.com/questions/54973/rotate-an-object-to-look-at-another-object-on-one.html

also forgot to suggest that you put your inspector variables in the script :

 var idleTime : float = 3.1;
 var mar$$anonymous$$an$$anonymous$$oveSpeed : float = 5.3;
 var mar$$anonymous$$anRotateSpeed : float = 3.4;
 var gravity : float = 50.0;
 var attackTarget : Transform;
 var chaseDistance : float = 5.0;
 var attackDistance : float = 0.25;

you can still change them in the inspector, it just saves putting them in if you put this script on a new gameObject,

avatar image You! · Mar 24, 2012 at 05:38 AM 0
Share

The player's Y is lower than the Enemy's Y!

Thanks for the tip!

avatar image AlucardJay · Mar 24, 2012 at 05:41 AM 0
Share

was just looking and you saw this. Check out the answer on this Qn for rotating in the Y only for look at :

http://unity3d.qatohost.com/questions/127705/ai-controller.html;jsessionid=A8B8D493F41B3C150276A5D71D688BDF#comment-127711

maybe can replace your transform.LookAt(attackTarget); with everything in their Update function (but use your attackTarget ins$$anonymous$$d of their targetPosition )

 var targetPoint = attackTarget.position;
 var targetRotation = Quaternion.LookRotation(targetPoint - transform.position, Vector.up);
 transform.position.y = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime*2.0).y;
avatar image You! · Mar 24, 2012 at 05:51 AM 0
Share

Replaced the current "transform.LookAt(attackTarget)" with "transform.Rotate(0,attackTarget.position.y * mar$$anonymous$$anRotateSpeed,0,Space.World);"

Same thing happens, but only faster... Now he's breakdancing!

Edit: Also tried Quaternion functions with the following var targetRotation = Quaternion.LookRotation(attackTarget.position - transform.position, Vector3.up);

transform.rotation.y = Quaternion.Slerp(transform.rotation, targetRotation, mar$$anonymous$$anRotateSpeed * Time.deltaTime).y;

This came from the unity3d.quatohost.com site. I copied the code and changed a few variables to fit my case. No change in reaction from the enemy.

I must be doing something else wrong, too... Ideas?

avatar image You! · Mar 24, 2012 at 08:00 AM 0
Share

attempted to limit movement toward the player to the x and z axes by replacing this:

 moveDirection = attackTarget.position - transform.position;
          break;

with this:

moveDirection += Vector3(attackTarget.position.x - transform.position.x,0,attackTarget.position.z - transform.position.z)

The sparatic movement of the enemy has decreased greatly, but still is spinning. $$anonymous$$ovement has been greatly improved, but is still somewhat variable because of spinning.

1 Reply

  • Sort: 
avatar image
1

Answer by Owen-Reynolds · Mar 24, 2012 at 02:01 PM

Your enemy is still moving when it gets within attack range. Sure, you only set moveDirection when you're walking, but you call Move() every frame. So, when you're close, you use the old value of moveDirection, which skitters you a little off to one side.

I'd prefer to split into Move and Turn. Or you could have attack zero-out moveDirection x and z.

attackDistance seems pretty small. The measurement is center-to-center, and 0.25 is 10 inches (25 centimeters.) Two standard Unity cubes (for example) are touching when they are 1 unit apart. But if you really are scaled that small (radius 0.08 colliders,) then 0.25 for attackDistance is fine.

When you compute moveDirection you should probably normalize it. Right now, your speed is based on distance -- you move faster the further you are away. If you raised chase distance to 15, you'd see the enemy blast towards you at triple speed, then slow down.

Another trick is to walk until you are at maybe 80% of attack range, but don't go from attack back to walk until you're out of range. That way the player can shift a little and you won't make unrealistic tiny steps to keep up.

Comment
Add comment · Show 3 · 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 You! · Mar 24, 2012 at 07:15 PM 0
Share

I took some of your suggestions and tested them. I had the x and z values of moveDirection set to zero at the beginning of Update() and normalized moveDirection at the end of Update(). I also changed some of the causes of state change, as suggested. None of these actually fixed the rotation, though, and the enemy now falls more slowly to the ground... I changed the script to reflect these changes. Any suggestions?

avatar image Owen-Reynolds · Mar 25, 2012 at 02:17 AM 1
Share

Sorry for the confusion -- the comment about 80% distance isn't to fix this problem. It's to fix the next problem you might get once you fix this one.

Normalizing is for just after computing the distance (X $$anonymous$$us X, Z $$anonymous$$us Z.) It turns the line between you two into a standard-sized arrow pointing that way, which you can use to move. Also, normalizing readjusts Y, so add gravity later.

The code should be stopping when it gets near you. Try printing the state. Is it always walk? If so, keep jacking up attackDistance.

avatar image You! · Mar 25, 2012 at 02:40 AM 0
Share

Fixed and updated the code. It works fairly great...except for the rotating.

Follow this Question

Answers Answers and Comments

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

How to make AI look like swat team members? 3 Answers

AI controller script, Enemy movement issues 0 Answers

Problem with the movement of AI 1 Answer

Rotating on X and Z axis only 2 Answers

Checking name from hit from Raycast in array 2 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