Проблема: Если я заставлю движение работать правильно, то столкновительные сетки не будут обнаружены.Если я обнаружу сетки столкновений, то движение будет работать некорректно.
Краткое описание проекта: У меня есть трехмерная среда с неподвижными объектами (с сетками коллайдеров) иподвижный игровой объект (твердое тело с коробочными коллайдерами x2), которым я управляю, используя тактильные устройства (в основном 3D-джойстик) через соединение UDP в приложении C ++, которое я собрал и которое работает во время работы приложения Unity.Связь между тактильными устройствами и единством в порядке.Я использую информацию о местоположении, передаваемую из тактильного устройства, в качестве переменных для перемещения моего игрового объекта.Опять же, данные о местоположении поступают в Unity просто отлично;метод использования данных о местоположении с соответствующими условиями и функциями в Unity - вот где я застрял.
Вещи, которые я пытался: Если я использую transform.localPosition (hapticDevicePosition);тогда движение велико, но оно игнорирует коллайдеры и проходит через все.Я читаю онлайн и понимаю, что transform.localPosition будет в основном перемещать мой объект поверх других объектов безотносительно к физике.Я также читал, что, возможно, я смогу ввести луч, который равен 0,000001, перед моим объектом, так что он предотвращает движение, если луч взаимодействует с любым другим объектом.Это может быть способ по-прежнему иметь возможность использовать transform.localPosition?Я не уверен, и я никогда не использовал лучи, поэтому мне было бы трудно правильно настроить этот скрипт.
Я пробовал AddForce .Это ведет себя очень странно.Это дает мне только 2 выхода силы вместо 3 ... т.е. я могу двигаться только в 2 из 3 осей.Я не понимаю, почему так себя ведет.Однако обнаружены коллайдеры.
Я пробовал rb.MovePosition (rb.position + posX + posY + posZ) и различные комбинации * Time.timeDelay и * speed, а также,Это также не работает правильно.Коллайдеры обнаружены, но движение либо вообще не работает, либо работает неправильно.
Вывод: Я играл со своим сценарием в течение последних 4 часов, и некоторые (не все) вещи, которые я пытался закомментировать, так что онивсе еще видно (см. код ниже).Я буду читать больше онлайн объяснений и пробовать другой код и обновлять здесь, если я найду решение.Если у кого-то есть какие-то указания или предложения, я буду очень признателен.
Спасибо!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FalconPegControl_2 : MonoBehaviour {
// Define needed variables
private TestUDPConnection udpListener;
public Vector3 realObjectCurrentPos;
private Vector3 realObjectLastPos;
public Vector3 realObjectCurrentRot;
private Vector3 realObjectLastRot;
public Vector3 realObjectPosChange;
public Vector3 realObjectRotChange;
private Quaternion rotation;
//public float pi = 3.14f;
private Rigidbody rb;
private int control = 0;
public bool collisionOccurred = false;
//public float thrust = 1000;
//public CalibrationManager calibrationManager;
// Use this for initialization
void Start () {
udpListener = GetComponentInParent<TestUDPConnection>();
collisionOccurred = false;
rb = GetComponent<Rigidbody> ();
SharedRefs.falconPegControl = this;
}
public void OffControl ()
{
control = 0;
}
public void CollisionDuplicateFix ()
{
collisionOccurred = true;
}
// Update is called once per frame
void FixedUpdate () {
//WITHOUT UNITY AXIS CONVERSION:
//realObjectCurrentPos[0] = udpListener.xPosReal; //[m]
//realObjectCurrentPos[1] = udpListener.yPosReal; //[m]
//realObjectCurrentPos[2] = udpListener.zPosReal; //[m]
//===============================
//Unity axis conversions:
//CHAI3D --> Unity
//(x, y, z) --> (x, -z, y)
//CHAI3D: realObjectCurrentPos[0], [1], [2] is CHIA3D (x, y, z)
//Also, to compensate for the workspace available to the Falcon Device (~0.04, ~0.06, ~0.06)
//adding a value of x10 allows it to reach the default hemisphere successfully
//updated comment: the sign values that work (-, +, -)
//===============================
//Unity conversion for rotation (using Falcon devices)
//Since one falcon is for translation and the other is for rotation,
//the rotation information is a conversion of translational information
//in other words, max range of (~0.04, ~0.06, ~0.06) has been converted into a max range of (90, 90, 90)
//using basic algebra (i.e., (90/0.04))
//thus giving the user the full range of 180 degrees (from 90 degrees to -90 degrees)
realObjectCurrentPos[0] = udpListener.xPosReal * (-5); //[m]
realObjectCurrentPos[1] = udpListener.zPosReal * (5); //[m]
realObjectCurrentPos[2] = udpListener.yPosReal * (-5); //[m]
realObjectCurrentRot [0] = udpListener.xRot * (90f / 0.04f); //degrees
realObjectCurrentRot [1] = udpListener.yRot * (90f / 0.06f); //degrees
realObjectCurrentRot [2] = udpListener.zRot * (90f / 0.06f); //degrees
if (Input.GetKeyDown ("1")) {
control = 1;
SharedRefs.stopWatch.startTimer ();
}
if (Input.GetKeyDown ("space"))
{
OffControl ();
}
if (control==1)
{
Vector3 posUnity = new Vector3 (realObjectCurrentPos[0], realObjectCurrentPos[1], realObjectCurrentPos[2]);
rb.AddForce (posUnity);
//Vector3 tempVect = new Vector3(realObjectCurrentPos[0], realObjectCurrentPos[1], realObjectCurrentPos[2]);
//Vector3 startPoint = new Vector3 (0f, 0.0225f, 0f);
//tempVect = tempVect * speed * Time.deltaTime;
//transform.localPosition = realObjectCurrentPos; //[m]
//var unityX = Vector3.Scale (posTemp, Vector3.right);
//var unityY = Vector3.Scale (posTemp, Vector3.up);
//var unityZ = Vector3.Scale (posTemp, Vector3.forward);
//Vector3 unityX = new Vector3 (Vector3.Scale (posTemp, Vector3.right), Vector3.Scale (posTemp, Vector3.up), Vector3.Scale (posTemp, Vector3.forward));
//Vector3 unityY = new Vector3 (Vector3.Scale (posTemp, Vector3.up));
//Vector3 unityZ = new Vector3 (Vector3.Scale (posTemp, Vector3.forward));
//rb.MovePosition (rb.position + unityX + unityY + unityZ);
//transform.localPosition = (startPoint + tempVect); //[m]
transform.localRotation = Quaternion.Euler(realObjectCurrentRot); //[m]
realObjectLastPos = realObjectCurrentPos;//[m]
realObjectLastRot = realObjectCurrentRot;//[m]
realObjectPosChange = realObjectCurrentPos - realObjectLastPos; //[m]
realObjectRotChange = realObjectCurrentRot - realObjectLastRot;
}
else if (control==0)
{
Vector3 stop = new Vector3 (0, 0, 0);
rb.constraints = RigidbodyConstraints.FreezePositionZ | RigidbodyConstraints.FreezeRotationZ;
rb.constraints = RigidbodyConstraints.FreezePositionX | RigidbodyConstraints.FreezeRotationX;
rb.constraints = RigidbodyConstraints.FreezePositionX | RigidbodyConstraints.FreezeRotationX;
rb.velocity = (stop);
}
}
}
Кроме того, обновлено из комментариев @ Али Али Бабы: у меня еще не было времени протестировать другие методы, но с помощью AddForce и игры с перетаскиванием и переменной модификатора силы я смогполучить контроль над всеми тремя осями (на самом деле 6DOF, потому что у меня также есть управление вращением от 2-го внешнего устройства), и у меня также намного лучший контроль над моим игровым объектом, чем раньше (особенно из-за настроек переменной модификатора перетаскивания и изменения силы).Это может быть лучшим решением, но изначально мне нужно было изменить свою позицию в зависимости от положения внешних устройств, которые я использую.Я добавляю базовый, уменьшенный, скорректированный код, который использует AddForce и позволяет регулировать управление ключом перетаскивания и моей переменной-модификатора силы в случае, если другие новички также увидят этот поток.Тем временем я попытаюсь заставить другие функции (MovePosition и т. Д.) Работать и обновлять результаты.
Тонкий, базовый код для перетаскивания / тестирования переменных:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Real_Controller : MonoBehaviour {
// Define needed variables
private TestUDPConnection udpListener;
public Vector3 realObjectCurrentPos;
public Vector3 realObjectCurrentRot;
private Quaternion rotation;
private Rigidbody rb;
private float increaseForce = 23;
// Use this for initialization
void Start () {
udpListener = GetComponentInParent<TestUDPConnection>();
rb = GetComponent<Rigidbody> ();
rb.drag = 1.24f;
}
// Update is called once per frame
void FixedUpdate () {
if (Input.GetKeyDown ("q"))
{
rb.drag -= 0.1f;
Debug.Log ("drag is: " + rb.drag);
}
if (Input.GetKeyDown ("w"))
{
rb.drag += 0.1f;
Debug.Log ("drag is: " + rb.drag);
}
if (Input.GetKeyDown ("a")) {
increaseForce -= 1f;
Debug.Log ("increased force is: " + increaseForce);
}
if (Input.GetKeyDown ("s")) {
increaseForce += 1f;
Debug.Log ("increase force is: " + increaseForce);
}
realObjectCurrentPos[0] = udpListener.xPosReal * (-increaseForce); //[m]
realObjectCurrentPos[1] = udpListener.zPosReal * (increaseForce); //[m]
realObjectCurrentPos[2] = udpListener.yPosReal * (-increaseForce); //[m]
Vector3 forceDirection = realObjectCurrentPos - transform.localPosition;
rb.AddForce (forceDirection * forceDirection.magnitude);
realObjectCurrentRot [0] = udpListener.xRot * (90f / 0.04f); //degrees
realObjectCurrentRot [1] = udpListener.yRot * (90f / 0.06f); //degrees
realObjectCurrentRot [2] = udpListener.zRot * (90f / 0.06f); //degrees
transform.localRotation = Quaternion.Euler(realObjectCurrentRot); //[m]
}
}