Unity - 对对象应用两个局部旋转(尝试将控制器操纵杆的旋转重新创建为 3D 网格操纵杆)
Unity - Apply two local rotations to object (trying to recreate the rotation of a controller joystick into a 3D mesh joystick)
我想将真实控制器操纵杆(即 360 控制器)的旋转一对一地重新创建为 3D 操纵杆网格(类似于 360 控制器)。
我考虑过根据输入的大小在 X 轴上旋转操纵杆(将其映射到 X 轴上的最小和最大旋转)。然后计算输入的角度并将其应用于3D摇杆的Y轴。
这是我的代码,操纵杆在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);
}
我不确定为什么不起作用,或者即使我以正确的方式进行操作(即也许有更优化的方法来实现它)。
非常感谢您的意见。
我建议将它旋转一定量,该量由围绕由方向确定的单个轴的幅度确定。这将避免操纵杆旋转,这在非对称操纵杆(例如飞行员操纵杆)的情况下尤其明显:
评论中的解释:
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);
}
这适用于操纵杆,其中:
- 从它的轴到它的末端的方向就是局部向上的方向,
- 它应该在中性输入上有零(身份)旋转,并且
y=0 的 stickInput
应该围绕摇杆的 forward/back 轴旋转旋钮,而 x=0 的 stickInput
应该围绕摇杆的 left/right 旋转旋钮轴.
找出问题所在,atan2 returns 以辐射点为单位的角度,但是代码假设它是欧拉度,一旦我进行了转换,它就运行良好。
如果有人感兴趣,我把代码放在这里(不是 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);
}
我想将真实控制器操纵杆(即 360 控制器)的旋转一对一地重新创建为 3D 操纵杆网格(类似于 360 控制器)。
我考虑过根据输入的大小在 X 轴上旋转操纵杆(将其映射到 X 轴上的最小和最大旋转)。然后计算输入的角度并将其应用于3D摇杆的Y轴。
这是我的代码,操纵杆在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);
}
我不确定为什么不起作用,或者即使我以正确的方式进行操作(即也许有更优化的方法来实现它)。
非常感谢您的意见。
我建议将它旋转一定量,该量由围绕由方向确定的单个轴的幅度确定。这将避免操纵杆旋转,这在非对称操纵杆(例如飞行员操纵杆)的情况下尤其明显:
评论中的解释:
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);
}
这适用于操纵杆,其中:
- 从它的轴到它的末端的方向就是局部向上的方向,
- 它应该在中性输入上有零(身份)旋转,并且 y=0 的
stickInput
应该围绕摇杆的 forward/back 轴旋转旋钮,而 x=0 的stickInput
应该围绕摇杆的 left/right 旋转旋钮轴.
找出问题所在,atan2 returns 以辐射点为单位的角度,但是代码假设它是欧拉度,一旦我进行了转换,它就运行良好。 如果有人感兴趣,我把代码放在这里(不是 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);
}