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
1
Question by popuppirate · Nov 17, 2014 at 07:26 AM · rigidbodytargettargetingrotate-move

Homing Missile not maintaining forward velocity

Hi guys,

Have been building a homing missile for my project wherein if targeting, the projectile will home in on the target or conversely if aiming will follow the targeting reticule as in Half Life 2.

However, since I don't think (I could be wrong) you can access the rigidbody's velocity vector directly, I'm finding it difficult to tell the projectile to continue in the new moving forward direction when the aim is taken off; it either slows down as it reaches the hitpoint terminus or when aim is taken off flies in the initial direction.

Thanks for your time!

Popuppirate

     public class Blob_Projectile_On_Hit : MonoBehaviour {
         GameObject black_hole;
         public GameObject player;
         public GameObject player_camera;
         public Vector3 hit_location;
         private float speed;
         Quaternion curr_rot;
     
         // Use this for initialization
         void Start () {
         speed = 1f;
     
             Target_Control targetcontrol = player.GetComponent<Target_Control> ();
             Camera_Control cameracontrol = player_camera.GetComponent<Camera_Control> ();
     
             //Cancel Player's movement velocity and set it moving in the direction of the target;
             Vector3 relative_pos=(cameracontrol.hit_location - transform.position);
             rigidbody.velocity=(relative_pos*speed)-player.rigidbody.velocity;
         }
         
         // Update is called once per frame
         void Update () {
                     //Translate towards target position-Ideally don't want this but it gets confused when I tell it to move player.transform.forwards
                     Target_Control targetcontrol = player.GetComponent<Target_Control> ();
                     Camera_Control cameracontrol = player_camera.GetComponent<Camera_Control> ();
                     Vector3 relative_pos=(cameracontrol.hit_location - transform.position);
                     
                     //Look  towards target
                     if (cameracontrol.targeting_on) {
                         Quaternion rotation = Quaternion.LookRotation(relative_pos);
                         curr_rot=rotation;
                         transform.rotation=Quaternion.Slerp (transform.rotation, rotation, Time.deltaTime);
                     } else if (cameracontrol.zoom_on) {
 //follow targeting reticule
                             RaycastHit hit;
                             Ray ray = new Ray (transform.position, player.transform.forward);
                             Physics.Raycast (ray, out hit, Mathf.Infinity);
                             Vector3 hit_point=hit.point;
                             Quaternion rotation = Quaternion.LookRotation(hit_point);
                             curr_rot=rotation;
                             transform.rotation=Quaternion.Slerp (transform.rotation, rotation, Time.deltaTime);
                             
                     } else {
 //Keep going in intended direction
                         transform.rotation=Quaternion.Slerp (transform.rotation, curr_rot, Time.deltaTime);
                         
                     }
     
                 Destroy (this.gameObject, Random.Range (5f, 10f));
             }
     
 
Comment
Add comment · Show 6
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 Immanuel-Scholz · Nov 17, 2014 at 07:46 AM 0
Share

However, since I don't think (I could be wrong) you can access the rigidbody's velocity vector directly

You already do this in your script (just by using "rigidbody.velocity") in line 18. So what is the difficulty?

avatar image meat5000 ♦ · Nov 17, 2014 at 07:14 PM 0
Share

If you are using the resultant vector as a factor of velocity then as you get closer you will slow down. Only store the Unit Vector for direction and multiply this by some factor when using it.

avatar image popuppirate · Nov 17, 2014 at 08:52 PM 0
Share

Hi meat500,

I've since stopped doing that- I'm using transform.forward now. It was a placeholder for my Quaternion rotations, which don't appear to do anything at all!

avatar image meat5000 ♦ · Nov 17, 2014 at 09:00 PM 0
Share

Perform the turning with AddTorgue ins$$anonymous$$d of transform for a rigidbody :)

avatar image popuppirate · Nov 17, 2014 at 09:03 PM 0
Share

Good shout, but unfortunately THAT doesn't work either! Do you reckon it has something to do with the fact the projectile is a sphere? I can't figure it out!

 void Start () {
     speed = 25f;
 
         Target_Control targetcontrol = player.GetComponent<Target_Control> ();
         Camera_Control cameracontrol = player_camera.GetComponent<Camera_Control> ();
 
         rigidbody.velocity = (player.transform.forward) * speed;
 
     }
     
     // Update is called once per frame
     void Update () {
 
         Target_Control targetcontrol = player.GetComponent<Target_Control> ();
         Camera_Control cameracontrol = player_camera.GetComponent<Camera_Control> ();
         hit_location = cameracontrol.hit_location;
         Vector3 relative_pos=(cameracontrol.hit_location - transform.position);
         float angle = Vector3.Angle (transform.forward, relative_pos);
         Vector3 cross_product=Vector3.Cross (transform.forward, relative_pos);
         rigidbody.AddTorque (cross_product*angle*100f);
             
         Destroy (this.gameObject, Random.Range (5f, 10f));
         }
 
     
Show more comments

1 Reply

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

Answer by Baste · Nov 17, 2014 at 10:51 AM

If you want the missile to have a constant forwards speed, you put something along the lines of this somewhere in your script:

 rigidbody.velocity = transform.forward * speed;
 

Then you rotate the missile with Quaternion.Slerp as you're already doing, and you'll get the behavior you're looking for.


About rigidbody.velocity, not directly question related:

To be clear here, you can both read and change the rigidbody's velocity, no problem. What you cannot do is to set the individual coordinates of the velocity. So you can't do this:

 rigidbody.velocity.y = 0f; //no worky in C#

This is simply because the velocity is a private variable with a getter and a setter. This means that you don't actually have access to the Vector, you can just send in a new one, and get out a copy of the old one. So to change just one coordinate, you have to do this:

 Vector3 copy = rigidbody.velocity;
 copy.y = 0f;
 rigidbody.velocity = copy;

This is, by the way, why I prefer actual getter and setter methods over the C# get/set paradigm - there's no way to tell from looking at the code if you're accessing a variable or actually calling a method.

Comment
Add comment · Show 5 · 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 popuppirate · Nov 17, 2014 at 02:14 PM 0
Share

Excellent and informative answer, sir!

avatar image popuppirate · Nov 17, 2014 at 07:09 PM 0
Share

Spoke too soon- the object now travels forward and only forward. Here is my code:

     void Start () {
     speed = 10f;
 
         Target_Control targetcontrol = player.GetComponent<Target_Control> ();
         Camera_Control cameracontrol = player_camera.GetComponent<Camera_Control> ();
 
 
         Vector3 relative_pos=(cameracontrol.hit_location - transform.position);
         rigidbody.velocity = (player.transform.forward) * speed;
     }
     
     // Update is called once per frame
     void Update () {
                 Target_Control targetcontrol = player.GetComponent<Target_Control> ();
                 Camera_Control cameracontrol = player_camera.GetComponent<Camera_Control> ();
                 hit_location = cameracontrol.hit_location;
                 Vector3 relative_pos=(cameracontrol.hit_location - transform.position);
 
                     Quaternion rotation = Quaternion.LookRotation(relative_pos);
                     transform.rotation=Quaternion.Slerp (transform.rotation, rotation, 100*Time.deltaTime);
             
 
                     Destroy (this.gameObject, Random.Range (5f, 10f));
         }
 
     
 
 void OnCollisionStay(Collision collisioninfo){
         foreach (ContactPoint contact in collisioninfo) {
             if (contact.point!=null && contact.otherCollider.gameObject!=player){
                 Destroy(this.transform.gameObject,0);
                 black_hole = Object.Instantiate (Resources.Load ("Black_Hole"),contact.point, new Quaternion (0, 0, 0, 0)) as GameObject;
                 }    
             }
         }
     
     }
avatar image Baste · Nov 17, 2014 at 10:34 PM 1
Share

Hmm. So, first of all, the Destroy in Update should be in Start, not update. You're queuing a new Destroy in 5-10 every frame, with the result that it's pretty much guaranteed to be destroyed just after 5 seconds.

Second of all, you have to reset the velocity on every frame. Now you're setting it straight ahead in Start, and then never resetting it, meaning that you rocket will fly in a straight line.

So move this line to start:

  Destroy (this.gameObject, Random.Range (5f, 10f));

and add this line to Update:

 rigidbody.velocity = transform.forward * speed;

Be sure to set the velocity after you set the rotation.

avatar image popuppirate · Nov 18, 2014 at 01:55 PM 0
Share

Good shout- I wasn't really thinking when I put this script together so that does make a lot of sense-will tell you if it's working later on!

avatar image popuppirate · Nov 18, 2014 at 06:26 PM 0
Share

It worked-thanks Baste! After a few tweaks here and there, here's what I've got:

 void Start () {
     speed = 10f;
     Destroy (this.gameObject, Random.Range (5f, 10f));
     }
     
     // Update is called once per frame
     void Update () {
 
                 Target_Control targetcontrol = player.GetComponent<Target_Control> ();
                 Camera_Control cameracontrol = player_camera.GetComponent<Camera_Control> ();
                 hit_location = cameracontrol.hit_location;
             //    Ray ray =new Ray(firepoint.transform.position, player.transform.forward);
             //    Debug.DrawRay (firepoint.transform.position, player.transform.forward, Color.black);
 
                 if (cameracontrol.targeting_on||cameracontrol.zoom_on) {
                         GameObject target = targetcontrol.local_target;
                         Vector3 relative_pos = (cameracontrol.hit_location - transform.position);
                         Quaternion rotation = Quaternion.LookRotation (relative_pos);
                         rigidbody.$$anonymous$$oveRotation (Quaternion.RotateTowards (transform.rotation, rotation, 5f));
                         Debug.Log (transform.rotation);
                         
                 }
                 rigidbody.velocity = transform.forward * speed;
                 
         }
 
 

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

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

Related Questions

Track objects in camera view using GUI? Like a HUD for flight sim lockon targeting. 1 Answer

Targeting an enemy trouble 1 Answer

Choose a Random Tag 1 Answer

Rocket launcher script help 1 Answer

Circle strafing/Z-Targeting 1 Answer


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