【问题标题】:Rotate around the touched position using oculus controller使用 oculus 控制器围绕触摸的位置旋转
【发布时间】:2019-05-21 01:01:12
【问题描述】:

我想将一个附加的对象(有点抓取,手动更新位置)旋转到 oculus 控制器,但不应该是控制器的子对象。

流程如下, 1.假设我有一个对象(枢轴(X,Y,Z))并且我触摸它(A,B,C)来抓住它,我正在手动更新它的位置而不是让它成为控制器的孩子。 2. 现在物体随着控制器一起移动,想要计算它的旋转,使其看起来像附加了物体,并根据控制器更新它的旋转。

有什么想法吗??

【问题讨论】:

  • but shouldn't be a child of the controller 为什么不呢?在我看来,最简单的解决方案是暂时让它成为控制器的孩子,当你再次放手时,让它不再是控制器的孩子。
  • Transform.RotateAround 似乎是个好建议
  • @zambari 你需要它 3 次,所以对于每个轴我猜 ^^
  • @zambari 我尝试了 Rotatearound,每个轴的每一行,但面临一个错误,如果我快速摇动控制器,对象将围绕连接点上的控制器旋转。
  • Update、LateUpdate 和 FixedUpdate 的区别(我认为还有一点可以附加代码)

标签: unity3d oculus


【解决方案1】:

如果你不想让它只是一个孩子,我会自然而然地看到 3 个选项:

1。使用FixedJoint

限制一个对象的移动依赖于另一个对象。这有点类似于 Parenting,但通过物理而不是 Transform 层次结构实现。使用它们的最佳场景是当您想要轻松地将对象分开时,或者在没有父级的情况下连接两个对象的移动。

所以每当你抓住物体时,做一些类似的事情

var fixedJoint = grabbedObject.AddComponent<FixedJoint>();
fixedJoint.connectedBody = controllerObject.GetComponent<RigidBody>();

//disable autoconfigure anchor
fixedJoint.autoConfigureConnectedAnchor = false;

// And set offsets depending on the current relative positions

// Get the position of the object in the controllers local coordinates
fixedJoint.connectedAnchor = controllerObject.transform.InverseTransformPoint(grabbedObject.transform.position);

// And get the controllers position relative to the object
fixedJoint.anchor = gtabbedObject.transform.InverseTransformPoint(controller.transform.posotion);

无论你在哪里释放对象,都要移除那个关节,例如

Destroy(grabbedObject.GetComponent<FixedJoint>());

2。计算变换

获取相对位置偏移量,您也可以使用一种伪造的父子关系,只需使用控制器本地坐标系按组件方式添加偏移量。

在可抓取对象上有类似的组件

public class CopyTransforms : MonoBehaviour
{
    private Transform target;
    private Transform startOffset;

    private RigidBody rb;

    private void Awake()
    {
        rb = GetComponent<RigidBody>();
    }

    // Call this In the moment you grab the object 
    public void Grab(Transform grabber)
    {
        target = grabber;
        offset = transform.position - target.position;
    }

    // Call this when releasing
    public void Release()
    {
        target = null;
    }

    // If dealing with rigidbodies you should use fixedupdate
    private void FixedUpdate()
    {
        if(!target) return;

        // Apply rotation
        rb.MoveRotation(target.rotation);

        var targetPosition = target.position + target.right * offset.x + target.up * offset.y + target.forward * target.z;
        rb.MovePosition(targetPosition);
    }
}

3。使用假养育方式

这个想法是在控制器下有一个空对象。

在您抓取的那一刻,您将此空对象的位置设置为您抓取的对象所在的位置 -> 将来,每当移动控制器时,此空对象将是您抓取的对象应该在的位置。所以你只需要应用它的转换并完成

var emptyObject = new GameObject("empty");
emptyObject.transform.SetParent(controllerObject.trasform, false);

emptyObject.transform.rotation = grabbedObject.transform.rotation;
emptyObject.transform.position = grabbedObject.transform.position;

现在您必须简单地复制其转换,例如在

void Update()
{
    grabbedObject.transform.rotation = emptyObject.transform.rotation;

    grabbedObject.transform.position = emptyObject.transform.position;
}

或像以前一样在FixedUpdate 中。


注意:在智能手机上打字,所以没有保修,但我希望这个想法能清楚。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-08
    • 2013-04-19
    • 1970-01-01
    • 2015-05-02
    相关资源
    最近更新 更多