链接:https://pan.baidu.com/s/13gFh0XuuurTRVyyMtlyJfg
提取码:lfw2
第一部分就是为了方便观察的标志。
public struct DoorPoint
{
public Vector3 top_left;
public Vector3 top_right;
public Vector3 buttom_left;
public Vector3 buttom_right;
}
public class LocationMark : MonoBehaviour
{
public Vector2 Size;
DoorPoint m_point;
private Vector3 m_postion;
private Vector3 m_rotation;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
m_postion = this.gameObject.transform.position;
m_rotation = new Vector3(this.gameObject.transform.rotation.x, this.gameObject.transform.rotation.y, this.gameObject.transform.rotation.z);
}
//绘制出参考标点
void OnDrawGizmos()
{
Vector2 halfSize = Size * 0.5f;
Gizmos.color = Color.red;
float lineLength = Mathf.Min(Size.x, Size.y);
Gizmos.DrawLine(transform.position, transform.position + transform.forward * lineLength);
Gizmos.color = Color.green;
Gizmos.DrawLine(transform.position, transform.position + transform.right * lineLength);
Gizmos.color = Color.yellow;
Gizmos.DrawLine(transform.position, transform.position + transform.up * lineLength);
Gizmos.color = Color.blue;
Vector3 topLeft = transform.position - (transform.right * halfSize.x) + (transform.up * Size.y) / 2;
Vector3 topRight = transform.position + (transform.right * halfSize.x) + (transform.up * Size.y) / 2;
Vector3 bottomLeft = transform.position - (transform.right * halfSize.x) - (transform.up * Size.y) / 2;
Vector3 bottomRight = transform.position + (transform.right * halfSize.x) - (transform.up * Size.y) / 2;
Gizmos.DrawLine(topLeft, topRight);
Gizmos.DrawLine(topRight, bottomRight);
Gizmos.DrawLine(bottomRight, bottomLeft);
Gizmos.DrawLine(bottomLeft, topLeft);
}
}
建立一个空物体,空物体上加上这个代码如图所示
这里最终的结果是以两条红线为基准,让两个物体对接, 对接后红线完全重合。
接下来就是被装备物体的代码
public class AssambleObject : MonoBehaviour
{
private Transform mMark;
private Transform tMark;
public Transform TAssambleObject;
// Use this for initialization
void Start ()
{
mMark = this.transform.Find("LocationMark");
if (mMark == null)
{
Debug.LogError("本地对象未找到位置标志");
}
tMark = TAssambleObject.Find("LocationMark");
if (tMark==null)
{
Debug.LogError("目标对象未找到位置标志");
}
}
// Update is called once per frame
void Update ()
{
if (Input.GetKeyDown(KeyCode.Space))
{
MoveToTarget();
}
}
int j = 0;
private void MoveToTarget()
{
Vector3 RotateAix = Vector3.Cross(mMark.transform.forward, tMark.transform.forward);
float angle = Vector3.Angle(mMark.transform.forward, tMark.transform.forward);
mMark.transform.parent.Rotate(RotateAix, angle, Space.World);
while (true)
{
//第一步
float Angle = Vector3.Angle(tMark.transform.up, mMark.transform.up);
mMark.transform.parent.Rotate(tMark.transform.forward, Angle, Space.World);
//第二步
Vector3 moveVector = tMark.transform.position - mMark.transform.position;
mMark.transform.parent.transform.Translate(moveVector, Space.World);
j++;
if (Angle == 0 && moveVector == Vector3.zero)
{
Debug.Log("进行了多少次数:"+j);//发现一次不是能达到目标,所以重复几次
break;
}
}
}
}
按下空格键,于是两个方块就按照标记点合在一起了
装配前:
结果:
此方法可用于零件动态装配,以及VR中手柄抓取物体到正确位置