I have a mini project where i have a car that drives on a cylinder and is rotating around the cylinder. When i press left mouse click the car rotates to the left and goes to the left and when i press right mouse click it rotates right and it goes right. What i want is when i release the mouse click buttons i want the car to rotate back to face the forward direction of the cylinder and continue going forward along the cylinder i have a script that is working but it is not rotating the car back to forward direction.
//THIS SCRIPT IS ATTACHED TO THE CAR
void Update(){
//CHECKS IF MOUSE BUTTON ARE CLICKED
if (Input.GetMouseButton (0)) {
rotation = -1;
} else if (Input.GetMouseButton (1)) {
rotation = 1;
} else {
rotation = 0;
}
}
void FixedUpdate(){
//moves the car forward
//rgb is the rigidbody of the car
rgb.MovePosition(rgb.position - transform.right * moveSpeed * Time.fixedDeltaTime);
// THE LINES BELOW ROTATE THE CAR TO THE LEFT OR RIGHT
Vector3 yRot = Vector3.up * rotation * rotation_speed * Time.deltaTime;
Quaternion deltaRot = Quaternion.Euler(yRot);
Quaternion targetRot = rgb.rotation * deltaRot;
rgb.MoveRotation(Quaternion.Slerp(rgb.rotation, targetRot, 50f * Time.fixedDeltaTime));
}
This is because you are setting the variable "rotation" to 0.
Vector3 yRot = Vector3.up * rotation * rotation_speed * Time.deltaTime;
Which results to 0 and your object doesn't rotate.
I would recommend you to do something like this in your update method:
if (Input.GetMouseButton (0))
{
rotation = -1;
}
else if (Input.GetMouseButton (1))
{
rotation = 1;
}
else
{
//Now when the rotation is positive,
//the object starts to rotate towards negative, but stops at 0
//Same is true when the rotation is negative
if (rgb.rotation.y > 0)
{
rotation = -1;
}
else if (rgb.rotation.y < 0)
{
rotation = 1;
}
else
{
//This needs to be added here to stop the object from rotating
//when the y rotation is already 0
rotation = 0;
}
}
Now it rotates towards 0 when you don't press anything. Also don't use Time.deltaTime in FixedUpdate.
Edit:
So I noticed that with this method it doesn't quite never return to 0. It gets very close but not close enough. By adding this to FixedUpdate the y rotation gets rounded to 0.
if (Mathf.Abs(targetRot.y) < 0.00001f)
{
targetRot = Quaternion.Euler(new Vector3(targetRot.x, 0, targetRot.z));
}
Related
I have a spaceship and I want to rotate it by pressing right and left arrow keys.
When ship is stable, it successfuly rotates and stops whenever i release the arrow keys.
But while the ship is in motion, it won't stop rotating until it gets back to its original position.
If I release before gets to 180 degrees, it goes back. If I release after 180 degrees, it completes the cycle.
How do I fix this? Here are some of the code blocks involved with this mechanic.
[SerializeField]public float rotationSpeed;
public bool isRotating = false;
public void Rotation()
{
if (Input.GetKey(KeyCode.RightArrow))
{
isRotating = true;
transform.Rotate(0,0,-rotationSpeed * Time.deltaTime,Space.World);
}
else if (Input.GetKey(KeyCode.LeftArrow)){
isRotating = true;
transform.Rotate(0,0,rotationSpeed * Time.deltaTime, Space.World);
}
else {
isRotating = false;
}
}
if ((force != Vector2.zero) && (shiprotatescript.isRotating == false)){
shiprotatescript.Rotation();
Quaternion toRotation = Quaternion.LookRotation(Vector3.forward, force);
transform.rotation = Quaternion.RotateTowards(transform.rotation,toRotation,rotationSpeed * Time.deltaTime);
}
Those two blocks are seperate scripts.
Have any idea? Thanks a lot for helping.
I'm trying to implement a system where my camera will zoom in on the front face of a gameobject and I can then rotate around it with clamping.
I've managed to get it work, though I'm guessing I've done it totally wrong - Basically I'm expecting actualAngle to be NEGATIVE when I pan to the left and POSITIVE when I pan to the right.
It does work for targets that have no rotation but not for targets that do have a rotation as the centred angle is not zero.
Here's my function:
float _prevMousePosX;
void RotateCamera()
{
//Allow min -30 degrees when panning to the left
minXLimit = -50;
//And max 30 degrees when panning to the right
maxXLimit = 50;
//Work out how much the mouse has moved
var mouseX = Input.GetAxis("Mouse X");
Vector3 angle = target.position + target.rotation * transform.position * -1;
var actualAngle = angle.x;
//The angle is very small so times it by 100
actualAngle = actualAngle * 100;
//This angle is not defaulting to zero before any rotation has occurred when the game object has a rotation other than zero - I think I should be taking into account the existing rotation somehow
Debug.Log(actualAngle);
//The rest of this code is working correctly
if ((actualAngle > minXLimit && actualAngle < maxXLimit && isMoving))
{
//No - Allow rotating in either direction horizontally
if(isMoving) transform.RotateAround(target.transform.position, Vector3.up, mouseX * 1);
} else
{
//Yes, it's more than 30 degrees either left or right
//Work out which way wer're trying to drag the mouse and whether we should allow rotation further in that direction
if (mouseX>0 && actualAngle < minXLimit)
{
//Don't allow?
}
else if (mouseX<0 && actualAngle < minXLimit)
{
//Allow rotating back
if (isMoving) transform.RotateAround(target.transform.position, Vector3.up, mouseX * 1);
}
else
{
//Mouse isn't moving
}
if (mouseX>0 && actualAngle > maxXLimit)
{
//Allow rotating back
if (isMoving) transform.RotateAround(target.transform.position, Vector3.up, mouseX * 1);
}
else if(mouseX<0 && actualAngle > maxXLimit)
{
//Don't allow rotating in this direction any further
} else
{
//Mouse isn't moving
}
}
_prevMousePosX = mouseX;
}
Issue resolved.
//Work out how close we are to facing each other
//We can minus 180 because we'll always be facing each other, but just not always directly
var newAngle = Quaternion.Angle(target.rotation, transform.rotation) -180;
//Then we need to work out whether we are to it's left or it's right
float rotateDirection = (((transform.eulerAngles.y - target.eulerAngles.y) + 360f) % 360f) > 180.0f ? 1 : -1;
var actualAngle = newAngle;
//And finally we can negate our degrees if we're to it's left
actualAngle = actualAngle * rotateDirection;
You can then use actualAngle to clamp your rotation as I do above.
Maybe its worth noting that I am using the Fingers asset for touch/mouse.
Okay so I have a turret that has a first person camera, on PC it uses the axis Mouse X/Y as I move the mouse around the camera follows. But I need for Mobile to work with the axis Mouse X/Y to drag the camera using touch.
What I need help with is:
As my fingers drags across the screen to move the camera's rotation not position. The position is modified by the vehicle.
This is the code I use for PC first person, moving the mouse:
x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
Quaternion rotation = Quaternion.Euler(y, x, 0f);
turretHeadToMove.rotation = rotation;
How would I use touch dragging to move the rotation? instead of mouse?
Any help with this? Thank you
Here is the current code for touch
if (Input.touchCount > 0)
{
if (Input.GetTouch(0).phase == TouchPhase.Moved)
{
Touch touch = Input.GetTouch(0);
x += touch.deltaPosition.x * xSpeed * 0.02f;
y -= touch.deltaPosition.y * ySpeed * 0.02f;
Quaternion rotation = Quaternion.Euler(y, x, 0f);
turretHeadToMove.rotation = rotation;
}
}
For touch you could use
Input.GetTouch(0).deltaPosition
Try fiddle with something using this:
float strength = 2;
if (Input.touchCount == 1) {
if (Input.GetTouch(0).phase == TouchPhase.Moved)
{
Vector2 touchDirection = Input.GetTouch(0).deltaPosition;
// Update ur transform.Rotate the way u desire
// Different depending on using 1st person, 3rd person etc.
}
}
I have two sprites and I am rotating them on mouse drag. When I rotate one, another has to rotate also but a bit slower. The issue is when I move first sprite too fast. I guess Unity skips some points where I ask for current rotation of object. Here is the code:
if(objekatKliknut=="Minute"){
mouseClickPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector3 dir = mouseClickPos - transform.position;
angle = Mathf.Atan2(dir.y,dir.x) * Mathf.Rad2Deg;
angle-=90;
if (angle < 0.0f) angle += 360.0f;
angle = Mathf.Round(angle/6.0f)*6.0f;
if(angle==360) angle=0;
hand1.transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
a1=angle;
if(a1!=a2){
float x = Mathf.Abs(a1-a2);
if(a1>a2){
moveRight = false;
if(x==6){
handRot+=addAngle*x/6f;
globeRot-=addGlobeAngle;
}
a2=a1;
}
else if(a1<a2){
moveRight = true;
if(x==6){
handRot-=addAngle*(x/6f);
globeRot+=addGlobeAngle*(x/6f);
}
a2=a1;
}
}
hand.transform.rotation = Quaternion.AngleAxis(handRot, Vector3.forward);
oblaci.transform.rotation = Quaternion.AngleAxis(globeRot, Vector3.forward);
}
hand1 is first object that I am rotating, and hand is the second one that needs to be rotated relative to the first one.
Can someone please help me?
I have an object and 2 GUI texture buttons. I want to rotate the object to the left when I press the left button and to the right while pressing the other one.
Any ideas ?
I have a script that works when I drag my object. I will post the important part:
function Start ()
{
var angles = transform.eulerAngles;
x = angles.y;
// Make the rigid body not change rotation
if (rigidbody)
rigidbody.freezeRotation = true;
}
function LateUpdate ()
{
if (isMouseOverGuiTexture()) return;
if (target && Input.GetMouseButton(0))
{
//0.1 represents the sensitivity of the mouse
x += Input.GetAxis("Mouse X") * xSpeed *0.1; //x rotation
//y -= Input.GetAxis("Mouse Y") * ySpeed *0.1; //y rotation
//y = ClampAngle(y, yMinLimit, yMaxLimit);
var rotation = Quaternion.Euler(y, x, 0);
var position = rotation * Vector3(0.900528, 8.829305, -distance+0.49548)+ target.position;
transform.rotation = rotation;
transform.position = position;
}
}
(Question answered in the comments. See Question with no answers, but issue solved in the comments (or extended in chat) )
The OP wrote:
I solved it by using the following :
var imageLeft: Texture2D; // drag the left button image here
var imageRight: Texture2D; // right button image
var speed: float = 60; // rotate speed in degrees per second
private var rotLeft = false; // object rotates left if true
private var rotRight = false; // object rotates right if true;
function OnGUI()
{
rotLeft = GUI.RepeatButton(Rect(10,10,200,200), imageLeft);
rotRight = GUI.RepeatButton(Rect(230,10,200,200), imageRight);
}
function Update()
{
if (rotLeft) transform.Rotate(0, -speed*Time.deltaTime, 0);
if (rotRight) transform.Rotate(0, speed*Time.deltaTime, 0);
}
I don't know which value Time.deltaTime assumes inside OnGUI - it should be the time since last OnGUI, but I'm not sure. To avoid problems, I placed the real rotation in Update and used two control booleans (rotLeft and rotRight) to communicate with OnGUI.