[英]Unity - Apply two local rotations to object (trying to recreate the rotation of a controller joystick into a 3D mesh joystick)
I would like to recreate one on one the rotation of the real life controller joystick (ie 360 controller) into a 3D joystick mesh (that resembles the 360 controller one).我想将现实生活中 controller 操纵杆(即 360 控制器)的旋转一对一地重新创建为 3D 操纵杆网格(类似于 360 Z594C103F2C6E04C0CAZAB059F031)。
I thought about doing it by rotating the joystick in the X axis according to the magnitude of the input (mapping it to a min and max rotation in the X axis).我考虑通过根据输入的大小在 X 轴上旋转操纵杆来做到这一点(将其映射到 X 轴上的最小和最大旋转)。 And then figure the angle of the input and apply it to the Y axis of the 3D joystick.然后计算输入的角度并将其应用于 3D 操纵杆的 Y 轴。
This is the code I have, the joystick tilts properly in the X axis but the rotation in the Y axis doesn't work:这是我的代码,操纵杆在 X 轴上正确倾斜,但在 Y 轴上的旋转不起作用:
public void SetStickRotation(Vector2 stickInput)
{
float magnitude = stickInput.magnitude;
// This function converts the magnitude to a range between the min and max rotation I want to apply to the 3D stick in the X axis
float rotationX = Utils.ConvertRange(0.0f, 1.0f, m_StickRotationMinX, m_StickRotationMaxX, magnitude);
float angle = Mathf.Atan2(stickInput.x, stickInput.y);
// I try to apply both rotations to the 3D model
m_Stick.localEulerAngles = new Vector3(rotationX, angle, 0.0f);
}
I am not sure why is not working or even if I am doing it the right way (ie perhaps there is a more optimal way to achieve it).我不确定为什么不工作,或者即使我以正确的方式做(即也许有更优化的方法来实现它)。
Many thanks for your input.非常感谢您的意见。
I would recommend rotating it by an amount determined by the magnitude around a single axis determined by the direction.我建议将其旋转一定量,该量由围绕由方向确定的单个轴的大小确定。 This will avoid the joystick spinning around, which would be especially noticeable in cases of asymmetric joysticks such as pilots joysticks:这将避免操纵杆旋转,这在不对称操纵杆(例如飞行员操纵杆)的情况下尤其明显:
Explanation in comments:评论中的解释:
public void SetStickRotation(Vector2 stickInput)
{
/////////////////////////////////////////
// CONSTANTS (consider making a field) //
/////////////////////////////////////////
float maxRotation = 35f; // can rotate 35 degrees from neutral position (up)
///////////
// LOGIC //
///////////
// Convert input to x/z plane
Vector3 stickInput3 = new Vector3(stickInput.x, 0f, stickInput.y);
// determine axis of rotation to produce that direction
Vector3 axisOfRotation = Vector3.Cross(Vector3.up, stickInput3);
// determine angle of rotation
float angleOfRotation = maxRotation * Mathf.Min(1f, stickInput.magnitude);
// apply that rotation to the joystick as a local rotation
transform.localRotation = Quaternion.AngleAxis(angleOfRotation, axisOfRotation);
}
This will work for joysticks where:这将适用于操纵杆,其中:
stickInput
with y=0 should rotate the knob around the stick's forward/back axis, and stickInput
with x=0 should rotate the knob around the stick's left/right axis. y=0 的stickInput
应该围绕摇杆的前/后轴旋转旋钮,x=0 的stickInput
应该围绕摇杆的左/右轴旋转旋钮。 Figure out the problem, atan2 returns the angle in radiants, however the code assumes it is euler degrees, as soon as I did the conversion it worked well.找出问题所在,atan2 返回以辐射为单位的角度,但是代码假定它是欧拉度,只要我进行了转换,它就运行良好。 I put the code here if anyone is interested (not the change in the atan2 function):如果有人感兴趣,我将代码放在这里(不是 atan2 函数的更改):
public void SetStickRotation(Vector2 stickInput)
{
float magnitude = stickInput.magnitude;
// This function converts the magnitude to a range between the min and max rotation I want to apply to the 3D stick in the X axis
float rotationX = Utils.ConvertRange(0.0f, 1.0f, m_StickRotationMinX, m_StickRotationMaxX, magnitude);
float angle = Mathf.Atan2(direction.x, direction.y) * Mathf.Rad2Deg;
// Apply both rotations to the 3D model
m_Stick.localEulerAngles = new Vector3(rotationX, angle, 0.0f);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.