x


How do I AddForce in the forward direction of another object?

I am making a ball rolling game, and am working on a decent control system, as it has to be fun to play. I am using an orbit camera to view the scene, but I wanted it to always move forward relative to the camera, so pressing "w" will always make the ball roll in the direction you ware pointing the camera, this is mostly to allow strafing control, so you can point the camera down a hill and use "a" and "d" to avoid obstacles, etc, as well as to turn corners fully, a la Super Monkey Ball et al.

I figured an elegant way to do this would be to create a kind of invisible helper at the point of the ball, which would read the y rotation ONLY from the camera, and update itself to match. The reason for the in between object, and to use y ONLY, is to not try and move INTO the ground if the camera is looking down at the ball from above. After spending, HOOOOUUUURS today trying to get Y rotation ONLY from camera and apply it to Y rotation ONLY on my helper (currently a cube, will be changed to an empty game object, it's just for visual feedback atm), after many, many problems, including rotating half way before unwinding itself like it was tied with elastic, something to do with quaternion angles, I finally have it. The trick was, to use an in between variable to grab the y euler angle from the camera, and put it into the y euler angle of the helper. Here is the script for that:

 var PlayerBall : Transform;
 var PlayerCam : GameObject;
 
 var angles;
 
 var Rotation = 0.0;
 
 
 function Update ()
 {   
     transform.position = PlayerBall.transform.position;
 
     angles = PlayerCam.transform.eulerAngles;
     Rotation = angles.y;
     
     transform.eulerAngles = Vector3(0, Rotation, 0);
 }


After all this I am a little bit drained. All I want to do now, is to now use the z axis of the helper cube as the forward direction for AddForce on the ball, but any combination of ideas seem to conflict, such as quaternions and floats and such. current movement script is below. How do I make it camera relative?

 var MoveSpeed : float = 100;
 
 var Helper : GameObject;
 
 function Update ()
 {
     if(Input.GetKey("w"))
     {
         rigidbody.AddForce (Vector3.forward * MoveSpeed);
     }
     
     if(Input.GetKey("s"))
     {
         rigidbody.AddForce (Vector3.back * MoveSpeed);
     }
     
     if(Input.GetKey("a"))
     {
         rigidbody.AddForce (Vector3.left * MoveSpeed);
     }
     
     if(Input.GetKey("d"))
     {
         rigidbody.AddForce (Vector3.right * MoveSpeed);
     }
 }

And whilst I am here, how would I best limit the speed of a physics object such as this? I am currently rolling on a flat surface, but when I get to my downhill rolling game, it doesn't seem like there is any limit to my top speed, but I wouldn't know how to control it as it is using physics, and not moving a set amount/rate through script. I would like it to SEEM to be increasingly fast, but I still want decent collision detection etc. How do they do it in games such as Super Monkey Ball, or more recently, Rock of Ages? (love that game!)

Thanks in advance for your help!

-WBC

more ▼

asked Mar 21, 2013 at 11:54 PM

Willium_Bob_Cole gravatar image

Willium_Bob_Cole
21 2 4 8

(comments are locked)
10|3000 characters needed characters left

2 answers: sort voted first

I actually managed to figure out a solution last night that met my needs. Basically, I load in the helper object as a variable, then I discovered you can use transform.TransformDirection to find which way is forward in relation to the helper and use that direction for the AddForce function. Code for ball movement below:

 var MoveSpeed : float = 100;
 
 var Helper : GameObject;
 
 function Update ()
 {
     if(Input.GetKey("w"))
     {
         var HelperForward = Helper.transform.TransformDirection (Vector3.forward);
         
         rigidbody.AddForce (HelperForward * MoveSpeed);
     }
     
     if(Input.GetKey("s"))
     {
         var HelperBack = Helper.transform.TransformDirection (Vector3.back);
         
         rigidbody.AddForce (HelperBack * MoveSpeed);
     }
     
     if(Input.GetKey("a"))
     {
         var HelperLeft = Helper.transform.TransformDirection (Vector3.left);
         
         rigidbody.AddForce (HelperLeft * MoveSpeed);
     }
     
     if(Input.GetKey("d"))
     {
         var HelperRight = Helper.transform.TransformDirection (Vector3.right);
         
         rigidbody.AddForce (HelperRight * MoveSpeed);
     }
 }

Combine this with high friction in the physics material, and it barely slides at all, and it has a little bit of bounciness! So far, it is perfect, though it may need tweaking when I actually have a downhill level. Also I will add in a jump, and a couple other mechanics, but as far as a controllable rolling ball goes, you can't ask for much more than this!

more ▼

answered Mar 22, 2013 at 11:20 AM

Willium_Bob_Cole gravatar image

Willium_Bob_Cole
21 2 4 8

@ Willium_Bob_Cole

Thanks! You are the BEST!

Apr 30, 2013 at 10:17 AM michaelmich3
(comments are locked)
10|3000 characters needed characters left

One way to apply force in the direction the camera is facing, is to bring the camera's forward position down to the level of the ball. So you would do something like:

 var v = PlayerCam.transform.forward;
 v.y = transform.position.y;
 rigidbody.Addforce(v3.normalized * MoveSpeed * Time.deltaTime);  

This will apply force using the forward of the camera but on the 'y' plane of the ball. Note this will not instantly make it go in the direction the camera is facing since there is still a current velocity. It just applies force in the direction the camera is facing. If you need it to quickly or instantly change directions, you will need to do some additional work. Note the addtion of Time.deltaTime to the AddForce() call. It will require you to substantially increase your MoveSpeed value (60x most likely).

more ▼

answered Mar 21, 2013 at 11:59 PM

robertbu gravatar image

robertbu
108k 21 38 158

Thanks for your input, I did actually figure out a solution myself, eventually. It is currently awaiting approval but it should appear below soon.

EDIT: or above. It will be the accepted answer as it is the solution I used. I hope it can help other people who also are looking for a simple way to control a ball, that is fun and intuitive!

Mar 22, 2013 at 11:06 AM Willium_Bob_Cole
(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

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

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x3216
x809
x498
x245
x37

asked: Mar 21, 2013 at 11:54 PM

Seen: 3176 times

Last Updated: Apr 30, 2013 at 10:17 AM