- Home /
How to angle projectiles depending on where the mouse is clicked ?
Consider the projectile to be something like a grenade with a parabolic trajectory. Wherever on the horizontal axis that the mouse click happens, the projectile is supposed to be thrown in that angle, and the vertical axis decides the height of the trajectory. The camera angle is locked.
Also, how to make the projectile rotate in the direction of the trajectory ?
Code I'm using to throw the projectile is as below:
public GameObject grenade;
public float throwPower = 100;
void Update (){
if (Input.GetButtonDown("Fire1")) {
GameObject clone;
clone = Instantiate(grenade, transform.position, transform.rotation);
clone.rigidbody.velocity = transform.TransformDirection(Vector3.forward * throwPower);
}
}
though I get an error Unexpected symbol for', expecting
identifier' for the line
clone.rigidbody.velocity = transform.TransformDirection(Vector3.forward * throwPower);
The below is an example of various directions the projectile can be thrown in depending on where the mouse click happens.
Seems like the "easy" way would be having a transform on your shooter object which tries to look at the mouse position in world space. Perhaps at a distant point on the camera's view plane, for instance? Projectiles get launched from that transform's position, and get an impulse in the direction of the transform's "forward". This way gives you some extra play over where the projectile spawns from. If it's launching from the camera's center, you could just as easily use that "camera ray" informed by the mouse as the projectile's initial velocity.
I didn't quite understand what you meant by that. What I basically need to do is somehow create a vector that starts from the middle of the screen and ends where the mouse click happens, and make the projectile continue in that vectors' direction and also rotate that way.
How about a ScreenPointToRay based on the mouse position:
http://docs.unity3d.com/ScriptReference/Camera.ScreenPointToRay.html
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Answer by jabez · Oct 26, 2014 at 01:42 AM
Hello there C:, i would do a raycast then minus the hit point with your position to get the direction i will post a script as an example. Vector3 Dir = (hit.point - transform.position) may have to be Vector3 Dir = transform.position - hit.point) anyways enjoy!
void Update () {
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 100))
Debug.DrawLine(ray.origin, hit.point);
Vector3 Dir = (hit.point - transform.position);
transform.rigidbody.AddForce (Dir * 4);
}
$$anonymous$$y impression was that the original poster didn't necessarily want the point where a mouse ray intersects with the world geometry. If I'm mistaken, this answer is suitable.
@AlwaysSunny - Ah, sorry if I wasn't clear in what I needed. @jabez - I used your code and added some stuff to it. The projectile fires everytime a click happens, but it doesn't do so in the direction of the mouse click. It fires only in the straight direction with the same height. Here is the code as it stands currently.
public GameObject grenade;
public float throwPower = 100;
void Update () {
if (Input.Get$$anonymous$$ouseButtonDown(0)){
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 100))
Debug.DrawLine(ray.origin, hit.point, Color.yellow);
Vector3 Dir = (hit.point - transform.position);
GameObject clone;
clone = Instantiate(grenade, transform.position, transform.rotation) as GameObject;
clone.transform.rigidbody.AddForce (Dir * throwPower);
}
}
Right, right, so the part about parabolic trajectory is where you're stuck, am I correct?
Wanting a rigidbody to be "tossed at a target" rather than "shot in a direction" requires some physics math. Calculating a trajectory is one thing, but what you want is the initial velocity which creates a trajectory which satisfies your start / end point constraints. The problem is, there are an infinite number of initial velocities which might satisfy your requirement. How you will ultimately choose from among them the one that best matches your intention is... confusing. I guess if you limit the scalar of the initial velocity to a fixed magnitude, that could give you a single desired initial velocity vector.
Here are your four basic kinematic equations, one or more of which you'll need to make use of as you solve for your unknown (the initial velocity): http://www.physicsclassroom.com/class/1D$$anonymous$$in/Lesson-6/$$anonymous$$inematic-Equations
If this is just totally daunting and not what you had in $$anonymous$$d, consider whether you absolutely need to pre-deter$$anonymous$$e where your tossed-projectile will land.
EDIT: Okay, I re-read your original question, and now see that you also want the height of the trajectory to be controlled. Sorry for missing that. Unfortunately, this further complicates an already complicated issue. I don't recall whether I've ever solved this particular kind of problem before - doesn't using vertical mouse position to inform the trajectory apex invalidate the whole concept of also using mouse position to pre-deter$$anonymous$$e the end point?
All of the parabolic trajectory is being taken care of by Unitys' physics engine. I'm just not able to get it to fire in the direction where the mouse is clicking. It is firing only in the straight direction, perpendicular to the camera.
Ok, turning on the Box Collider of the object to which the ray was colliding, made the angle of the projectile work. So, now I can click anywhere on the screen and the projectile goes in that direction, along with the elevation as required. Need to get the rotation to work now.
Update: I got the rotation to work somewhat, but it doesn't rotate in the direction of the throw. Here is what I added at the end of the code
clone.transform.rigidbody.AddTorque (Vector3.right * rpm);