- Home /
How to rotate object slowly on only Z axis
So I got this script working so that the object will automatically rotate back to back to whatever the target object's rotation is. However I only want it to rotate back on the Z axis. I couldn't figure this out, any help would be amazing. Thanks, and here is my short script that almost does the job:
var target: Transform; var speed: float;
function Update () {
var step = speed * Time.deltaTime;
transform.rotation = Quaternion.RotateTowards(transform.rotation, target.rotation, step);
transform.position = Vector3.MoveTowards(transform.position, target.position, step);
}
Answer by robertbu · Aug 04, 2013 at 06:23 AM
I know from experience answering rotation questions, that my interpretation of the question is sometimes different that your intent. Here is an implementation of what I think you are asking:
var target: Transform;
var speed: float = 25.0;
function Update () {
var step = speed * Time.deltaTime;
var v3 = target.right - (Vector3.Dot(target.right, transform.forward) * transform.forward);
var q = Quaternion.FromToRotation(transform.right, v3);
transform.rotation = Quaternion.RotateTowards(transform.rotation, q, step);
transform.position = Vector3.MoveTowards(transform.position, target.position, step);
}
It works by taking the transform.right of the target and projecting it on to the XY plane of object containing this script. It then rotates to match its Transform.right vector with the vector projected on to the plane.
Not quite, but thanks. It still rotates back to its original position. So it wont go back to the center, but it will rotate back on the Z axis. So it isn't curved, Sorry for the vague explanation, but here are some pictures to try to demonstrate it:
With these kinds of questions, 90% of the challenge for me is understanding what you want. Neither your comments or your picture are very helpful. Remember you get to play with your game so what it is doing as well as what it should be doing is obvious to you. But to me I have no concept of your game and only your few words to try and make sense of what you want. Drawings help. Videos help. Posting your project on the net to play with can help. Posting a video can help. Posting a package of your project can help. The code will be easy compared to figure out the right behavior.
Thanks for all the help,
Here is a script that I'm using to make the player look around and move, it is an iOS game. The problem is that sometimes when you drag your finger to look around, the camera gets tilted oddly. I actually like this effect, but if possible I would like it to reset not the rotation, just the tilt. If this still doesn't manage to explain what it is I want, I can try to figure out how to package the game. And thanks a ton for the help, most people don't bother helping past a simple response:
I posted the script as an answer to my question.
Answer by 3 · Aug 04, 2013 at 09:01 PM
This is just code that is a response to a comment, it is not an answer, the code wouldn't fit in a comment box.
// Move by tapping on the ground in the scenery or with the joystick in the lower left corner.
// Look around by dragging the screen.
// These controls are a simple version of the navigation controls in Epic's Epic Citadel demo.
// The ground object must be on the layer 8 (I call it Ground layer).
// Attach this script to a character controller game object. That game object must
// also have a child object with the main camera attached to it.
using UnityEngine;
using System.Collections;
[RequireComponent (typeof (CharacterController))]
public class EpicCitadelControl : MonoBehaviour {
public bool kJoystikEnabled = true;
public float kJoystickSpeed = 0.5f;
public bool kInverse = false;
public float kMovementSpeed = 10;
Transform ownTransform;
Transform cameraTransform;
CharacterController characterController;
Camera _camera;
int leftFingerId = -1;
int rightFingerId = -1;
Vector2 leftFingerStartPoint;
Vector2 leftFingerCurrentPoint;
Vector2 rightFingerStartPoint;
Vector2 rightFingerCurrentPoint;
Vector2 rightFingerLastPoint;
bool isRotating;
bool isMovingToTarget = false;
Vector3 targetPoint;
Rect joystickRect;
void MoveFromJoystick()
{
isMovingToTarget = false;
Vector2 offset = leftFingerCurrentPoint - leftFingerStartPoint;
if (offset.magnitude > 10)
offset = offset.normalized * 10;
characterController.SimpleMove(kJoystickSpeed * ownTransform.TransformDirection(new Vector3(offset.x, 0, offset.y)));
}
void MoveToTarget()
{
Vector3 difference = targetPoint - ownTransform.position;
characterController.SimpleMove(difference.normalized * kMovementSpeed);
Vector3 horizontalDifference = new Vector3(difference.x, 0, difference.z);
if (horizontalDifference.magnitude < 0.1f)
isMovingToTarget = false;
}
void SetTarget(Vector2 screenPos)
{
Ray ray = _camera.ScreenPointToRay (new Vector3 (screenPos.x, screenPos.y));
RaycastHit hit;
int layerMask = 1 << 8; // Ground
if (Physics.Raycast(ray, out hit, Mathf.Infinity, layerMask))
{
targetPoint = hit.point;
isMovingToTarget = true;
}
}
void OnTouchBegan(int fingerId, Vector2 pos)
{
if (leftFingerId == -1 && kJoystikEnabled && joystickRect.Contains(pos)) {
leftFingerId = fingerId;
leftFingerStartPoint = leftFingerCurrentPoint = pos;
} else if (rightFingerId == -1) {
rightFingerStartPoint = rightFingerCurrentPoint = rightFingerLastPoint = pos;
rightFingerId = fingerId;
isRotating = false;
}
}
void OnTouchEnded(int fingerId)
{
if (fingerId == leftFingerId)
leftFingerId = -1;
else if (fingerId == rightFingerId)
{
rightFingerId = -1;
if (false == isRotating)
SetTarget(rightFingerStartPoint);
}
}
void OnTouchMoved(int fingerId, Vector2 pos)
{
if (fingerId == leftFingerId)
leftFingerCurrentPoint = pos;
else if (fingerId == rightFingerId)
{
rightFingerCurrentPoint = pos;
if ((pos - rightFingerStartPoint).magnitude > 2)
isRotating = true;
}
}
void Start ()
{
joystickRect = new Rect(Screen.width * 0.02f, Screen.height * 0.02f, Screen.width * 0.2f, Screen.height * 0.2f);
ownTransform = transform;
cameraTransform = Camera.mainCamera.transform;
characterController = GetComponent<CharacterController>();
_camera = Camera.mainCamera;
}
void Update ()
{
if (Application.isEditor)
{
if (Input.GetMouseButtonDown(0))
OnTouchBegan(0, Input.mousePosition);
else if (Input.GetMouseButtonUp(0))
OnTouchEnded(0);
else if (leftFingerId != -1 || rightFingerId != -1)
OnTouchMoved(0, Input.mousePosition);
}
else
{
int count = Input.touchCount;
for (int i = 0; i < count; i++)
{
Touch touch = Input.GetTouch (i);
if (touch.phase == TouchPhase.Began)
OnTouchBegan(touch.fingerId, touch.position);
else if (touch.phase == TouchPhase.Moved)
OnTouchMoved(touch.fingerId, touch.position);
else if (touch.phase == TouchPhase.Canceled || touch.phase == TouchPhase.Ended)
OnTouchEnded(touch.fingerId);
}
}
if (leftFingerId != -1)
MoveFromJoystick();
else if (isMovingToTarget)
MoveToTarget();
if (rightFingerId != -1 && isRotating)
Rotate();
}
void Rotate()
{
Vector3 lastDirectionInGlobal = _camera.ScreenPointToRay(rightFingerLastPoint).direction;
Vector3 currentDirectionInGlobal = _camera.ScreenPointToRay(rightFingerCurrentPoint).direction;
Quaternion rotation = new Quaternion();
rotation.SetFromToRotation(lastDirectionInGlobal, currentDirectionInGlobal);
ownTransform.rotation = ownTransform.rotation * Quaternion.Euler(0, kInverse ? rotation.eulerAngles.y : -rotation.eulerAngles.y, 0);
// and now the rotation in the camera's local space
rotation.SetFromToRotation( cameraTransform.InverseTransformDirection(lastDirectionInGlobal),
cameraTransform.InverseTransformDirection(currentDirectionInGlobal));
cameraTransform.localRotation = Quaternion.Euler(kInverse ? rotation.eulerAngles.x : -rotation.eulerAngles.x, 0, 0) * cameraTransform.localRotation;
rightFingerLastPoint = rightFingerCurrentPoint;
}
}
I thought if I took a look with fresh eyes I could figure this out, but I'm stumped. The problem is that you have two different rotations going on (parent/child), and just reading this code does not allow me to visualize the issue. A couple of things here strike me as potential problems. The first is you are reading eulerAngles directly. They can change representation on you. The second is the InverseTransformDirection(). You are setting the world rotation with vectors converted to local space.
In order for me to help you I think I need to see the behavior...video, Unity package of the project, or web build.
Unfortunately I won't be able to access my computer until Friday. But if your still around I'll upload everything, thanks
Your answer
Follow this Question
Related Questions
Rotate to Original Z Rotation 3 Answers
Rotation with multiple objects 1 Answer
Rotating an object on Z axis while moving 1 Answer
Rotate a moving object 0 Answers