- Home /
Basic two-wheeled functionality for Segway-type vehicle
Hello. I'm trying to create a simple GameObject comprising two wheels that move independently. I'm having trouble getting it to behave as expected.
The basic model looks like this:
The end aim is to give (analogue) input using a Wii Balance Board so that the model behaves roughly like a Segway: lean forward to apply torque to both wheels and roll forwards; lean back to apply torque to both wheels and roll backwards; and finally I want leaning to one side to have a dampening effect on the torque applied to that side (so leaning right slows down the wheel on the right if it's moving, and has the effect of turning the vehicle to the right).
As an intermediate goal I'm trying to get the GameObject to behave as described for simple directional key presses. Here is what I've tried so far:
Wheel Colliders*
Created an empty GameObject called 'Segway' that contains two cylinders (Left Wheel and Right Wheel) with Rotation (90,0,0) and Scale (1,0.2,1). Left Wheel is at Position (0,0,-1.5), Right Wheel at Position (0,0,1.5). A third cylinder called 'Axle' is positioned at (0,0,0) with Rotation (90,0,0) and Scale (0.1,1.5,0.1). The parent Segway is a rigid body, but the three child cylinders -- Left Wheel, Right Wheel and Axle -- aren't. (I tried making them all rigid bodies but on testing the scene they repelled each other: Axle dropped to the floor and the wheels rolled off.)
I added two empty GameObjects as children of Segway, called 'L Wheel Collider' and 'R Wheel Collider'. To both of these I added a Wheel Collider component. Here is where I may be doing something wrong. I've sized the empty GameObjects with Wheel Collider components so as to appear to coincide with the wheels in local space when looking at the scene. Here are the Transform values used to achieve this:
L Wheel Collider R Wheel Collider
Pos (0,0,-1.5) Pos (0,0,1.5)
Rot (0,90,0) Rot (0,90,0)
Sca (1,0.5,1) Sca (1,0.5,1)
I left the default values of the Wheel Collider component untouched.
Scripts:
For starters, I just want to check that the up/down key presses make the Segway behave as expected. Here is my SegwayController cs script attached to Segway:
public class SegwayController : MonoBehaviour {
public float speed;
public WheelCollider leftwheel;
public WheelCollider rightwheel;
void FixedUpdate ()
{ float moveHorizontal = Input.GetAxis ("Horizontal");
float moveVertical = Input.GetAxis ("Vertical");
leftwheel.motorTorque = moveVertical*speed;
rightwheel.motorTorque = moveVertical*speed;
}
}
Speed is set in the Unity editor at 250, whilst leftwheel and rightwheel have been linked to L Wheel Collider and R Wheel Collider. Note that I'm not yet doing anything with the left/right key press. It seems like a simple continuous up key press should turn the two wheel colliders and I should see the Segway rolling smoothly away. This doesn't happen. Instead the Segway wobbles for a second as if it's struggling to move, then does nothing.
What am I doing wrong? Am I missing something about how Wheel Colliders work? The next step was going to be to comment out the line that applies torque to R Wheel Collider and see if the Segway turns as expected.
Use rigidbody.AddRelativeTorque() instead of Wheel Colliders*
I tried another approach that avoided Wheel Colliders and applied torque directly to the Segway object at different places using rigidbody functions. So far, the relevant bit of code in my Fixed Update() is:
float moveVertical = Input.GetAxis ("Vertical");
rigidbody.AddRelativeTorque(0.0f,0.0f,moveVertical*200);
This makes the Segway move up and down with up/down key presses as expected -- great! But I don't then know how to go about tweaking this to apply varying amounts of torque to each side of the Segway. If I make Left Wheel and Right Wheel into rigid bodies in order to be able to apply torque to each of them, then the Segway falls apart. So if I can only apply physics forces to the Segway itself but not its children (since it doesn't contain any rigid bodies), it seems I have to apply torque around the Z-axis but not at the centre of Segway to get my intended behaviour. There doesn't seem to be a function for this (AddRelativeTorque() always goes around the origin).
Any help with either of my two approaches here is greatly appreciated. I'm new to Unity so it could be that I haven't yet grasped something very fundamental about how it works.
Thanks.
EDITED: I have now given up on trying to get wheel colliders to work. It must be the wrong sort of compound object for wheel colliders. So now I am focusing exclusively on the second approach.
I've since learnt that I can use fixed joints to connect several child objects with rigidbody components to each other under the same parent object. Now I can get the Segway rolling up and down by applying relativetorque to both wheels directly (since they both now have rigidbody components). Progress! But the fixed joints between the axle and each wheel are too restrictive. I'd like applying torque to the left wheel (around x) to cause that wheel to roll along the ground while the right wheel stays in place but turns (around y) as constrained by the connecting axle. What I currently get however is that applying torque to one wheel causes both to roll forwards since the fixed joint I'm using is too fixed. This is intuitive enough and to be expected, so I at least feel I'm on the right lines now.
Current plan: learn how configurable joints work.
(I've also learnt that cylinders come with capsule colliders as standard (for some reason I don't yet appreciate). I've changed these to mesh colliders so that they take the shape of the wheel. I don't know if this was a good thing to do.)
Your answer
Follow this Question
Related Questions
Making a realistic tire/wheel? 0 Answers
Static and kinetic friction on wheel collider 0 Answers
Setting Wheelcollider BrakeTorque to 0 does not release brake 0 Answers
Wheel is wrong rotation 0 Answers
Making a realistic tire/wheel? 2 Answers