(Unity3d)Vuforia开发基础五-模型交互
最后再来说说模型怎么交互。模型交互主要还是以下这些交互方式:
主要的交互方式包括:
1、 模型的旋转、平移和缩放
这些需要配合触屏来操作。
2、 模型的选定-射线法
模型选定之后显示高亮边框
3、 模型动画的操作
使用代码,控制模型坐标等
使用Unity3d动画系统来完成
4、 音频、文字等
使用Unity3D自带的组件完成
NGUI
5、 其他
填色板等
这里先介绍最基本的交互方式:模型的旋转、平移和缩放
如果在PC上,使用鼠标操作。
如果在移动终端上,需要结合触屏来操作。
先来分析下旋转平移的原理,主要涉及到模型和摄像头的投影矩阵。
因此,一个模型的旋转、平移和缩放主要受这两者的投影矩阵对应关系影响。改变其中一个,都会使模型发生变化。
在一般的场景中,可以改变两者,而且改变摄像头的位置是比较常用的方式,因为对于缩放比较容易,网上一大推教程,可以去看看。
但是对AR场景,由于ARCamera是不能移动的,所以只能通过改变模型本身的坐标系。
请看下面的代码:
using UnityEngine; using System.Collections; public class Move : MonoBehaviour { public Transform target; float distance = 30f; float xSpeed = 150f; float ySpeed = 150f; float yMinLimit = -180f; float yMaxLimit = 180f; float x = 0f; float y = 0f; Vector2 oldPosition1; Vector2 oldPosition2; private bool flag_Roable = true;//自动旋转标志 private System.DateTime oldTime; private System.DateTime nowTime; // Use this for initialization void Start() { transform.eulerAngles = new Vector3 (0,-90,0); Vector3 angles = transform.eulerAngles; x = angles.y; y = angles.x; if (rigidbody) { rigidbody.freezeRotation = true; } oldTime = System.DateTime.Now; } // Update is called once per frame void Update() { nowTime = System.DateTime.Now; System.TimeSpan ts1 = new System.TimeSpan(oldTime.Ticks); System.TimeSpan ts2 = new System.TimeSpan(nowTime.Ticks); System.TimeSpan ts = ts2.Subtract(ts1).Duration(); if (ts.Seconds > 8 && !Input.anyKey) { flag_Roable = true; oldTime = System.DateTime.Now; } if (Input.anyKey) { /* if (Input.touchCount == 1) { if (Input.GetTouch(0).phase == TouchPhase.Moved) { //x += Input.GetAxis("Mouse X") * xSpeed * 0.02f; //y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f; x = Input.GetAxis("Mouse X") * xSpeed ; y = Input.GetAxis("Mouse Y") * ySpeed ; transform.Rotate(Vector3.up * -x * Time.deltaTime, Space.World); transform.Rotate(Vector3.right * y * Time.deltaTime, Space.World); } }*/ if (Input.touchCount > 1) { if (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved) { Vector2 tempPosition1 = Input.GetTouch(0).position; Vector2 tempPosition2 = Input.GetTouch(1).position; if (isEnlarge(oldPosition1, oldPosition2, tempPosition1, tempPosition2)) { 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); } //备份上一次触摸点的位置,用于对比 oldPosition1 = tempPosition1; oldPosition2 = tempPosition2; } } } } bool isEnlarge(Vector2 oP1, Vector2 oP2, Vector2 nP1, Vector2 nP2) { //函数传入上一次触摸两点的位置与本次触摸两点的位置计算出用户的手势 var leng1 = Mathf.Sqrt((oP1.x - oP2.x) * (oP1.x - oP2.x) + (oP1.y - oP2.y) * (oP1.y - oP2.y)); var leng2 = Mathf.Sqrt((nP1.x - nP2.x) * (nP1.x - nP2.x) + (nP1.y - nP2.y) * (nP1.y - nP2.y)); if (leng1 < leng2) { //放大手势 return true; } else { //缩小手势 return false; } } }