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 aceX · Apr 21, 2014 at 05:37 PM · raycastai

Fire projectile, tracing a Raycast, enemy AI, 2D

'Aight, here's the situation:

  • Enemy patrols, depending on direction, speed and whether it's hit a wall or not.

  • If the player walks inside its range, it stops and STARES O_O...

  • It also does some damage and knocks the player back on collision - standard stuff...

What I want it to do: - Instead of STARING at the player ... I want it to trace a raycast, instantiate my laser object and apply force in the direction ( or using the angle ) of the raycast. - Alternatively ... I could make it shorter than the player and make it a dull enemy firing in a straight line ... but that wouldn't be fun now would it.

Here's my script so far with the note that I already have some working enemies and a boss fight, it's just this that I'm having an issue with, I don't want to be spoon fed and would much rather theoretical responses with short examples THANKS!

 public class Enemy1 : MonoBehaviour 
 {
     //Public variables
     public float moveDistance; //Distance the enemy will move on both sides/aka Patrol distance
     public float moveSpeed; //Speed at which the enemy will move
 
     //Private variables
     private bool playerInside; //Used to check if the player is inside
     private float orgPos; //The enemy's original position
     private float useSpeed; //Some more speed variables
     private bool wallInTheWay; //Indicates if a wall has been hit
     private Animator _anim1; //Used for animation, specifically the shooting one
 
     //Some general logic 
     void LateUpdate()
     {
         Debug.DrawRay (transform.position,GameObject.Find ("nyan").transform.position - transform.position , Color.green);
     }
 
     //Setting up CoUpdate() and variables
     private IEnumerator Start()
     {
         //Grab the component so that we can animate stuff
         //_anim1.gameObject.GetComponent<Animator> ();
 
         //Patrol speed and initial position
         useSpeed = -moveSpeed;
         orgPos = this.gameObject.transform.position.x;
 
         //Assign bools to false, avoiding any stupid scenarios
         wallInTheWay = false;
         playerInside = false;
 
         //And finaly start CoUpdate()
         yield return StartCoroutine (CoUpdate ());
     }
 
     //CoUpdate - Update() with the block functionality
     private IEnumerator CoUpdate()
     {
         //Stuff here happens once
 
         //Update
         while (true) 
         {
             //Screem, aim and fire
             if(playerInside)
             {
                 yield return StartCoroutine(ScrAimFire());
             }
             //Or... wait for it... waaaaait for it...
             else if(!playerInside)
             {
                 //If there is no wall in the way patrol in regular intervals 
                 if(!wallInTheWay)
                 {
                     //Based on position, assign direction 
                     if(orgPos - this.transform.position.x > moveDistance)
                         useSpeed = moveSpeed;
                     else if(orgPos - this.transform.position.x < -moveDistance)
                         useSpeed = -moveSpeed;
 
                     //And move...
                     this.transform.Translate (useSpeed * Time.deltaTime, 0, 0);
                 }
                 //If there is a wall there however...
                 else if(wallInTheWay)
                 {
                     //Translate the object accordingly
                     yield return StartCoroutine(WallMovement());
                 }
             }
 
             //Always - to avoid infinit loops and crashes
             yield return null;
         }
     }
 
     //Check if the player is in range
     private void OnTriggerEnter2D(Collider2D plr)
     {
         if (plr.gameObject.tag == "Player") 
             playerInside = true;
     }
 
     //Make sure to disable the trigger if the player is no longer in range
     private void OnTriggerExit2D(Collider2D plr)
     {
         if (plr.gameObject.tag == "Player")
             playerInside = false;
     }
 
     //Various collision checks
     private void OnCollisionEnter2D(Collision2D obj)
     {
         //If it's a player...
         if (obj.gameObject.tag == "Player") 
         {
             //Knockback and stop the player ... kinda messy due to all the component fetching
             if(obj.gameObject.GetComponent<Rigidbody2D>().velocity.x < 0)
             {
                 obj.gameObject.GetComponent<Rigidbody2D>().velocity = new Vector2(0,0);
                 obj.gameObject.GetComponent<Rigidbody2D>().AddForce(new Vector3(2000.0f,0.0f,0.0f));
 
             }
             else if(obj.gameObject.GetComponent<Rigidbody2D>().velocity.x > 0)
             {
                 obj.gameObject.GetComponent<Rigidbody2D>().velocity = new Vector2(0,0);
                 obj.gameObject.GetComponent<Rigidbody2D>().AddForce(new Vector3(-2000.0f,0.0f,0.0f));
             }
             //Also remember to do some damage
             _Player.curHealth -= 50;
         }
 
         //If it's a wall, make sure the rest of the script knows this
         if (obj.gameObject.tag == "Wall") 
             wallInTheWay = true;
 
         if (obj.gameObject.tag == "Lava")
             Destroy (this.gameObject);
     }
 
     //Make sure you know when you're no longer touching the wall
     private void OnCollisionExit2D(Collision2D obj)
     {
         if (obj.gameObject.tag == "Wall")
             wallInTheWay = false;
     }
 
     //Wall Logic - simple
     private IEnumerator WallMovement()
     {
         //This should do for now ... Plan on making it float back up later on
         RaycastHit2D rightWall = Physics2D.Raycast(this.gameObject.transform.position, Vector2.right, 5.0f);
 
         //If you hit a wall on the right
         if (rightWall)
             this.transform.Translate (-moveDistance, 0.0f, 0.0f);
 
         //Otherwise...
         else 
             this.transform.Translate (moveDistance, 0.0f, 0.0f);
 
         //And make sure you dont teleport/run back to the wall
         orgPos = this.transform.position.x;
 
         //ALWAYS!!
         yield return null;
     }
 
     //The actual scream, aim and fire logic
     private IEnumerator ScrAimFire()
     {
         yield return null;
     }
 }
 
Comment
Add comment · Show 2
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 robertbu · Apr 21, 2014 at 06:07 PM 0
Share

I'm a little fuzzy about what you are asking. Typically a class like this one will have a reference to the player. And will initialize it in Start():

 private Transform player;
 
 void Start() {
    player = GameObject.FindWithTag("Player").transform;
 }

Then to apply force, you can do:

 Vector3 dir = player.position - transform.position
 player.rigidbody2D.AddForce(dir * someForce);

You may want to vary the force based on the distance to the player. You can get the distance with 'dir.magnitude' to make the calculation.

avatar image aceX · Apr 21, 2014 at 06:13 PM 0
Share

Ugh ... I'll try making it as simple as possible, sorry for any controversy over my initial explanation. Here goes -

I have an enemy, that's twice taller compared to my player. That enemy has to fire a projectile at the player when the player is in range. But the player can jump ... and move, so firing a projectile in the same direction would make it bad and easy to kill.

I want a ray to be cast at the player, originating from the enemy. Using that ray I want the enemy to fire a better aimed projectile that takes care of jumping and any movement in general, while posing a challenge.

You can see what I mean with the:

Debug.DrawRay (transform.position,GameObject.Find ("nyan").transform.position - transform.position , Color.green);

Line. I basically want the projectile to follow this ray.

EDIT: OR alternatively I just realised, I can assign a variable to equal the player's transform while the player is in range, and fire a projectile in that direction.

EDIT2: Testing something...

1 Reply

· Add your reply
  • Sort: 
avatar image
1

Answer by robertbu · Apr 21, 2014 at 06:25 PM

I'm assuming "nyan" is your player. As with my previous comment, typically you would find it once in Start() rather than call it in the bowels of your code. Assuming the projectile is coming from 'transform.position', then all you need to do is:

 Transform player = GameObject.Find ("nyan").transform;
 Vector3 dir = player.position - transform.position;
 projectile.rigidbody2D.AddForce(dir.normalzied * someForceFactor);

Often a projectile is Instantiated and moved on it forward. So you would have something like:

 Transform player = GameObject.Find ("nyan").transform;
 Vector3 dir = player.position - transform.position;
 Vector3 look = Quaternion.LookRotation(dir);
 GameObject go = Instantiate(projectilePrefab, transform.position, look) as GameObject;
 go.rigidbody2D.AddForce(go.transform.forward * someForceFactor);





 
Comment
Add comment · Show 2 · 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 aceX · Apr 21, 2014 at 06:48 PM 0
Share

Right ... for some reason this is giving me an "object reference not set to an instance of an object" when trying to apply force...

I'm using the exact same thing over in my player script ... (kind of)

 Vector3 direction = playerPos.position - transform.position;
 Rigidbody2D clone;
 clone = Instantiate (laser, this.transform.position, Quaternion.identity) as Rigidbody2D;
 clone.rigidbody2D.AddForce (direction * 5000.0f);

The reason why I'm not using Vector3 look is because "You can't convert a vector3 to a Quaternion" and if I use a quaternion they go all funky so... this should do

AW$$anonymous$$AY! Fixed it ... thanks a bunch (I had the wrong prefab assigned to laser doh!)

PS: I'd upvote you... but since I don't have 15 $$anonymous$$arma it's Unity's policy not to trust me sorry :<

Question answered feel free to close it... lasers look a bit awkward but I'll make them rotate sooner or later (they don't rotate according to the direction they're going in ugh...)

Unfortunately I believe that requires 50 $$anonymous$$arma ... so ugh

avatar image robertbu · Apr 21, 2014 at 07:05 PM 0
Share

I converted my comment to an answer. You can close the question out by clicking on the checkmark next to the answer.

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

20 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 avatar image avatar image avatar image avatar image

Related Questions

WayPoints mixed with Raycast 1 Answer

Have falling object exit from a collider after collision? 2 Answers

AI Evasion help 1 Answer

How can I get a character to patrol and follow terrain? 1 Answer

Jitter on Slerp - Raycast 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