Я закончил тем, что решил свою проблему, после нескольких дней чесания моей головы действительно, очень сильно. Если честно, я бы, наверное, не справился бы сам по себе из-за проблемы с logi c (это очень часто так, не так ли?).
Initial Setup
В моем случае игровой объект, с которым нужно взаимодействовать, представляет собой винт. Я хотел, чтобы он выполнял положительный перевод, когда происходит положительный поворот, и наоборот. К этому игровому объекту прикреплены некоторые компоненты:
- коллайдер (мне sh, коробка, капсула)
- твердое тело
- PointerHandler.cs (MRTK)
- a ObjectManipulator.cs (MRTK)
- a NearInteractionGrabbable.cs (MRTK)
- TwistingRotation.cs, найденный ниже
твердое тело, PointerHandler.cs, ObjectManipulator.cs и конфигурации TwistingRotation.cs можно найти здесь:
Волхвы c появляются вместе с PointerHandler.cs которые позволяют нам определять, когда происходит близкое взаимодействие с винтом, благодаря событию OnPointerDragged.
TwistingRotation.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Translation of the object while rotating it when grabbed using the MRTK.ObjectManipulator
/// Boundaries and axis restrictions ongoing
/// </summary>
public class TwistingRotation : MonoBehaviour
{
/*******CACHE REFERENCE*******/
private Transform _myTransform;
[SerializeField] private float translationFactor = 90f;
private Vector3 _minPosition;
private Vector3 _maxPosition;
private Vector3 _previousVector;
private Rigidbody _rb;
private void Start()
{
// Cache reference
_myTransform = gameObject.transform;
_rb = gameObject.GetComponent<Rigidbody>();
// Reference for the previous rotation vector
_previousVector = _myTransform.up;
// Default position is the maximum transform.position (unscrewed)
_maxPosition = _myTransform.position;
// Minimum position is default transform.position + 1unit in local space direction
_minPosition = _maxPosition + Vector3.forward;
}
/// <summary>
/// Move the object according to the rotation angle value
/// A positive rotation leads to a positive translation, and vice-versa
/// </summary>
public void TranslateRotation()
{
// Retrieve the angle on a defined local axis when the rotation occur
var currentVector = _myTransform.up;
// Compute the angle between the previous and the current vector on a defined local axis
// Difference between the previous rotation vector, and the actual, on a global axis
var angle = Vector3.SignedAngle(_previousVector, currentVector, Vector3.forward);
// Move object proportional to its rotation
var translation = Vector3.forward * (angle / translationFactor);
_myTransform.Translate(translation, Space.Self);
// Get the GO current position
var currentPosition = _myTransform.position;
// Clamp for each axis between _minPosition and _maxPosition (the default spawn position)
// Doing a Mathf.Min/Max inside the Mathf.Clamp to insure that the min and max values are correct
var x = Mathf.Clamp(currentPosition.x, Mathf.Min(_minPosition.x, _maxPosition.x), Mathf.Max(_minPosition.x, _maxPosition.x));
var y = Mathf.Clamp(currentPosition.y, Mathf.Min(_minPosition.y, _maxPosition.y), Mathf.Max(_minPosition.y, _maxPosition.y));
var z = Mathf.Clamp(currentPosition.z, Mathf.Min(_minPosition.z, _maxPosition.z), Mathf.Max(_minPosition.z, _maxPosition.z));
// Compute the new position while taking the boundaries into consideration
var newPosition = new Vector3(x, y, z);
_myTransform.position = newPosition;
// Save position for the next frame
_previousVector = currentVector;
}
}
Что происходит?
Довольно просто: при вращении винт перемещается более чем на 1 (единицу). Значение поворота зависит от значения переменной translationFactor. В моем случае это значение 360, так что полный оборот за единицу перевода (1).
Результат
Это далеко не идеально, вероятно, очень "ме" но эй, это работает (не так, как задумано, но все же), и это позволило мне двигаться вперед, и я сделал свою презентацию.