- Home /
[Solved]Shoot a projectile towards a target location.
I have a projectile that have a target location. At the moment I use
transform.position = Vector3.Lerp (transform.position, _target.transform.FindChild("Champion").transform.FindChild("Heart").transform.position , _projectileSpeed * Time.deltaTime);
and a OnCollisionEnter to determine if the projectile hits an obstacle or the target.
The problem I´m having is that the movement of the projectile gets shaky at the end and sometimes travles around its target (cause of the rigidbody or such?). I´m looking for a better way to shoot the projectile towards the target in a strait line and at the same time look what the projectile hits on the way. The projectile has to be visible for other players etc.
[SOLUTION]
I found that by changing "Is Kinematic" (rigidbody) to true on my projectile and using
void OnTriggerEnter(Collider other)
to be the most effective way to shoot it. I´m still using
transform.position = Vector3.Lerp (transform.position, _target.transform.FindChild("Champion").transform.FindChild("Heart").transform.position , _projectileSpeed * Time.deltaTime);
to send the projetile at it's location, but since I changed "Is Kinematic" it flows freely and doesn´t bump into other objects. And since I use OnTriggerEnter i can check for enemies, obstalces etc and destroy the projectile if needed.
Answer by Garitzar · Apr 11, 2014 at 10:15 AM
[SOLUTION]
I found that by changing "Is Kinematic" (rigidbody) to true on my projectile and using
void OnTriggerEnter(Collider other)
to be the most effective way to shoot it. I´m still using
transform.position = Vector3.Lerp (transform.position, _target.transform.FindChild("Champion").transform.FindChild("Heart").transform.position , _projectileSpeed * Time.deltaTime);
to send the projetile at it's location, but since I changed "Is Kinematic" it flows freely and doesn´t bump into other objects. And since I use OnTriggerEnter i can check for enemies, obstalces etc and destroy the projectile if needed.
Answer by Smileys · Apr 10, 2014 at 06:42 PM
I dont know what you are trying to achieve - but your code lets the projectile follow the target even if it moves (assuming that Champion is a character or enemy).
In genereal a projectile like a bullet will not change its direction after leaving the barrel (only affected by gravity and wind - but i dont think that you need this). Physics are from my experience very bad to track projectile collision because they are often too fast and tiny. Often colliders pass other colliders in between the Physics steps.
My advice would be to look at raycasting. Raycast every update in transform.forward direction to check if theres any collider in front of the projectile then move it forward based on the desired speed (speed * time.deltatime) . If you want to let the projectile follow the player/enemy - just rotate it towards the target every update.
Other physics based tutorials are in the Unity example projects (at least for a rocket type projectile).
If you have played League Of Legneds imagine Caitlyns ultimate which shoots a projectile towards her target like a rocket, it needs to be visible and blockable by other players. Or just an simple autoattack which sends out a bullet. Caitlyn Ultimate
$$anonymous$$y experiance wich Raycasting is that it sends out an ray and on hit it stores information, but the Ray is instant and is not traveling through the world with a speed (5m/s or something)?
Like i said - if you only have big and slow projectiles in your game then download Unitys example projects. If i remember correct they do this by adding force to a rigidbody. Just keep in $$anonymous$$d for later projects that this is not a universal solution for projectiles.
If youre still intrested in the raycast solution you should look closer at the scripting reference. You can limit the raycast distance. Just shoot a ray for example 0.5units in forward direction and check if there is any collider. If not just move the projectile by the amount of units you want it to travel per second (float amountOfUnits = 4 * time.deldatime) in Update. $$anonymous$$eep in $$anonymous$$d that Update is called every frame. This will result in a smooth projectile movement.
I found another solution, updated the question :) but thank you for your help.
Answer by robertbu · Apr 10, 2014 at 06:41 PM
First, Lerp() used this way will give you a eased movement towards the end...not what you want in a projectile. Second, Lerp() transports object from one position to another. The result can be a conflict between collisions and the transport or often the collision is missed entirely. I'm not an expert in this area, but try this:
var pos = Vector3.MoveTowards(transform.position, _target.transform.FindChild("Champion").transform.FindChild("Heart").transform.position , _projectileSpeed * Time.deltaTime);
rigidbody.MovePosition(pos);
A couple of other things. I believe Transform.FindChild() is depreciated. It was replaced by Transform.Find(). And you can use a path in Find(). So I believe you can do:
_target.transform.Find("Champion/Heart");
You might also consider doing this calculation only once when the target is acquired rather than in the Update() loop.
Your code didn´t make it better :( it's shaky all the way now and not only at the end. But thank you for your tips.
If it is 'shakey all the way', either you have other forces/scripts acting on the object, or it may be a vsync issue.
Your comment to @Smileys indicated you found another solution. You should enter this new solution as an answer and then click on the checkmark next to that answer to close this question out.
Your answer
Follow this Question
Related Questions
Gun Fire, sparks on Collision 1 Answer
Bullet Collision in Networking Game. 0 Answers
Filter Collision by tag not working 0 Answers
Why are my bullets acting as being deflected by the camera borders collider? 0 Answers
Top down 2d shooting - XZ rotation 0 Answers