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 will998999 · Mar 23, 2012 at 11:04 PM · addforceprojectilecatapult

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
         }
     }
 }
Comment
Add comment
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

1 Reply

· Add your reply
  • Sort: 
avatar image
1

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.

Comment
Add comment · Show 2 · 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 will998999 · Mar 24, 2012 at 12:48 PM 0
Share

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

avatar image aldonaletto · Mar 25, 2012 at 02:34 PM 0
Share

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

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

4 People are following this question.

avatar image avatar image avatar image avatar image

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


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