object - unity - Problemas que limitan la rotación de objetos con Mathf.Clamp()
unity clamp01 (2)
El código que publicaste fija la posición z. Lo que quiere es usar transform.rotation
void ClampRotation(float minAngle, float maxAngle, float clampAroundAngle = 0)
{
//clampAroundAngle is the angle you want the clamp to originate from
//For example a value of 90, with a min=-45 and max=45, will let the angle go 45 degrees away from 90
//Adjust to make 0 be right side up
clampAroundAngle += 180;
//Get the angle of the z axis and rotate it up side down
float z = transform.rotation.eulerAngles.z - clampAroundAngle;
z = WrapAngle(z);
//Move range to [-180, 180]
z -= 180;
//Clamp to desired range
z = Mathf.Clamp(z, minAngle, maxAngle);
//Move range back to [0, 360]
z += 180;
//Set the angle back to the transform and rotate it back to right side up
transform.rotation = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, z + clampAroundAngle);
}
//Make sure angle is within 0,360 range
float WrapAngle(float angle)
{
//If its negative rotate until its positive
while (angle < 0)
angle += 360;
//If its to positive rotate until within range
return Mathf.Repeat(angle, 360);
}
Estoy trabajando en un juego que rota un objeto en el eje z. Necesito limitar la rotación total a 80 grados. Probé el siguiente código, pero no funciona. minAngle = -40.0f y maxAngle = 40.0f
Vector3 pos = transform.position;
pos.z = Mathf.Clamp(pos.z, minAngle, maxAngle);
transform.position = pos;
Aquí hay una versión estática de la buena solución de Imapler que, en lugar de cambiar el ángulo en sí, devuelve el ángulo recortado, por lo que se puede usar con cualquier eje.
public static float ClampAngle(
float currentValue,
float minAngle,
float maxAngle,
float clampAroundAngle = 0
) {
return Mathf.Clamp(
WrapAngle(currentValue - (clampAroundAngle + 180)) - 180,
minAngle,
maxAngle
) + 360 + clampAroundAngle;
}
public static float WrapAngle(float angle)
{
while (angle < 0) {
angle += 360;
}
return Mathf.Repeat(angle, 360);
}
O si no espera usar el método WrapAngle, aquí hay una versión todo en uno :
public static float ClampAngle(
float currentValue,
float minAngle,
float maxAngle,
float clampAroundAngle = 0
) {
float angle = currentValue - (clampAroundAngle + 180);
while (angle < 0) {
angle += 360;
}
angle = Mathf.Repeat(angle, 360);
return Mathf.Clamp(
angle - 180,
minAngle,
maxAngle
) + 360 + clampAroundAngle;
}
Entonces ahora puedes hacer:
transform.localEulerAngles.x = YourMathf.ClampAngle(
transform.localEulerAngles.x,
minX,
maxX
);