Как правильно перемещать объекты в Unity VR Toolkit (Raycast)?

#unity3d #virtual-reality #toolkit

#unity3d #виртуальная реальность #инструментарий

Вопрос:

я действительно застрял с какой-то более простой проблемой. я хочу воссоздать функцию в oculus home для своего собственного проекта квартиры, где я могу размещать и особенно перемещать / поворачивать мебель с помощью моего контроллера виртуальной реальности (raycast around).

на данный момент я могу перемещать мебель, привязывая transform.position объекта к RaycastHit.position. при реализации смещения я могу нажимать на объект, куда захочу, и перемещать его. Проблема:

  1. Объект игнорирует другие поверхности, такие как стены и полы, во время перемещения. (rigedbody игнорирует коллайдеры).
  2. Я не могу увеличить расстояние до raycast, потому что оно привязано к положению объектов. поэтому я могу уменьшить расстояние только при перемещении указателя на меня, но не от меня.

Это видео показывает поведение. Захват видео с Youtube со сцены

Пока это код. На правом RayController скрипт для передачи ненужной в данный момент позиции и HitPoint.position выбранному объекту

 using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.XR.Interaction.Toolkit;

public class ControllerPosition : MonoBehaviour
{
    public InputActionProperty positionProperty;
    [SerializeField] XRRayInteractor rayController;

    public Vector3 Position { get; private set; } = Vector3.zero;
    public Vector3 rayHitPosition { get; private set; } = Vector3.zero;


    private void Awake()
    {
        rayController = GetComponent<XRRayInteractor>();
    }

    private void Update()
    {
        if (rayController.TryGetHitInfo(out var hitPosition, out var hitNormal, out _, out _))
        {
            rayHitPosition = hitPosition;
        }

        Position = positionProperty.action.ReadValue<Vector3>();
    }
}
 

Это код для перетаскиваемого объекта

 using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;

public class DragObject : XRGrabInteractable
{
    [SerializeField] XRRayInteractor ray;

    private Vector3 mOffset;

    private ControllerPosition controllerPosition = null;

    protected override void Awake()
    {
        base.Awake();
    }

    protected override void OnSelectEntered(SelectEnterEventArgs args)
    {
        base.OnSelectEntered(args);
        controllerPosition = args.interactor.GetComponent<ControllerPosition>();

        mOffset = gameObject.transform.position - controllerPosition.rayHitPosition;
    }

    protected override void OnSelectExited(SelectExitEventArgs args)
    {
        base.OnSelectExited(args);
        controllerPosition = null;
    }

    public override void ProcessInteractable(XRInteractionUpdateOrder.UpdatePhase updatePhase)
    {
        base.ProcessInteractable(updatePhase);

        if (isSelected)
        {
            if (updatePhase == XRInteractionUpdateOrder.UpdatePhase.Dynamic)
            {
                UpdateObjectPosition();
            }
        }
    }

    private void UpdateObjectPosition()
    {
        Vector3 position = controllerPosition ? controllerPosition.Position : Vector3.zero;
        
        transform.position = controllerPosition.rayHitPosition   mOffset;

    }
}
 

Какие-нибудь советы?

с наилучшими пожеланиями

Комментарии:

1. Я бы предложил изменить тип движения на отслеживание скорости. Это позволит жесткому телу проверять наличие столкновений. Что касается определения расстояния для работы, я бы попробовал использовать отдельный луч, отличный от того, который используется для обнаружения объекта, или игнорировать тег / слой захвата во время raycast, когда вы уже выбираете объект.