问题: 如果我使机芯正常工作,则不会检测到碰撞网格。如果我检测到碰撞网格物体,则说明该运动无法正常进行。
项目摘要: 我有一个3D环境,其中包含不可移动的对象(带有对撞机网格物体)和可移动的游戏对象(带有x2盒子对撞机的刚体),我通过C ++应用中的UDP连接使用触觉设备(基本上是3D游戏杆)进行控制放在一起并在Unity应用程序运行时运行。触觉设备与统一之间的通信非常好。我将从触觉设备传递的位置信息用作移动游戏对象的变量。同样,位置数据也可以很好地到达Unity;目前,我在Unity中使用具有适当条件和功能的位置数据的方法。
我尝试过的事情: 如果我使用 transform.localPosition (hapticDevicePosition);那么运动就很好了,但是它忽略了对撞机并通过了所有物体。我在网上阅读并了解到transform.localPosition基本上会将我的对象移到其他对象之上,而与物理无关。我还读到我可以在对象前面引入一个像0.000001的射线,这样如果该射线与任何其他对象相互作用,它就可以防止移动。这可能是仍然可以使用transform.localPosition的方式吗?我不确定,而且我从未使用过射线,因此很难正确设置该脚本。
我尝试了 AddForce 。这表现得很奇怪。它只给我2个力输出而不是3个力输出...即我只能在3个轴中的2个上移动。我不明白为什么它会这样。但是,可以检测到对撞机。
我尝试了 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);
}
}
}
此外,根据@Ali Baba的评论进行了更新: 我还没有时间测试其他方法,但是通过使用AddForce并使用拖动和力修改器变量,我能够控制所有三个轴(实际上是6DOF,因为我也从第二个轴开始进行旋转控制)外部设备),而且我对游戏对象的控制也比以前更好(特别是由于拖动和力修改器变量的调整)。这可能是最好的解决方案,但是我最初需要根据要使用的外部设备的位置来更改位置。我正在添加一个基本的,精简的,经过调整的代码,该代码使用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]
}
}
答案 0 :(得分:1)
除了将gameObject
放置在控制器的确切位置上之外,您可以尝试在想要gameObject
所处位置的方向上施加力:
if (control==1)
{
Vector3 forceDirection = realObjectCurrentPos - transform.localPosition;
rb.AddForce (forceDirection);
transform.localRotation = Quaternion.Euler(realObjectCurrentRot)
}
此处施加的力与gameObject
的位置与实际物体之间的距离成线性关系,因此,它的行为基本上像弹簧。您应该尝试将力乘以不同的因素并进行测试:
rb.AddForce (forceDirection * 0.5f);
或按平方缩放:
rb.AddForce (forceDirection * forceDirection.magnitude);
感觉最好的