프로젝트

일반

사용자정보

통계
| 개정판:

t1 / TFDContents / Assets / KinectDemos / InteractionDemo / Scripts / GrabDropScript.cs @ 3

이력 | 보기 | 이력해설 | 다운로드 (8.75 KB)

1
using UnityEngine;
2
using System.Collections;
3

    
4
public class GrabDropScript : MonoBehaviour, InteractionListenerInterface
5
{
6
	[Tooltip("List of the objects that may be dragged and dropped.")]
7
	public GameObject[] draggableObjects;
8

    
9
	[Tooltip("Material used to outline the currently selected object.")]
10
	public Material selectedObjectMaterial;
11
	
12
	[Tooltip("Drag speed of the selected object.")]
13
	public float dragSpeed = 3.0f;
14

    
15
	[Tooltip("Minimum Z-position of the dragged object, when moving forward and back.")]
16
	public float minZ = 0f;
17

    
18
	[Tooltip("Maximum Z-position of the dragged object, when moving forward and back.")]
19
	public float maxZ = 5f;
20

    
21
	// public options (used by the Options GUI)
22
	[Tooltip("Whether the objects obey gravity when released or not. Used by the Options GUI-window.")]
23
	public bool useGravity = true;
24
	[Tooltip("Whether the objects should be put in their original positions. Used by the Options GUI-window.")]
25
	public bool resetObjects = false;
26

    
27
	[Tooltip("Camera used for screen ray-casting. This is usually the main camera.")]
28
	public Camera screenCamera;
29

    
30
	[Tooltip("GUI-Text used to display information messages.")]
31
	public GUIText infoGuiText;
32

    
33
	[Tooltip("Interaction manager instance, used to detect hand interactions. If left empty, it will be the first interaction manager found in the scene.")]
34
	public InteractionManager interactionManager;
35

    
36
	// hand interaction variables
37
	//private bool isLeftHandDrag = false;
38
	private InteractionManager.HandEventType lastHandEvent = InteractionManager.HandEventType.None;
39

    
40
	// currently dragged object and its parameters
41
	private GameObject draggedObject;
42
	//private float draggedObjectDepth;
43
	private Vector3 draggedObjectOffset;
44
	private Material draggedObjectMaterial;
45
	private float draggedNormalZ;
46

    
47
	// initial objects' positions and rotations (used for resetting objects)
48
	private Vector3[] initialObjPos;
49
	private Quaternion[] initialObjRot;
50

    
51
	// normalized and pixel position of the cursor
52
	private Vector3 screenNormalPos = Vector3.zero;
53
	private Vector3 screenPixelPos = Vector3.zero;
54
	private Vector3 newObjectPos = Vector3.zero;
55

    
56

    
57
	// choose whether to use gravity or not
58
	public void SetUseGravity(bool bUseGravity)
59
	{
60
		this.useGravity = bUseGravity;
61
	}
62

    
63
	// request resetting of the draggable objects
64
	public void RequestObjectReset()
65
	{
66
		resetObjects = true;
67
	}
68

    
69

    
70
	void Start()
71
	{
72
		// by default set the main-camera to be screen-camera
73
		if (screenCamera == null) 
74
		{
75
			screenCamera = Camera.main;
76
		}
77

    
78
		// save the initial positions and rotations of the objects
79
		initialObjPos = new Vector3[draggableObjects.Length];
80
		initialObjRot = new Quaternion[draggableObjects.Length];
81

    
82
		for(int i = 0; i < draggableObjects.Length; i++)
83
		{
84
			initialObjPos[i] = screenCamera ? screenCamera.transform.InverseTransformPoint(draggableObjects[i].transform.position) : draggableObjects[i].transform.position;
85
			initialObjRot[i] = screenCamera ? Quaternion.Inverse(screenCamera.transform.rotation) * draggableObjects[i].transform.rotation : draggableObjects[i].transform.rotation;
86
		}
87

    
88
		// get the interaction manager instance
89
		if(interactionManager == null)
90
		{
91
			interactionManager = InteractionManager.Instance;
92
		}
93
	}
94

    
95

    
96
	void Update() 
97
	{
98
		if(interactionManager != null && interactionManager.IsInteractionInited())
99
		{
100
			if(resetObjects && draggedObject == null)
101
			{
102
				// reset the objects as needed
103
				resetObjects = false;
104
				ResetObjects ();
105
			}
106

    
107
			if(draggedObject == null)
108
			{
109
				// check if there is an underlying object to be selected
110
				if(lastHandEvent == InteractionManager.HandEventType.Grip && screenNormalPos != Vector3.zero)
111
				{
112
					// convert the normalized screen pos to pixel pos
113
					screenNormalPos = interactionManager.IsLeftHandPrimary() ? interactionManager.GetLeftHandScreenPos() : interactionManager.GetRightHandScreenPos();
114

    
115
					screenPixelPos.x = (int)(screenNormalPos.x * (screenCamera ? screenCamera.pixelWidth : Screen.width));
116
					screenPixelPos.y = (int)(screenNormalPos.y * (screenCamera ? screenCamera.pixelHeight : Screen.height));
117
					Ray ray = screenCamera ? screenCamera.ScreenPointToRay(screenPixelPos) : new Ray();
118

    
119
					// check if there is an underlying objects
120
					RaycastHit hit;
121
					if(Physics.Raycast(ray, out hit))
122
					{
123
						foreach(GameObject obj in draggableObjects)
124
						{
125
							if(hit.collider.gameObject == obj)
126
							{
127
								// an object was hit by the ray. select it and start drgging
128
								draggedObject = obj;
129
								draggedObjectOffset = hit.point - draggedObject.transform.position;
130
								draggedObjectOffset.z = 0; // don't change z-pos
131

    
132
								draggedNormalZ = (minZ + screenNormalPos.z * (maxZ - minZ)) - 
133
									draggedObject.transform.position.z; // start from the initial hand-z
134
								
135
								// set selection material
136
								draggedObjectMaterial = draggedObject.GetComponent<Renderer>().material;
137
								draggedObject.GetComponent<Renderer>().material = selectedObjectMaterial;
138

    
139
								// stop using gravity while dragging object
140
								draggedObject.GetComponent<Rigidbody>().useGravity = false;
141
								break;
142
							}
143
						}
144
					}
145
				}
146
				
147
			}
148
			else
149
			{
150
				// continue dragging the object
151
				screenNormalPos = interactionManager.IsLeftHandPrimary() ? interactionManager.GetLeftHandScreenPos() : interactionManager.GetRightHandScreenPos();
152
				
153
				// convert the normalized screen pos to 3D-world pos
154
				screenPixelPos.x = (int)(screenNormalPos.x * (screenCamera ? screenCamera.pixelWidth : Screen.width));
155
				screenPixelPos.y = (int)(screenNormalPos.y * (screenCamera ? screenCamera.pixelHeight : Screen.height));
156
				//screenPixelPos.z = screenNormalPos.z + draggedObjectDepth;
157
				screenPixelPos.z = (minZ + screenNormalPos.z * (maxZ - minZ)) - draggedNormalZ -
158
					(screenCamera ? screenCamera.transform.position.z : 0f);
159

    
160
				newObjectPos = screenCamera.ScreenToWorldPoint(screenPixelPos) - draggedObjectOffset;
161
				draggedObject.transform.position = Vector3.Lerp(draggedObject.transform.position, newObjectPos, dragSpeed * Time.deltaTime);
162
				
163
				// check if the object (hand grip) was released
164
				bool isReleased = lastHandEvent == InteractionManager.HandEventType.Release;
165

    
166
				if(isReleased)
167
				{
168
					// restore the object's material and stop dragging the object
169
					draggedObject.GetComponent<Renderer>().material = draggedObjectMaterial;
170

    
171
					if(useGravity)
172
					{
173
						// add gravity to the object
174
						draggedObject.GetComponent<Rigidbody>().useGravity = true;
175
					}
176

    
177
					draggedObject = null;
178
				}
179
			}
180
		}
181
	}
182

    
183

    
184
	void OnGUI()
185
	{
186
		if(infoGuiText != null && interactionManager != null && interactionManager.IsInteractionInited())
187
		{
188
			string sInfo = string.Empty;
189
			
190
			long userID = interactionManager.GetUserID();
191
			if(userID != 0)
192
			{
193
				if(draggedObject != null)
194
					sInfo = "Dragging the " + draggedObject.name + " around.";
195
				else
196
					sInfo = "Please grab and drag an object around.";
197
			}
198
			else
199
			{
200
				KinectManager kinectManager = KinectManager.Instance;
201

    
202
				if(kinectManager && kinectManager.IsInitialized())
203
				{
204
					sInfo = "Waiting for Users...";
205
				}
206
				else
207
				{
208
					sInfo = "Kinect is not initialized. Check the log for details.";
209
				}
210
			}
211
			
212
			infoGuiText.text = sInfo;
213
		}
214
	}
215

    
216

    
217
	// reset positions and rotations of the objects
218
	private void ResetObjects()
219
	{
220
		for(int i = 0; i < draggableObjects.Length; i++)
221
		{
222
			draggableObjects[i].GetComponent<Rigidbody>().useGravity = false;
223
			draggableObjects[i].GetComponent<Rigidbody>().velocity = Vector3.zero;
224

    
225
			draggableObjects[i].transform.position = screenCamera ? screenCamera.transform.TransformPoint(initialObjPos[i]) : initialObjPos[i];
226
			draggableObjects[i].transform.rotation = screenCamera ? screenCamera.transform.rotation * initialObjRot[i] : initialObjRot[i];
227
		}
228
	}
229

    
230

    
231
	public void HandGripDetected(long userId, int userIndex, bool isRightHand, bool isHandInteracting, Vector3 handScreenPos)
232
	{
233
		if (!isHandInteracting || !interactionManager)
234
			return;
235
		if (userId != interactionManager.GetUserID())
236
			return;
237

    
238
		lastHandEvent = InteractionManager.HandEventType.Grip;
239
		//isLeftHandDrag = !isRightHand;
240
		screenNormalPos = handScreenPos;
241
	}
242

    
243
	public void HandReleaseDetected(long userId, int userIndex, bool isRightHand, bool isHandInteracting, Vector3 handScreenPos)
244
	{
245
		if (!isHandInteracting || !interactionManager)
246
			return;
247
		if (userId != interactionManager.GetUserID())
248
			return;
249

    
250
		lastHandEvent = InteractionManager.HandEventType.Release;
251
		//isLeftHandDrag = !isRightHand;
252
		screenNormalPos = handScreenPos;
253
	}
254

    
255
	public bool HandClickDetected(long userId, int userIndex, bool isRightHand, Vector3 handScreenPos)
256
	{
257
		return true;
258
	}
259

    
260

    
261
}