Hi!
I'm writing a pendulum that rotates with user input, and gravity.
I have the gravity part of it working fine.
But when applying the force from user input, it gets stuck at 180. It doesn't rotate a full loop, and I need that.
I believe that is because of gymbal lock, since I'm using `transform.localRotation.z` to manipulate the angles.
The code I have, with gravity working, is this:
function FixedUpdate() {
transform.localRotation += Input.GetAxis("Horizontal") * inputSpeed;
anglePendulum = transform.localRotation.z;
angularAcceleration += (-gravitationalConstant) / radius * (Mathf.Sin(anglePendulum)) * Time.deltaTime;
anglePendulum += angularAcceleration;
transform.localRotation.z = anglePendulum;
transform.localRotation.z *= friction;
}
I have tried using joints, but I'm not very familiar with that, and it's physics is more "real" than I need.
Any help is appreciated. Thanks!
PS:
The pendulum is a child of another object that moves it around the world, and sets it's forward direction.
2 Answers
2
inputSpeed a Vector3 or a Quaternion? I haven't tried to think in detail about your problem, so this might not be the answer you're looking for. But looking at your code I see several problems and/or weird things that might not be intended (and if they aren't, maybe fixing them helps on the path of solving your actual problem :o) )
- t.localRotation is a Quaternion, so t.localRotation.z is not the angle, but just the z component of the rotation axis the Quaternion is referring to. If you are aware that this is a Quaternion, you might want to use t.localRotaion.w, which is the actual angle associated with the Quaternion. Otherwise, if it's the z-Rotation angle you are looking for, you need to use t.localEulerAngles.z instead.
- the trigonometric Mathf functions use Radians, while Unity uses Degrees. So assuming that anglePendulum is a Unity angle, your Sin needs to be calculated as: Mathf.Sin(anglePendulum*Mathf.Deg2Rad).
Hi Guys!
Thanks to Wolfram I made real progress with this.
It's now a working pendulum. I still have to implement friction, and work out a solution for the angular speed/acceleration. Any ideas on that are very welcome!
UPDATE: Implemented friction. Simply by multiplying the acceleration by a fraction. Updated code below:
var anglePendulum : Quaternion;
var radius = 10.0;
var gravitationalConstant = 50.0;
var angularAcceleration = 0.0;
var friction = .99;
var speed = 0.0;
var inputSpeed = 0.3;
function FixedUpdate() {
angularAcceleration += (-gravitationalConstant) / radius * (Mathf.Sin(transform.localEulerAngles.z * Mathf.Deg2Rad)) * Time.deltaTime + Input.GetAxis("Horizontal") * inputSpeed;
transform.localEulerAngles.z += angularAcceleration;
angularAcceleration *= friction;
}
Wolfram, thanks a lot! That's insightful! Please, assume that things are more "tentatives" than intentional. :) This is the furthest I got to getting the gravity working (it actually works, surprisingly). inputSpeed is actually a float. Those are the variables I'm using: var anglePendulum = 0.0; var radius = 10.0; var gravitationalConstant = 25.0; var angularAcceleration = 0.0; var friction = .9; I'll try and adjust the code following your suggestions. The thing is: it's easier to me to think of angles in Degrees, so I get confused when Euler/Quaternion comes up.
– anon30418489Euler angles is just another word for the "normal" angles you see in the Inspector as rotation X/Y/Z. So when using t.localEurelAngles, you can directly access the rotational angles around the three coordiante axis, in degrees. With t.localRotation, you can't.
– WolframWolfram, thanks a lot! That helped! It's now a working pendulum that rotates past 180, with rotational gravity. I'm working on adding friction to it, now.
– anon30418489