【问题标题】:Constrain object rotation to behave like joystick约束对象旋转以表现得像操纵杆
【发布时间】:2016-08-31 15:57:52
【问题描述】:

我正在尝试限制对象的旋转,使其表现得像一个操纵杆(这意味着它只能从中心旋转到某个最大角度)。

我试图在每个单独的轴上限制旋转,但它们在旋转时表现得非常奇怪(角度值不只是线性增长)。我用来提供这种旋转的输入是物理控制器的旋转。我该怎么做?

这就是它现在的工作方式以及我希望它的工作方式: 图像是 2D 的,但它适用于所有轴。

【问题讨论】:

  • 我认为您在此处提供的信息不足以让用户提供帮助。您是否有正在操作的对象的属性的图像,可能还有代码?演示您想要实现的目标的视觉辅助工具也可能会有所帮助,以及详细解释“它们在旋转时表现得非常奇怪”的意思(例如,当前行为如何无法实现您想要的。)
  • 我正在操作的对象并不重要,这个问题可以应用于任何具有旋转的对象。我也没有代码,因为我根本不知道,但我要添加一些图像。
  • 澄清一下,您如何接收将操纵虚拟操纵杆的输入?您是使用Input.GetAxis() 从实际操纵杆获取值(值范围为 [-1, 1]),还是其他形式的数据?
  • 不,我正在接收旋转(四元数),现在我只是将 localRotation 设置为这个四元数。

标签: unity3d rotation


【解决方案1】:

在我看来,这个问题有两个部分:

  1. 确定提供的旋转是否超过对象的最大允许旋转
  2. 如果提供的旋转太大,请减小该旋转以使其符合旋转约束,然后应用它

在我的代码示例中,我将假设虚拟操纵杆的初始旋转完全为零 (Quaternion.identity),并且您提供的旋转称为 newRotation

对于第一部分,我想到了Quaternion.Angle()。这给出了两个给定旋转之间的角度,可以像这样使用:

if (Quaternion.Angle(Quaternion.identity, newRotation) < 30){
    // Angle from initial to new rotation is under 30 degrees
}

对于第二部分,您需要某种方式来减少提供的旋转,使其在初始旋转的允许角度范围内。为此,Quaternion.Slerp() 很有用。这允许您在两个旋转之间进行插值,返回一个Quaternion,它是所提供的两者的组合。例如,这会返回一半的newRotation

Quaternion.Slerp(Quaternion.identity, newRotation, 0.5f);

将这两种方法放在一起,您可以编写一个夹紧方法,以确保提供的旋转不会超过初始旋转的某个角度。这是一个示例用法:

// Maximum angle joystick can tilt at
public float tiltAngle;
// If this isn't your initial rotation, set it in Awake() or Start()
Quaternion initialRotation = Quaternion.identity;

void Update(){
    Quaternion newRotation = MethodToGetSuppliedRotation();
    Quaternion clampedRotation = ClampRotation(initialRotation, newRotation, tiltAngle);
    transform.localRotation = clampedRotation;
}

// Clamps "b" such that it never exceeds "maxAngle" degrees from "a"
Quaternion ClampRotation(Quaternion a, Quaternion b, float maxAngle){
    float newAngle = Quaternion.Angle(a, b);
    if (newAngle <= maxAngle){
        // Rotation within allowable constraint
        return b;
    }
    else{
        // This is the proportion of the new rotation that is within the constraint
        float angleRatio = maxAngle / newAngle;
        return Quaternion.Slerp(a, b, angleRatio);
    }
}

希望这会有所帮助!如果您有任何问题,请告诉我。

【讨论】:

  • 谢谢,我一回家就试试看。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多