• 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 Tavis · Aug 15, 2012 at 07:10 AM · projectiletrackingfiring

How to make a projectile fire at a moving player.

Hey guys I am extremely new to programming and im having alot of issues with making a projectile fired from a moving boss towards the moving player. What im after is a pathfind solution where the boss fires the projectile where the player is at that point. However in my last build the projectile tracked the player untill it hit him instead of just taking its position when it was fired.

the code we are currently using was written by one of our group members but he is unavailbe to explain it all to me for a few days. I've tried searching other questions, google and the documentation but I dont really understand what hes provided me with.

public class BossProjectileScript : MonoBehaviour {

  public Transform target;
  public int moveSpeed;
  public int rotationSpeed;
  
  private Transform _t;
  
  public float ProjectileSpeed;
  
  private Transform myTransform;
  
  void Awake() 
  {
    myTransform = transform; 
  }
  
  void Start () 
  {
    GameObject go = GameObject.FindGameObjectWithTag("Player");
  
  target = go.transform;
  }
  
  // Update is called once per frame
  void Update () 
  {
    float amtToMove = ProjectileSpeed * Time.deltaTime;
    //transform.Translate(new Vector3 (target.postition) * amtToMove);
    Debug.DrawLine(target.position, myTransform.position, Color.yellow);
    //Look at Target
    myTransform.rotation = Quaternion.Slerp(myTransform.rotation, Quaternion.LookRotation(target.position - myTransform.position), rotationSpeed * Time.deltaTime);
 
  }

}

That code is some parts of the old code we used on the boss. Which still looks at the player and provides a debug line. However this new code on the Projectile seems to do nothing but move it forward.

As i said im pretty new to programming and this is my first question and im trying to give alot of detail so apologies for the wall of text.

Comment
Add comment · Show 4
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 Meltdown · Aug 15, 2012 at 07:41 AM 0
Share

Please edit your post and format your code correctly using the 10101 icon

avatar image herp johnson · Aug 15, 2012 at 08:31 AM 0
Share

so you've tried using lerps and/or the Vector3.$$anonymous$$oveTowards. I'm not quite sure, but you could probably make or instantiate an empty GameObject whose distance away from the player is relative to the distance from the player to the boss. that would include a lot of guessing and checking but that's all I can come up with.

Hopefully this helps, but if it doesn't, I hope a more experienced coder comes along and helps you!

avatar image herp johnson · Aug 15, 2012 at 08:32 AM 0
Share

well, misspelling "target.postition" might be problematic. try to create that empty GO at the time of firing, and make the boss look at it the whole time. also, ins$$anonymous$$d of using transform.translate, use Vector3.moveTowards, or lerp if you want extremely fast movement. Look both of those up for more info on how to use them. And ins$$anonymous$$d of "myTransform.rotation..." use transform.LookAt or a smooth follow script through inspector.

avatar image Tavis · Aug 15, 2012 at 10:35 AM 0
Share

thanks for the suggestion Herp, I had a go at using lerp. Following the scripting reference http://docs.unity3d.com/Documentation/ScriptReference/Vector3.Lerp.html . Here is what I tried, currently it seems to do nothing as when the projectile is instantiated it just remains still.

public class BossProjectileScript : $$anonymous$$onoBehaviour {

 public Transform target;
 public GameObject Player;
 public float shipx;
 public float shipy;
 public float shipz;
 
 public Transform start;
 public Transform end;
 
 
 
 
 void Start () 
 {
     GameObject player = GameObject.FindGameObjectWithTag("Player");
     
     end = player.transform;
     
     GameObject UFOPrefab = GameObject.FindGameObjectWithTag("boss");
     
     start = UFOPrefab.transform;
     
     
      
     
 }
 
 // Update is called once per frame
 void Update () 
 {
     
     transform.position = Vector3.Lerp(start.position,   end.position, Time.time);
 


 }

}

3 Replies

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

Answer by aldonaletto · Aug 15, 2012 at 11:16 AM

Your original script constantly fixes the projectile direction to aim the target - that's why it tracks the player to death. You may reduce the rotationSpeed value, greatly reducing the tracking effect - the projectile will turn to the player slowly, missing the target if it moves fast.
But if you really want to simply fire the projectile in a straight line to the player direction, just aim it at Start and move forward in Update:

public class BossProjectileScript : MonoBehaviour {

  public Transform target;
  public float ProjectileSpeed = 20;
  
  private Transform myTransform;
  
  void Awake() 
  {
    myTransform = transform; 
  }
  
  void Start () 
  {
    GameObject go = GameObject.FindGameObjectWithTag("Player");
    target = go.transform;
    // rotate the projectile to aim the target:
    myTransform.LookAt(target);
  }
  
  // Update is called once per frame
  void Update () 
  {
    // distance moved since last frame:
    float amtToMove = ProjectileSpeed * Time.deltaTime;
    // translate projectile in its forward direction:
    myTransform.Translate(Vector3.forward * amtToMove);
  }

} NOTE: Anyway, none of above is actually a good solution, because Translate screws up the collision detection system: the projectile should be a rigidbody and receive an initial velocity towards the target, and the only code in its script should be the OnCollisionEnter code, to destroy the projectile and apply damage to the target.

Comment
Add comment · Show 4 · 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 Tavis · Aug 15, 2012 at 01:01 PM 0
Share

Hey Aldo thanks for the suggestion. when I use the code you provided the projectile is instantiated and moves, but it moves extremely slowly even when i change ProjectileSpeed to 5000. At the rate at which it is moving at the moment it is hard to tell if they are travelling in the right direction, they do seem to change a little as the player moves around but it isn't much. It seems like this might move the projectile to the spot but in a curve where as i was hoping for more of a straight line to wherever the player was.

How would i go about doing a better solution? How would i go about adding a force in a specific direction to a rigid body? something like

  rigidbody.AddForce(Vector3.forward * 10); 
ins$$anonymous$$d of the current myTransform.Translate?

avatar image aldonaletto · Aug 15, 2012 at 01:51 PM 0
Share

I suspect that some other script is affecting the projectile movement, since with the code above it should fly at the specified projectileSpeed. Usually the bullet is a rigidbody, and you add force or set its velocity right after it's instantiated in the shooting code - like this:

Rigidbody projPrefab; // drag the projectile prefab here float projectileSpeed = 20;

... Rigidbody projectile = Instantiate(projPrefab, ...) as Rigidbody; projectile.velocity = projectile.transform.forward * projectileSpeed; ... If the projectile prefab has Inspector/Rigidbody/Use Gravity unchecked, the projectile will fly in a straight line towards the player position.

avatar image herp johnson · Aug 15, 2012 at 04:05 PM 0
Share

Hey Aldonaletto thanks for telling that transform messes up collision detection, I was wondering why my helicopter moved through land! xD

Tavis, have you tried playing around with the rigidbody's mass and drag? Sometimes that can slow it down.

avatar image Tavis · Aug 15, 2012 at 04:24 PM 0
Share

For some reason i didn't get Aldonaletto's notification until just now. What i did wrong was i was changing the speed in the script, but it wasn't actually changing in the inspector. Just a $$anonymous$$or oversight that stumped me for ages.

The projectiles are working fine now.I put in a Vector3.Distance checker and when the projectile gets too close it stops traveling towards the player and just continues in whatever direction the player was in last( my games a space rail shooter, so its not really following standard physics rules).

Thanks for all your help aldonaletto it really helped me understand a lot of new things.

avatar image
0

Answer by turtsmcgurts · Aug 15, 2012 at 11:27 AM

Without your code being properly formatted (and my laziness :3), I decided to just give you the essence of my method. It's in Javascript and will not work out of the box, you will need to give it an object to work with.

 var projectileSpeed : float = 20;
 var angle = projectile.location - player.location;
 projectile.rigidbody.AddForce(angle * projectileSpeed);

This will push your object toward the player at a specified speed. Note this doesn't take bullet drop or anything fancy like that into account.

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 aldonaletto · Aug 15, 2012 at 11:31 AM 0
Share

Not a good idea: the projectile will backfire and kill the shooter! The angle vector is backwards - you should use:

 var angle = player.position - projectile.position;
avatar image
0

Answer by Dhaiku · Aug 15, 2012 at 11:17 AM

what you do is you make a target for the player transform not for his position then you say to yoyur projectile, go to the place where the player transform is wich is always where the player is

instead of

  target = go.transform;

you should do

  target = go.transform.position;


this stores the current position of the player, and it won't follow him anymore then in your code, you should replace the target .position, with target (because it now has a transform.position in it, and you can't do transform.position.position)

a position is a Vector3, or a x y and z a transform is something every gameobject has, and its position is a small part of it also note that if you use Transform instead of transform, your code could act weird transform with a small t is the transform of the gameobject linked to the script Transform is some kind of type, like int, float, or boolean you cant say int = 5 but you can say var test : int = 5 same with transform

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 aldonaletto · Aug 15, 2012 at 11:34 AM 1
Share

That's ok, but target should be declared as Vector3:

 ...
 public Vector3 target;
 ...

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

12 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

Related Questions

Firing only a single projectile at a time, then adding a second. 2 Answers

How to avoid speed change in bullets while moving? 1 Answer

Projectile Hit Detection with Bullet Drop 1 Answer

Projectile firing at wrong height 1 Answer

Instantiate a projectile on key press "F" key / OnMouseDown! Help!!! 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