基于unity+vuforia的VR二级齿轮减速器动画分解

AR二级齿轮减速器动画分解

记录一下自己上学期做的期末作业之一,二级齿轮是一个简模,它的分解动画主要是利用unity自带动画帧系统K的,有点小简陋哈哈。莫见笑。

一、功能需求

基于AR图像识别、二级齿轮减速器动画分解和文字说明以及对减速器的放大、缩小、旋转。

二、系统开发的关键技术

2.1 AR图像识别

识别图:
在这里插入图片描述
摄像机进行图像识别后,出现二级齿轮 减速器动画分解界面,进入动画分解步骤。
成果如图1展示:
在这里插入图片描述图1

2.2 UI设计

二级齿轮减速器动画分解开始的文字说明:
在这里插入图片描述

三、系统的详细设计与具体实现

3.1 系统的功能模块

3.1.1 AR图像识别功能

在Unity2018导入vuforia Engine模块以后,添加AR camera组件以及imagetarget组件,选择相应的数据库与图片,
在这里插入图片描述

3.1.2 实现动画分解功能

摄像机识别出现二级齿轮减速器后,按设定步骤分解动画,关键代码如下

//实例化对象
public GameObject CamObj;
public GameObject SubObj;
public GameObject[] OBJ1;
public GameObject[] OBJ2;
 public GameObject[] OBJ3; 
public GameObject[] OBJ4;
 public GameObject[] OBJ5;
public GameObject[] OBJ6;
public GameObject[] OBJ7;
public GameObject[] OBJ8;
public GameObject[] OBJ9; 
public GameObject[] OBJ10;
//获取动画
private Animator CamAnim;
private Animator SubAnim;
AnimatorStateInfo CamStateInfo;
AnimatorStateInfo SubStateInfo;
public int Step;
 private float AddTime;
 void Start() 
 CamAnim = CamObj.GetComponent<Animator>();
 SubAnim = SubObj.GetComponent<Animator>();
 Step = 0; void Update()
        print(Step);
        switch (Step)
        {
            case 0://第一步相机动画
                if(CamAnim)
                {
                    CamStateInfo = CamAnim.GetCurrentAnimatorStateInfo(0);
                    if (CamStateInfo.IsName ("Base Layer.CamAnim1"))
                    {
                        if (CamStateInfo .normalizedTime > 1)
                        {
                            Step = 1;
                            //          下一步,提前执行
           SubObj.transform.Find("Text").GetComponent<Text>().text = "二级齿轮减速器分解讲解开始";
                        }
                    }
                }
                break;
            case 1://第二步,显示字幕
                if(SubAnim)
                {
                    SubAnim.SetInteger("Subtitle", 1);
                    Step = 2;
                }
                break;
            case 2://第二步 消失字幕
                if (SubAnim)
                {
                    SubStateInfo = SubAnim.GetCurrentAnimatorStateInfo(0); 
                    if(SubStateInfo .IsName ("Base Layer.wenziShow"))
                    {
                        if(SubStateInfo .normalizedTime > 1)
                        {
                            SubAnim.SetInteger("Subtitle", 2);
                            Step = 3;
                        }
                    }
                }
                break;
            case 3://第三步 相机动画
                if(SubAnim)
                {
                    SubStateInfo = SubAnim.GetCurrentAnimatorStateInfo(0);
                    if (SubStateInfo.IsName ("Base Layer.wenziHide"))
                    {
                       
                        if(SubStateInfo.normalizedTime > 0.5f)
                        {
                            CamAnim.SetInteger("CamStep",2);
                            Step = 4;                                  SubObj.transform.Find("Text").GetComponent<Text>().text = "拆下端盖紧固螺钉";
                        }
                    }
                }
                break;
            case 4://第四步 显示字幕
                if(CamAnim)
                {
                    CamStateInfo = CamAnim.GetCurrentAnimatorStateInfo(0);
                    if(CamStateInfo .IsName ("Base Layer.CamAnim2"))
                    {
                        if(CamStateInfo .normalizedTime > 1)
                        {
                            if(SubAnim)
                            {
                                SubAnim.SetInteger("Subtitle", 1);
                                    Step = 5;
                            }
                        }
                    }
                }
                break;
            case 5://第五步,拆下端盖紧固螺钉1
                if(SubAnim)
                {
                    SubStateInfo = SubAnim.GetCurrentAnimatorStateInfo(0);
                    if (SubStateInfo.IsName("Base Layer.wenziShow"))
                    {
                        if(SubStateInfo .normalizedTime > 1)
                        {
                            for (int i = 0; i < OBJ1.Length; i++)
                            {
                               if( OBJ1[i].GetComponent<Animator>())
                                {
                          OBJ1[i].GetComponent<Animator>().enabled = true;
                                }
                            }
                            Step = 6;
                        }
                    }

四、安卓端脚本实现手指互动控制模型旋转和放大缩小

脚本需挂载到齿轮模型上:

    ***3.1.2 实现模型旋转:***
    //单指上下左右滑动屏幕旋转
   if (Input.GetMouseButton(0))
        {
            if (Input.touchCount == 1)
            {
                if (Input.GetTouch(0).phase == TouchPhase.Moved)
                {
                    Touch touch = Input.GetTouch(0);
                    Vector2 deltaPos = touch.deltaPosition;
                    transform.Rotate(Vector3.down * deltaPos.x, Space.World);
                    transform.Rotate(Vector3.right * deltaPos.y, Space.World);
                }
            }
#### 3.1.3 实现放大缩小:***
//双指缩放模型
 if (Input.touchCount == 2)
        {
            if (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved)
            {
                Vector2 temPos1 = Input.GetTouch(0).position;
                Vector2 temPos2 = Input.GetTouch(1).position;

                if (isEnLarge(oldPos1, oldPos2, temPos1, temPos2))
                {
                    float oldScale = transform.localScale.x;
                    float newScale = oldScale * 1.025f;

                    transform.localScale = new Vector3(newScale, newScale, newScale);

                }
                else
                {
                    float oldScale = transform.localScale.x;
                    float newScale = oldScale / 1.025f;

                    transform.localScale = new Vector3(newScale, newScale, newScale);
                }

                oldPos1 = temPos1;
                oldPos2 = temPos2;

            }
        }
    }
    //判断手势
    bool isEnLarge(Vector2 oP1, Vector2 oP2, Vector2 nP1, Vector2 nP2)
    {
        float length1 = Mathf.Sqrt((oP1.x - oP2.x) * (oP1.x - oP2.x) + (oP1.y - oP2.y) * (oP1.y - oP2.y));
        float length2 = Mathf.Sqrt((nP1.x - nP2.x) * (nP1.x - nP2.x) + (nP1.y - nP2.y) * (nP1.y - nP2.y));

        if (length1 < length2)
        {
            return true;
        }
        else
        {
            return false;
        }
    }  

五、系统发布与测试

测试方式:
打开程序,将识别图置于摄像机内,测试AR图像识别功能,识别之后自动进入二级齿轮减速器动画分解
在这里插入图片描述
也可以发布到安卓端就行互动测试。

六、总结
该程序对二级齿轮减速器进行了一个简单的动画分解,模拟了二级齿轮减速器的拆装 分解,让人能直观的感受到齿轮减速器分解的全过程。同时该程序运用了AR图像识别技术,基于unity完成,让我学习到了更多AR开发技术,完成过程中遇到的apk打包问题也一一解决了,收获挺多的。

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
以下是使用VuforiaUnity实现最简单的虚拟按钮的步骤: 1. 创建一个新的Unity项目,导入Vuforia插件。 2. 在Vuforia开发者门户网站上创建一个新的AR应用程序,并下载使用UnityVuforia AR应用程序包。 3. 将Vuforia AR应用程序包导入Unity项目中。 4. 在场景中添加AR相机,然后将Vuforia的Image Target添加到场景中。 5. 选中Image Target,将其Image Target Behaviour组件中的Image Target Type设置为Predefined,并选择一个预定义的图像。 6. 在场景中创建一个Cube或其他形状的游戏对象,将其作为虚拟按钮。 7. 将虚拟按钮的位置和旋转与Image Target对齐。 8. 为虚拟按钮添加一个Box Collider组件并勾选Is Trigger。 9. 为虚拟按钮添加一个新的脚本,并在脚本中实现OnClick函数。例如: ``` public class VirtualButtonScript : MonoBehaviour, IVirtualButtonEventHandler { private VirtualButtonBehaviour virtualButton; void Start() { virtualButton = GetComponent<VirtualButtonBehaviour>(); virtualButton.RegisterEventHandler(this); } public void OnButtonPressed(VirtualButtonBehaviour vb) { // 当按钮被按下时执行的代码 } public void OnButtonReleased(VirtualButtonBehaviour vb) { // 当按钮被释放时执行的代码 } } ``` 10. 在虚拟按钮的GameObject上添加Virtual Button Behaviour组件,并将其设置为使用刚刚创建的脚本。 11. 运行应用程序,并在相机中将图像目标对准预定义的图像。当虚拟按钮被按下时,OnClick函数将被调用。 这就是实现最简单的虚拟按钮所需的步骤。您可以根据自己的需求进行扩展和改进。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周周的Unity小屋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值