I want to achieve a rotating cube.
The goals are as follows:
Press up and down ,or the left and right keys, the cube will rotate 90 degrees to the Corresponding direction ,
it is not to turn 90 degrees immediately, but like the “Slerp” ,having a gradient effect.
However, with the Slerp implementation , When the rotation is repeated several times, the rotation axis will change, resulting in a wrong direction of rotation.
With “Rotate” plus time,deltaTIme will occur a larger error with the increasing speed.
May I ask who can provide a good way to give C# code to achieve this function?
I have thought for a few days, but I cannot find a perfect solution…
Pleade don’t use plugins.
Can you give me a Demo to achieve this function,please?
Code can also be ok.
The code that I wrote can only achieve a part of function, because after the rotation, the axis will chang, I do not know how to determine the axis of rotation.
I do not want to use dozens of “if” to determine all the cases.
This is one of my code from a while back. Not 100% correct but it’s a good start :
using UnityEngine;
using System.Collections;
public class rot90 : MonoBehaviour {
Quaternion rot = Quaternion.identity, saveRot = Quaternion.identity;
float speed = 100.0f, c = 1.0f, deg = 90.0f;
bool moving = false;
void Update () {
if (Quaternion.Angle (transform.rotation, rot) > c && !moving) {
moving = true;
transform.rotation = Quaternion.RotateTowards (transform.rotation, rot, Time.deltaTime * speed);
}else if(!moving){
transform.rotation = rot;
if (Input.GetKeyDown (KeyCode.UpArrow)) {
saveRot = transform.rotation;
transform.RotateAround (transform.position, Vector3.right, deg);
rot = transform.rotation;
transform.rotation = saveRot;
}
else if (Input.GetKeyDown (KeyCode.DownArrow)) {
saveRot = transform.rotation;
transform.RotateAround (transform.position, Vector3.left, deg);
rot = transform.rotation;
transform.rotation = saveRot;
}
else if (Input.GetKeyDown(KeyCode.LeftArrow)) {
saveRot = transform.rotation;
transform.RotateAround (transform.position, Vector3.up, deg);
rot = transform.rotation;
transform.rotation = saveRot;
}
else if (Input.GetKeyDown (KeyCode.RightArrow)) {
saveRot = transform.rotation;
transform.RotateAround (transform.position, Vector3.down, deg);
rot = transform.rotation;
transform.rotation = saveRot;
}
}
moving = false;
}
}
using UnityEngine;
using System.Collections;
public class RotateControlVBug : MonoBehaviour
{
public float smooth = 10f;
public float xMistake = 50f;
public float yMistake = 100f;
private int upDirection = 1, forwardDirection = 1;
private float nowLeftAngle = 0f, nowForwardAngle = 0f;
public bool isLeft = false, isRight = false;
public bool isUp = false, isDown = false;
private Vector3 sPosition = Vector3.zero, ePosition = Vector3.zero;
void Start()
{
xMistake = Mathf.Abs(xMistake);
yMistake = Mathf.Abs(yMistake);
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
sPosition = Input.mousePosition;
ePosition = sPosition;
}
if (Input.GetMouseButtonUp(0))
ePosition = Input.mousePosition;
if (Input.GetKeyDown(KeyCode.RightArrow) || (ePosition.x - sPosition.x >= xMistake && Mathf.Abs(ePosition.y - sPosition.y) < yMistake))
{
isRight = true;
isLeft = isUp = isDown = !isRight;
if (nowForwardAngle == 180)
upDirection = 1;
else
upDirection = -1;
nowLeftAngle = nowLeftAngle + upDirection * 90f;
if (nowLeftAngle >= 360)
nowLeftAngle -= 360;
else if (nowLeftAngle < 0)
nowLeftAngle += 360;
sPosition = ePosition = Vector3.zero;
}
else if (Input.GetKeyDown(KeyCode.LeftArrow) || (ePosition.x - sPosition.x <= -xMistake && Mathf.Abs(ePosition.y - sPosition.y) < yMistake))
{
isLeft = true;
isRight = isUp = isDown = !isLeft;
if (nowForwardAngle == 180)
upDirection = -1;
else
upDirection = 1;
nowLeftAngle = nowLeftAngle + upDirection * 90f;
if (nowLeftAngle >= 360)
nowLeftAngle -= 360;
else if (nowLeftAngle < 0)
nowLeftAngle += 360;
sPosition = ePosition = Vector3.zero;
}
else if (Input.GetKeyDown(KeyCode.UpArrow) || (ePosition.y - sPosition.y >= xMistake && Mathf.Abs(ePosition.x - sPosition.x) < yMistake))
{
isUp = true;
isLeft = isRight = isDown = !isUp;
forwardDirection = -1;
nowForwardAngle = nowForwardAngle + forwardDirection * 90f;
if (nowForwardAngle >= 360)
nowForwardAngle -= 360;
else if (nowForwardAngle < 0)
nowForwardAngle += 360;
sPosition = ePosition = Vector3.zero;
}
else if (Input.GetKeyDown(KeyCode.DownArrow) || (ePosition.y - sPosition.y <= -xMistake && Mathf.Abs(ePosition.x - sPosition.x) < yMistake))
{
isDown = true;
isLeft = isRight = isUp = !isDown;
forwardDirection = 1;
nowForwardAngle = nowForwardAngle + forwardDirection * 90f;
if (nowForwardAngle >= 360)
nowForwardAngle -= 360;
else if (nowForwardAngle < 0)
nowForwardAngle += 360;
sPosition = ePosition = Vector3.zero;
}
#region Test
if (nowLeftAngle == 270)
{
transform.localRotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0f, nowLeftAngle, -nowForwardAngle), Time.deltaTime * smooth);
}
else if (nowLeftAngle == 90)
{
transform.localRotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0f, nowLeftAngle, nowForwardAngle), Time.deltaTime * smooth);
}
else if (nowLeftAngle == 180)
{
transform.localRotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(-nowForwardAngle, nowLeftAngle, 0f), Time.deltaTime * smooth);
}
else
{
transform.localRotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(nowForwardAngle, nowLeftAngle, 0f), Time.deltaTime * smooth);
}
#endregion
Debug.Log("nowLeftAngle = " + nowLeftAngle + " nowForwardAngle = " + nowForwardAngle);
}
}
This is my error code , Do I meet the Gimble Lock?
@Positive7