- Home /
Scripting in C# + Past 360 degrees
My apologies for not using the correct mathematical terminologies.
I'm trying to exceed rotation of an object past 360 degrees and under 0 degrees. I do not want degrees to resets to 0 and 360 degrees. I would like to use a float value that takes the current rotation and increments degrees past 360 degrees and under 0 degrees. In other words, I do not want the degrees to reset, ever! E.g. degrees could increment plus or minus 1460 degrees or more!
My program is a little complicated. But basically I am rotating a wheel that follows the position of when I click and drag. I want the wheel to stop at a specific rotation. I am doing this by setting a cap: if rotation is less then 360 degrees, set rotation to 360 and stop rotating. But when I drag my mouse past 360 degrees, the cap is broken and the wheel rotates past the break point.
I am thinking of it as a rope. If you twist a rope, there is no such thing as rotation resetting. The rope will rotate until it snaps. I want this kind of rotation; a rotation that does not reset.
How do I do this? What algorithm can I implement to achieve this in C#?
$$anonymous$$ay I ask why? I think you could keep track of your own rotation value, but ultimately the objects will always be constrained to 0..360 on any given axis.
Answer by robinking · Jun 29, 2011 at 09:17 PM
I don't know if I'm understanding your problem correctly. This script should cap the rotation properly, i.e. if myRotation < 0, wheel angle stays at 0, if myRotation is 0-360, wheel rotation is 0-360, and if myRotation >360, wheel angle stays at 360.
Using System;
Using UnityEngine;
public class CappedWheel : MonoBehaviour {
public float myRotation = 0f;
void Update() {
transform.eulerAngles.x = Mathf.Clamp( myRotation, 0f, 360f );
}
}
Or if I've understood it the wrong way round, this script will rotate the wheel ONLY when myRotation is outside 0...360:
Using System;
Using UnityEngine;
public class CappedWheel : MonoBehaviour {
public float myRotation = 0f;
void Update() {
float x = (myRotation < 0f || myRotation > 360f) ? myRotation : 0f;
transform.eulerAngles.x = x;
}
}
The line in Update() is a shorter way of stating:
if (myRotation < 0f || myRotation > 360f) {
transform.eulerAngles.x = myRotation;
}
else
{
transform.eulerAngles.x = 0f;
}
$$anonymous$$odulo would give the same result as simply rotating the x axis using myRotation... It seemed the question was to introduce some kind of capping?
Thank you Robin...This greatly helps; however that was not exactly what I was looking for...
I am having a hard time explaining what I want, but basically, I want to get rid of the capping.
For example. I want to be able to rotate the wheel over 360 degrees. For example: I want to have a rotation of anywhere between 4560 and -450. Not always fixed between 360 and 0. Why? Because if you think about how rotation really works in the real world...if you rotate something rotation does not get reset. It just keeps incrementing...
When I click and drag a position on the wheel, I want the wheel to rotate with the mouse; however, I do not want rotation to be reset back to 0 once rotation hits 360...that way I can set a cap for rotation but NOT set a cap for dragging the mouse. The problem I am having is that by dragging the mouse, the rotation of the wheel is uncapped, once the mouse drags over from 360 to 0. Although my wheels rotation is capped at 360, it is uncapped because it follows my mouse' rotation.
I hope this better explains what i am looking for :)
I see. Well, by definition there is no angle larger than 360˚ - if you input 390˚, the modulo (remainder) mentioned above comes into effect, giving an effective angle of 30˚. So if you state
transform.eulerAngles.x = 390f;
then it's the same as saying
transform.eulerAngles.x = 390f % 360f;
or
transform.eulerAngles.x = 30f;
I'm rereading your description... by your mouse's rotation, I am imagining a graphical representation of a dial, that you drag around by clicking and dragging round and round the graphical wheel. It can go around from -450 to 4560 and then will stop twisting, even if the mouse carries on dragging. Am I right?
I've added a new answer with a new script, hope this is more what you're looking for :)
Answer by robinking · Jun 30, 2011 at 01:06 AM
Okay I think I understand your question better now. Try adding this script to an empty gameobject in an empty scene and running it. Now, imagine a wheel or dial whose centre is the centre of the screen. Click on the wheel and drag it around the centre - clockwise to increase myValue, counter-clockwise to decrease myValue. myValue is capped at -450 and 4560.
using UnityEngine;
using System.Collections;
public class WheelRotation : MonoBehaviour {
public float myValue = 0f; // This is the output value
private float click;
public float factor = 1f;
// Change this to increase or decrease the wheel's effect on myValue
void Update () {
// hub of wheel is in centre of screen
Vector2 hub = new Vector2( Screen.width/2f, Screen.height/2f );
if (Input.GetMouseButton(0)) {
// Get angle from hub to mouse position
// (probably a better way to do this)
Vector2 mousePos = Input.mousePosition;
float mouseAngle = Vector2.Angle(Vector2.up, mousePos - hub);
if (mousePos.x<hub.x) mouseAngle = 360f-mouseAngle;
// If this is the click down, store the starting angle
if (Input.GetMouseButtonDown(0)) {
click = mouseAngle;
}
// How much has angle changed since last frame?
float difference = mouseAngle - click;
// To prevent error when going past zero
if (difference>180f) difference-=360f;
if (difference<-180f) difference+=360f;
// Increment myValue by that difference and clamp it
myValue += difference * factor;
click = mouseAngle;
myValue = Mathf.Clamp(myValue, -450f, 4560f);
}
}
}