原文链接:http://www.arvrschool.com/read.php?tid=22
ARVR技术交流群:129340649
模型交互主要还是以下这些交互方式:
主要的交互方式包括:1、模型的旋转、平移和缩放
这些需要配合触屏来操作。
2、模型的选定-射线法
模型选定之后显示高亮边框
3、模型动画的操作
使用代码,控制模型坐标等
使用Unity3d动画系统来完成
4、音频、文字等
使用Unity3D自带的组件完成
NGUI
5、其他
填色板等
这里先介绍最基本的交互方式:模型的旋转、平移和缩放
如果在PC上,使用鼠标操作。
如果在移动终端上,需要结合触屏来操作。
先来分析下旋转平移的原理,主要涉及到模型和摄像头的投影矩阵。
因此,一个模型的旋转、平移和缩放主要受这两者的投影矩阵对应关系影响。改变其中一个,都会使模型发生变化。
在一般的场景中,可以改变两者,而且改变摄像头的位置是比较常用的方式,因为对于缩放比较容易,网上一大推教程,可以去看看。
但是对AR场景,由于ARCamera是不能移动的,所以只能通过改变模型本身的坐标系。
请看下面的代码:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
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 ; } } } |