I am making an object rotate with the rotation angle of the hand. It is working well and I am able to rotate the 3D model object. Unfortunately now I only want the object to rotate in its z-axis. I am trying to use Quaternion.Euler (0, 0, rot.eulerAngles.z);
but does not work and the model rotates in all 3 axes. How do I fix it?
public GameObject targetHand;
[Header ("3D Model")]
public GameObject powerSwitch;
[Header ("Hand to 3D Model")]
public float activationDistance;
private Quaternion currentRot;
private Vector3 startPos;
private bool offsetSet;
void Update () {
if ((IsCloseEnough ())) {
Rotate ();
} else {
offsetSet = false;
}
}
void Rotate () {
SetOffsets ();
Vector3 closestPoint = Vector3.Normalize (targetHand.transform.position - powerSwitch.transform.position);
var rot = Quaternion.FromToRotation (startPos, closestPoint);
rot = Quaternion.Euler (0, 0, rot.eulerAngles.z); //Not working when I do this, why?
powerSwitch.transform.rotation = rot * currentRot;
}
void SetOffsets () {
if (offsetSet)
return;
startPos = Vector3.Normalize (targetHand.transform.position - powerSwitch.transform.position);
currentRot = powerSwitch.transform.rotation;
offsetSet = true;
}
bool IsCloseEnough () {
if (Mathf.Abs (Vector3.Distance (targetHand.transform.position, powerSwitch.transform.position)) < activationDistance)
return true;
return false;
}
CodePudding user response:
You want to clamp the rotation around that axis.
I have a few rotation extension methods like this to help.
public static class MyExtensions // Name it what you like I just use this
{
public static Quaternion ClampRotationAroundZAxis(this Quaternion q)
{
if (!Mathf.Approximately(q.w, 0f))
{
q.x = !Mathf.Approximately(q.x, 0f) ? q.x /= q.w : q.x;
q.y = !Mathf.Approximately(q.y, 0f) ? q.y /= q.w : q.y;
q.z = !Mathf.Approximately(q.z, 0f) ? q.z /= q.w : q.z;
q.w = 1f;
}
q.x = 0f;
q.y = 0f;
return q;
}
}
// To Call it
rotation.ClampRotationAroundZAxis();
Edit
You can get it to match it like this if I have them the correct way round otherwise swap order when setting the dir
Vector3 dir = (powerSwitch.transform.position - targetHand.transform.position).normalized;
Quaternion rot = Quaternion.LookRotation(dir, Vector3.up).ClampRotationAroundZAxis();
powerSwitch.transform.rotation = rot;
CodePudding user response:
Can not believe how simple it is.
To rotate things JUST .z
axies you should keep other axies. Example :
Transform target;
transform.eulerAngles = new Vector3(transform.eulerAngles.x, transform.eulerAngles.y, target.eularAngles.z);
Just using targets z.