- Home /
Firing rigidbody in an arc given the beginning and middle of arc
Here is the updated code, unfortunately when i release my finger from the screen nothing happens :-( any help is appreciated.
#pragma strict
var startpos : Vector3;
var mousePos : Vector3;
function Update () {
for(var touch : Touch in Input.touches)
{
if(touch.phase == TouchPhase.Began)
{
mousePos = touch.position;
}
else if(touch.phase == TouchPhase.Moved)
{
mousePos = touch.position;
}
else if(touch.phase == TouchPhase.Ended)
{
var pos = mousePos;
var startpos = transform.position; // get the initial position
// create a plane at startpos and perpendicular to the camera:
var plane = new Plane(-Vector3.forward, startpos);
// create a ray from the touch point:
var ray: Ray = Camera.main.ScreenPointToRay(pos);
var dist: float;
plane.Raycast(ray, dist); // cast the ray to the plane
var apex: Vector3 = ray.GetPoint(dist); // find the hit point
var delta: Vector3 = apex-startpos; // delta.y = apex height
var g = -Physics.gravity.y; // g is the gravity absolute value
var vel = Vector3.zero; // calculate the velocity needed:
vel.y = Mathf.Sqrt(2.0*g*delta.y); // vertical velocity
vel.x = delta.x/(vel.y/g); // horizontal velocity
rigidbody.velocity = vel; // fire the rigidbody
}
}
}
Answer by aldonaletto · Mar 24, 2012 at 03:52 AM
There's a problem in your code: you're mixing screen coordinates (mousepos) and world space (startpos). You must convert the touch position to the world space: assuming that world Y is the vertical direction, X is horizontal and Z points to the screen, you could create a plane passing through the start object, do a raycast from the touch position and find where it intersects the plane - this is the apex point. Having the startpos and the apex, you can calculate the necessary vertical velocity to reach the apex point. With this velocity, you can find the time needed to reach it, and calculate the horizontal velocity. A piece of cake, no?
In practice, the whole thing would become something like this:
function Update () { if (Input.touchCount>0){ // if any touche... var touch: Touch = Input.touches[0]; // get the first one switch (touch.phase){ case TouchPhase.Began: case TouchPhase.Moved: var mousepos = touch.position; break; case TouchPhase.Ended: Shoot(mousePos); } } }
function Shoot(pos: Vector2){ var startpos = transform.position; // get the initial position // create a plane at startpos and perpendicular to the camera: var plane = new Plane(-Vector.forward, startpos); // create a ray from the touch point: var ray: Ray = Camera.main.ScreenPointToRay(pos); var dist: float; plane.Raycast(ray, dist); // cast the ray to the plane var apex: Vector3 = ray.GetPoint(dist); // find the hit point var delta: Vector3 = apex-startpos; // delta.y = apex height var g = -Physics.gravity.y; // g is the gravity absolute value var vel = Vector3.zero; // calculate the velocity needed: vel.y = Mathf.Sqrt(2.0*g*delta.y); // vertical velocity vel.x = delta.x/(vel.y/g); // horizontal velocity rigidbody.velocity = vel; // fire the rigidbody } NOTE 1: The touch code wasn't tested (I don't have an Android device);
NOTE 2: The vertical velocity is calculated from the energy formula: m.v2/2 = m.g.h, what becomes vel.y = sqrt(2*g*h). Since at the apex the vertical velocity was consumed by the gravity, the time t to reach it is vel.y/g, and the horizontal velocity should be vel.x/t.
Thank you for your quick response. I tested your code and changed it around slightly so that the touch controls worked but, unfortunately, nothing happens :-( I see what you are trying to do but i cannot see where the code is failing. I have edited my answer to show the updated code and hope that you can help me once again.
$$anonymous$$ind Regards, Will
This code worked perfectly in my tests - I only replaced the touch part by a conventional mousePosition equivalent. There was another difference: I attached my script to an empty object that defined the starting position, and moved the rigidbody to it right before setting its velocity. In your case, the script is attached to the rigidbody, what creates a problem: the rigidbody must be resting on the ground or some kind of support when you fire it. Other points to check: I'm supposing that your screen is the XY plane, and Z is the world's and camera's forward direction (that's why the plane uses -Vector3.forward as the normal parameter).
Your answer
![](https://koobas.hobune.stream/wayback/20220613065453im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Using Raycasting to lob a projectile. 2 Answers
one gameobject instantiaton not 100 3 Answers
For some akward reason bullet is moving in the wrong direction 1 Answer
Addforce to RigidBody problem 1 Answer
Firing projectile in curve 1 Answer