机器人手臂(对撞机是活动区域)
问题的说明
我正在制作机械臂的虚拟克隆,需要它移动到立方体(可移动区域)内的坐标。目前,机器人手臂由三个值x,y和z控制。这些值可使机器人手臂的头部到达立方体的所有四个角。值从0到100。我需要在unitys世界空间中将vector3转换为多维数据集内的这些值。我这样做是为了在不破坏此功能的情况下移动和旋转整个机器人预制件。关于如何实现此目标的任何想法?
答案 0 :(得分:3)
如果它是一个简单的立方体,那么您只需要知道它的边缘大小并执行类似的操作即可
// Set this e.g. in the Inspector
// or somewhere get it e.g. in Start like
// edgesize = transform.lossyScale.x;
public float edgesize;
public Vector3 RobotToUnityPosition(Vector3 input)
{
var output = input;
// first shift the values in order to map the values (0 to 100) to
// (-50 to +50)
output -= Vector3.one * 50.0f;
// now eliminate the factor 100
// so you get (-0.5 to +0.5)
output /= 100.0f;
// finally scale it accordingly to the cube's edgesize
// so get it mapped to (-0.5 * edgesize to +0.5 * edgesize)
output *= edgesize;
return output;
// could ofcourse also be done in one line like
return ((input - Vector3.one * 50) / 100.0f) * edgesize;
}
public Vector3Int UnityToRobotPosition(Vector3 input)
{
// basically do it the other way round
var output = input;
// Get percentages
// (-0.5 to +0.5)
output /= edgesize;
// scale it up to factor 100
// (-50 to +50)
output *= 100.0f;
// shift the values back
// (0 to 100)
output += Vector3.one * 50.0f;
// Until here you also could have done it again in one line like
//var output = (intput / edgesize) * 100.0f + Vector3.one * 50.0f;
// Now you might want to clamp the values
output.x = Mathf.Clamp(output.x, 0, 100);
output.y = Mathf.Clamp(output.y, 0, 100);
output.z = Mathf.Clamp(output.z, 0, 100);
// Finally you might want to get it as Vector3Int ?
// if not you can skip that and change the return type to Vector3
return Vector3Int.FloorToInt(output);
}
演示(我添加了一些内容只是为了演示其工作原理)
这是我要用作起点的完整代码
public class PositionConverter : MonoBehaviour
{
public float edgesize;
public Vector3 inputVector;
// I used a transform here in order to simply drag around
// the object in Unity (or set it via script)
public Transform WorldSpacePosition;
public Vector3 backtoRobot;
// whether to automatically update backtoRobot using the WorldSpacePosition.localPosition;
public bool autoupdate;
private void Awake()
{
// I simply used the lossyScale.x as edgeSize
edgesize = transform.lossyScale.x;
}
private void Update()
{
if(!autoupdate)return;
UpdateRobotPosition();
}
// Just fancy stuff for being able to call that method via
// the context menu
[ContextMenu("UpdateWorldPosition")]
private void UpdateWorldPosition()
{
WorldSpacePosition.localPosition = RobotToUnityPosition(inputVector);
}
// Just fancy stuff for being able to call that method via
// the context menu
[ContextMenu("UpdateRobotPosition")]
private void UpdateRobotPosition()
{
backtoRobot = UnityToRobotPosition(WorldSpacePosition.localPosition);
}
public Vector3 RobotToUnityPosition(Vector3 input)
{
var output = input;
// first shift the values since 0 means e.g. -x edge etc
output.x -= Vector3.one * 50.0f;
// eliminate the factor 100
output /= 100.0f;
// scale it according to the cube's edgesize
output *= edgesize;
return output;
}
public Vector3Int UnityToRobotPosition(Vector3 input)
{
// basically do it the other way round
var output = input;
// Get percentages
output /= edgesize;
// scale it up to factor 100
output *= 100;
// shift the values back
output += Vector3.one * 50.0f;
// you might want to clamp the values
output.x = Mathf.Clamp(output.x, 0, 100);
output.y = Mathf.Clamp(output.y, 0, 100);
output.z = Mathf.Clamp(output.z, 0, 100);
// you might want to get it as Vector3Int ?
// if not you can skip that and change the return type to Vector3
return Vector3Int.FloorToInt(output);
}
// Just for drawing the WireCube for the bounds
private void OnDrawGizmos()
{
edgesize = transform.lossyScale.x;
Gizmos.matrix = transform.localToWorldMatrix;
Gizmos.DrawWireCube(Vector3.zero, Vector3.one * edgesize);
}
}
GameObject
中,并在Transform
中设置比例尺WorldSpacePosition
答案 1 :(得分:2)
这很简单。您可以使用Transform组件在任何对象局部空间中执行计算。
// constants (choose as they fit your scene)
Vector3 cubeSize = new Vector3(100, 100, 100);
Vector3 cubePivotLocal = new Vector3(0, 0, 0);
// The actual calculation
Vector3 worldPos = (your target world position);
Vector3 localPos = Vector3.Scale((transform.InverseTransformPoint(worldPos) - cubePivotLocal), cubeSize);
// localPos contains position of the target point in the local space of the script holder (your robot)
考虑了脚本持有者及其父代(祖父母,...)的所有转换(平移,旋转,缩放)。