Rotate game object by clicking a button - unity3d

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.

Related

Car rotation help for a mini game project

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));
}

Object X pos is drastically changing after screen shake ends

I'm using the code below to move my player, named balloon, left and right on the x axis by calculating the difference between where you first touched (or clicked) and where you're currently touching, using ScreenToWorldPoint.
void Update()
{
if (gameStarted)
if (Input.GetMouseButtonDown(0))
{
firstTouch = Camera.main.ScreenToWorldPoint(Input.mousePosition);
startPos = balloon.position;
}
if (Input.GetMouseButton(0))
CheckTouchPosition();
}
}
void CheckTouchPosition()
{
Vector2 currentTouch = Camera.main.ScreenToWorldPoint(Input.mousePosition);
float horizontalDif = currentTouch.x - firstTouch.x;
balloon.position = new Vector2(startPos.x + horizontalDif * 1.2f, balloon.position.y);
}
This works normally except after I run into an obstacle and call my trigger shake function, which performs a typical screen shake. After the screen shake ends the player is translated across the X axis, from what I can tell in the inspector roughly doubling its X position.
public class ScreenShake : MonoBehaviour {
Vector3 initialPosition;
float shakeDuration;
public bool shaking;
[SerializeField] float shakeMagnitude = 0.5f;
[SerializeField] float dampingSpeed = 1.0f;
void Update()
{
if (shakeDuration > 0)
{
shaking = true;
transform.localPosition = initialPosition + Random.insideUnitSphere * shakeMagnitude;
shakeDuration -= Time.unscaledDeltaTime * dampingSpeed;
}
else
{
shakeDuration = 0f;
transform.localPosition = initialPosition;
shaking = false;
}
}
public void TriggerShake(float duration, Vector3 position)
{
shakeDuration = duration;
initialPosition = position;
}
}
I can't figure out why the balloon's X is changing after the screen shake, but it doesn't happen if I don't call that function. I think maybe it has to do with ScreenToWorldPoint being messed up because I'm changing the position of the camera?
EDIT: I forgot to add that the weird repositioning of the balloon ONLY occurs if youre currently holding touching the screen (or holding down the mouse button) when the screen shake occurs. Otherwise everything happens normally.

Rotate object to mouse direction

I have this script, that already works
I,m using leanFinger
var c = Camera.main;
var center = rb.position;
var lastPos = _finger.GetWorldPosition(c.transform.position.y, c);
var lastDelta = Vector3.Distance(center, lastPos);
float angle = Mathf.Atan2(lastPos.x, lastPos.z) * Mathf.Rad2Deg;
rb.rotation = Quaternion.Euler(new Vector3(0, angle - initialRotation, 0));
The problem is that my object is rotating in absolute angles, so if it is already rotated, there is a unwanted rotation. I want it to take an initialRotation value, but i don't know how.
Thanks
You can use transform.rotation to access the current rotation of your object: Transform.rotation
You could also use this method for convenience: Transform.LookAt
Simple JS example:
public var target : Transform;
function Update ()
{
transform.LookAt(target);
}

Unity OnMouseDrag too fast drag issue

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?

Orthographic camera zoom with focus on a specific point

I have an orthographic camera and would like to implement a zoom feature to a specific point. I.e., imagine you have a picture and want to zoom to a specific part of the picture.
I know how to zoom in, the problem is to move the camera to a position that has the desired zone in focus.
How can I do so?
The camera's orthographicSize is the number of world space units in the top half of the viewport. If it's 0.5, then a 1 unit cube will exactly fill the viewport (vertically).
So to zoom in on your target region, center your camera on it (by setting (x,y) to the target's center) and set orthographicSize to half the region's height.
Here is an example to center and zoom to the extents of an object. (Zoom with LMB; 'R' to reset.)
public class OrthographicZoom : MonoBehaviour
{
private Vector3 defaultCenter;
private float defaultHeight; // height of orthographic viewport in world units
private void Start()
{
defaultCenter = camera.transform.position;
defaultHeight = 2f*camera.orthographicSize;
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
Collider target = GetTarget();
if(target != null)
OrthoZoom(target.bounds.center, target.bounds.size.y); // Could directly set orthographicSize = bounds.extents.y
}
if (Input.GetKeyDown(KeyCode.R))
OrthoZoom(defaultCenter, defaultHeight);
}
private void OrthoZoom(Vector2 center, float regionHeight)
{
camera.transform.position = new Vector3(center.x, center.y, defaultCenter.z);
camera.orthographicSize = regionHeight/2f;
}
private Collider GetTarget()
{
var hit = new RaycastHit();
Physics.Raycast(camera.ScreenPointToRay(Input.mousePosition), out hit);
return hit.collider;
}
}
hope you find this code example useful, should be a copy / paste.
Note: this script assume it's attached to the camera object, otherwise you should adjust the transform to the camera object reference.
private float lastZoomDistance = float.PositiveInfinity; // remember that this should be reset to infinite on touch end
private float maxZoomOut = 200;
private float maxZoomIn = 50;
private float zoomSpeed = 2;
void Update() {
if (Input.touchCount >= 2) {
Vector2 touch0, touch1;
float distance;
Vector2 pos = new Vector2(transform.position.x, transform.position.y);
touch0 = Input.GetTouch(0).position - pos;
touch1 = Input.GetTouch(1).position - pos;
zoomCenter = (touch0 + touch1) / 2;
distance = Vector2.Distance(touch0, touch1);
if(lastZoomDistance == float.PositiveInfinity) {
lastZoomDistance = distance;
} else {
if(distance > lastZoomDistance && camera.orthographicSize + zoomSpeed <= maxZoomOut) {
this.camera.orthographicSize = this.camera.orthographicSize + zoomSpeed;
// Assuming script is attached to camera - otherwise, change the transform.position to the camera object
transform.position = Vector3.Lerp(transform.position, zoomCenter, Time.deltaTime);
} else if(distance < lastZoomDistance && camera.orthographicSize - zoomSpeed >= maxZoomIn) {
this.camera.orthographicSize = this.camera.orthographicSize - zoomSpeed;
transform.position = Vector3.Lerp(transform.position, zoomCenter, Time.deltaTime);
}
}
lastZoomDistance = distance;
}
}