使用unity进行零件装配

测试工程百度网盘链接:链接:https://pan.baidu.com/s/1nswyqrsFTyc_sVdppgIAXA
提取码:dkzm

第一部分就是为了方便观察的标志。

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);
    }

}

建立一个空物体,空物体上加上这个代码如图所示

使用unity进行零件装配_第1张图片

这里最终的结果是以两条红线为基准,让两个物体对接, 对接后红线完全重合。

接下来就是被装备物体的代码

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;
            }
        }
    }
}

使用unity进行零件装配_第2张图片使用unity进行零件装配_第3张图片

按下空格键,于是两个方块就按照标记点合在一起了

装配前:

使用unity进行零件装配_第4张图片

结果:

使用unity进行零件装配_第5张图片

此方法可用于零件动态装配,以及VR中手柄抓取物体到正确位置

你可能感兴趣的:(虚拟设计)