Unity - 任意角度之间的夹子旋转

Unity - Clamp Rotation between arbitrary angles(Unity - 任意角度之间的夹子旋转)
本文介绍了Unity - 任意角度之间的夹子旋转的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个任务,我必须在其他两个角度之间夹一个角度.

I have a task where I have to clamp an angle between other two angle.

问题是限制可以是 >360 或 <0

The catch is that the limits can be >360 or <0

(例如 [-45,45] 或 [275,45]).

(ex. [-45,45] or [275,45]).

考虑到所有特殊情况,有没有一种干净的方法来做到这一点?案例?

Is there a clean way to do this taking into account all the special cases?

(例如,范围 [-45,45] 和 225 的输入角度应为 -45).

(ex. range [-45,45] and input angle of 225 should be -45).

提前致谢!附言我正在使用统一,所以我手头有所有默认的四元数方法.

Thanks in advance! P.S. I am using unity, so I have all the default Quaternion methods at hand.

当前代码:

  Quaternion inputAngle = Quaternion.identity;
            if (Character.IsFacingRight)
                inputAngle = Quaternion.FromToRotation(forwardVector, playerInput);
            else
                inputAngle = Quaternion.FromToRotation(playerInput, forwardVector);
            Quaternion minAngle = Quaternion.Euler(0F, 0F, addedForce.force.angle);
            Quaternion angleRange = Quaternion.Euler(0F, 0F, addedForce.force.angleRange);
            Quaternion maxAngle = angleRange * minAngle;

            // var yaw = Math.Atan2(2.0 * (inputAngle.y * inputAngle.z + inputAngle.w * inputAngle.x), inputAngle.w * inputAngle.w - inputAngle.x * inputAngle.x - inputAngle.y * inputAngle.y + inputAngle.z * inputAngle.z);
            // var pitch = Math.Asin(-2.0 * (inputAngle.x * inputAngle.z - inputAngle.w * inputAngle.y));
            float roll = (float)Math.Atan2(2.0 * (inputAngle.x * inputAngle.y + inputAngle.w * inputAngle.z), inputAngle.w * inputAngle.w + inputAngle.x * inputAngle.x - inputAngle.y * inputAngle.y - inputAngle.z * inputAngle.z);

            Quaternion correctedRotation = Quaternion.Euler(0F, 0F, roll / Mathf.PI * 180F);

            float endAngleZ = ClampRotation2(correctedRotation.eulerAngles.z, minAngle.eulerAngles.z, maxAngle.eulerAngles.z);

            Quaternion endAngle = Quaternion.Euler(0F, 0F, endAngleZ);

夹具旋转2:

public static float ClampRotation2(float angle, float min, float max)
{
    if (angle < 0) angle += 360;

    if (max < 0) max += 360;

    if (min < 0) min += 360;
    if (min > max) min -= 360;

    return Mathf.Clamp(angle, min, max);
}

推荐答案

好的,所以我找到了在所有情况下都能正确夹角的解决方案,

OK, so I found the solution which clamps the angle correctly in all cases,

Quaternion.Angle() 带给你我呈现:

Quaternion inputAngle = Quaternion.identity;
            if (Character.IsFacingRight)
                inputAngle = Quaternion.FromToRotation(forwardVector, playerInput);
            else
                inputAngle = Quaternion.FromToRotation(playerInput, forwardVector);
            Quaternion minAngle = Quaternion.Euler(0F, 0F, addedForce.force.angle);
            Quaternion angleRange = Quaternion.Euler(0F, 0F, addedForce.force.angleRange);
            Quaternion maxAngle = angleRange * minAngle;

            float roll = (float)Math.Atan2(2.0 * (inputAngle.x * inputAngle.y + inputAngle.w * inputAngle.z), inputAngle.w * inputAngle.w + inputAngle.x * inputAngle.x - inputAngle.y * inputAngle.y - inputAngle.z * inputAngle.z);
            float correctedRotation = roll / Mathf.PI * 180F;

            float minAngleF = minAngle.eulerAngles.z;
            float maxAngleF = maxAngle.eulerAngles.z;

            if (correctedRotation < 0) correctedRotation += 360;

            if (maxAngleF < 0) maxAngleF += 360;

            if (minAngleF < 0) minAngleF += 360;
            if (minAngleF > maxAngleF) minAngleF -= 360;

            if (correctedRotation < minAngleF || correctedRotation > maxAngleF)
            {
                float rotationToMax = Quaternion.Angle(Quaternion.Euler(0F, 0F, correctedRotation), Quaternion.Euler(0F, 0F, maxAngleF));
                float rotationToMin = Quaternion.Angle(Quaternion.Euler(0F, 0F, correctedRotation), Quaternion.Euler(0F, 0F, minAngleF));
                if (Mathf.Abs(rotationToMax) < Mathf.Abs(rotationToMin))
                    correctedRotation = maxAngleF;
                else
                    correctedRotation = minAngleF;
            }
            Quaternion endAngle = Quaternion.Euler(0F, 0F, correctedRotation);

这篇关于Unity - 任意角度之间的夹子旋转的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)