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 post has been wikified, any user with enough reputation can edit it.
avatar image
2
Question by TheGamer106 · Mar 18, 2012 at 12:03 PM · aienemyraycastingenemy ai

Enemy AI using raycasting.. **Solved**

HI, I have been looking into all the ways of doing Ai for an enemy character.. What I have decided upon is to use raycasting to position the enemy and let him just randomly wonder about the room, and when he sees you to go into attack mode and chase you. I have a basic attack script working(sort of) but what I want it to do is, if the enemy looses sight of you to go to the last known position he saw you at and go back into Random Wonder mode.

What I have accomplished right now is to have an invisible GO above the enemy which has a smoothLookAt script attached to look directly at the player and cast a ray of 100 length towards the character. If the ray hits the player, he simply follows the player(geting stuck on walls, falling behind, etc.)

for Random Wonder mode, I need the enemy to happily explore the room without getting stuck on any walls.. sort of like those robotic hoovers make their way around your house, but, you get the idea? Anyway, my code I have right now is this:

 //EnemylockOn.js 
 //attatched to the invisible GO above the enemy
 
 var player : Transform;
 var LKplayerPos : Transform;
 
 function Update () 
 {
     var hit : RaycastHit;
     
       if(Physics.Raycast(transform.position,transform.TransformDirection(Vector3.forward) , hit, 50)) 
     {
         if(hit.collider.gameObject.tag == "Player")
         {
             LKplayerPos = player;
             print("Player found");
         }
         else if(hit.collider.tag == "Wall")
         {
             LKplayerPos = null;
             print("Player lost");
         }
     }
     Enemy_ai_v2.player = LKplayerPos;
 }
 
 //EnemyAIv2.js
 //attatched to the enemy its self.
 
 var speed : float = 6.0;
 var rotation : float = 8.0;
 
 private var target : Transform;
 private var myTransform : Transform;
 
 static var player : Transform;
 
 function Start()
 {
     myTransform = transform;
 }
 
 function Update()
 {
     if(player)
     {
         target = player;
         myTransform.rotation = Quaternion.Slerp(myTransform.rotation, 
                 Quaternion.LookRotation(target.position - myTransform.position),
                 rotation * Time.deltaTime);
         
         myTransform.position += myTransform.forward * speed * Time.deltaTime * 2;
     }
 }

I know what I am asking is very tricky, and that's fine, I have been using Unity for over two years now and I do know my way around the program.

Many, many thanks --TG106

UPDATE

this is my code right now, the enemy has basic RW working and a more precise status switching, also a respawn. Any suggestions are very welcome.

 var hits : int;
 var rayRange : float;
 var speed : float = 6.0;
 var rotation : float = 8.0; 
 var fieldOfViewRange : float = 68.0; 
 var minPlayerDetectDistance : float = 4.0;
 
 var status : int = 0;
 private var csp = false;
 private var repos = false;
 
 /////////////////////
 // STATUS KEY:
 // 0 = sleep         
 // 1 = chase           
 // 2 = randomWonder. 
 /////////////////////
 
 var player : Transform;
 var target : Transform;
 private var myTransform : Transform;
 private var spawnPos : Vector3;
 
 private var rayDirection = Vector3.zero;
 
 static var reset = false;
 
 function Start()
 {
     myTransform = transform;
     spawnPos = transform.position;
         
     status = 0;
     
     // Error checks
     
     if(player == null)
         Debug.LogError("Player is not set on " + this.name);
         
     if(target == null)
         Debug.LogError("target is not set on " + this.name);
 }
 
 function Update()
 {
     // Setting local variables 
     
     var hit : RaycastHit;
     var dtt = Vector3.Distance(transform.position, target.position);
     var distanceToPlayer = Vector3.Distance(transform.position, player.position);
     
     rayDirection = player.position - transform.position;
     
     // Failsafe 
     
     if((status != 2) && (Physics.Raycast(transform.position, transform.forward, hit, 2)))
     {
         target.position = transform.position;
     }
     if(transform.position.y <= -20)
     {
         transform.position = spawnPos;
     }
     
     // Catch the player if he is within view 
     
     if((Vector3.Angle(rayDirection, transform.forward)) < fieldOfViewRange)
     { 
         if (Physics.Raycast (transform.position, rayDirection, hit, rayRange)) 
         {
             if ((hit.transform.tag == "Player") && (hit.transform.tag != "Wall"))
             {
                 target.position = player.position;    
                 csp = true;        
             }
             else
             {
                 csp = false;
             }
         }
     }
     
     // Catch the player if he sneaks up behind 
     
     if(Physics.Raycast (transform.position, rayDirection, hit))
     { 
         Debug.DrawRay(transform.position, rayDirection, Color.green);
         
         if((hit.transform.tag != "Player") && (distanceToPlayer <= minPlayerDetectDistance))
         {
             target.position = player.position;
         }
     }
     
     // Status setting 
     
     if(dtt <= 3 && csp)
     {
         status = 0;
     }
     if(dtt > 3 && csp)
     {
         status = 1;
     }
     if(dtt <= 3 && !csp)
     {
         status = 2;
     }
     
     // Status Control
     
     if(csp)
         hits = 0;
     
     switch(status)
     {
         case 0:
             break;
         
         case 1: 
             myTransform.rotation = Quaternion.Slerp(myTransform.rotation, 
                                    Quaternion.LookRotation(target.position - myTransform.position),
                                    rotation * Time.deltaTime);
             
             myTransform.position += myTransform.forward * speed * Time.deltaTime * 2;
             
             break;
             
         case 2:
             RandomWonderMode();
             break;
             
         default:
             Debug.LogError("Unrecognised enemy status " + status);
             break;
     }
     
     if(reset)
     {
         Reset();
     }
 }
 
 function RandomWonderMode()
 {
     var pp = player.positon;
     var mp = transform.position;
     var dtt = Vector3.Distance(transform.position, target.position);
     var hit : RaycastHit;
     
     if(!csp)
     {
         if(dtt > 3)
         {
             myTransform.rotation = Quaternion.Slerp(myTransform.rotation, 
                                    Quaternion.LookRotation(target.position - myTransform.position),
                                    rotation * Time.deltaTime);
                                            
             myTransform.position += myTransform.forward * speed * Time.deltaTime;
         }
         else
         {
             repos = true;
         }
         
         if(Physics.Raycast (transform.position, transform.forward, hit, 2) || repos)
         {
             var pos = Vector3(Random.Range(-50,50), 1, Random.Range(-50,50));
             target.position = pos;
             repos = false;
             hits ++;
         }
         
         if(hits > 100 && !csp)
         {
             hits = 0;
             transform.position = spawnPos;
         }
     }
 }
 
 function Reset()
 {
     transform.position = spawnPos;
     hits = 0;
     status = 2;
     reset = false;
     
     // Error checks
     
     if(player == null)
     {
         Debug.LogError("Player is not set on " + this.name);
     }
     if(target == null)
     {
         Debug.LogError("target is not set on " + this.name);
     }
 }
Comment
Add comment · Show 1
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 pyroantimonic_entity · May 14, 2018 at 11:24 PM 0
Share

I need a C# script

2 Replies

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

Answer by Owen-Reynolds · Mar 18, 2012 at 05:39 PM

Some comments:

o Don't null out lastKnownPlayerPos when you see a wall. The entire point of saving LKPPos is for when you finally see a wall. A common trick is to have a "wanderTarget." When you first lose the player, set wanderTarget to LKplayerPos (and when you reach wanderTarget, set the next one randomly.) You'd need a "player seen last frame" var to check for "I just lost him."

o Probably don't look straight ahead to check if you see the player (unless the player is huge.) A lot of people check the angle (between my forward, and world angle from me to player) and then raycast directly to the player, for visibility.

o You don't need an extra gameObject doing the raycast, if you don't want. Your NPC script can just raycast from EmptyChildWhereMyEyesAre in whatever direction you like.

o transform.TransformDirection(Vector3.forward) has a shortcut: transform.forward that can make programs a little easier to read.

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 TheGamer106 · Mar 18, 2012 at 09:26 PM 0
Share

Hi, those are good points, if you could just give me an example on what I should do to code the first two points? I have fixed the last two..

Thanks --TG106 ps, thanks for the .forward shortcut. Totally forgot about that :P

avatar image Owen-Reynolds · Mar 19, 2012 at 02:29 AM 0
Share

Search here for "AI raycast." Not too many complete solutions, but some with the right idea. http://answers.unity3d.com/questions/15735/field-of-view-using-raycasting.html has "raycast to player" and an angle-check, for example.

avatar image TheGamer106 · Mar 19, 2012 at 10:28 AM 0
Share

Thanks alot man ;) got the AI sorted now. You have been a great help, seriously you have. --TG106

avatar image
0

Answer by davedx · Mar 18, 2012 at 07:37 PM

You probably want to look into some kind of better path finding. The common algorithm used to path between two points on a flat surface is A*. Unity 3.5 comes with a nice easy to use navigation mesh system, check it out here: http://unity3d.com/support/documentation/Manual/Navmesh%20and%20Pathfinding.html

It's for Pro only unfortunately. Otherwise, implementing A* and its subsystems is excellent practise and great experience to have.

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

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

7 People are following this question.

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

Related Questions

Multiple Cars not working 1 Answer

FPS Problem Help! 0 Answers

Different enemy types script design 1 Answer

Enemy gets through wall over time, colliders working. 1 Answer

Enemy keeps moving in one direction. Help pls! 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