t1 / TFDContents / Assets / KinectDemos / PhysicsDemo / Scripts / BallController.cs @ 3
이력 | 보기 | 이력해설 | 다운로드 (6.21 KB)
1 |
using UnityEngine; |
---|---|
2 |
using System.Collections; |
3 |
//using Windows.Kinect; |
4 |
|
5 |
|
6 |
public class BallController : MonoBehaviour |
7 |
{ |
8 |
[Tooltip("Index of the player, tracked by this component. 0 means the 1st player, 1 - the 2nd one, 2 - the 3rd one, etc.")] |
9 |
public int playerIndex = 0; |
10 |
|
11 |
[Tooltip("The ball game object.")] |
12 |
public Transform ballObject; |
13 |
|
14 |
[Tooltip("Minimum distance used to consider the ball being thrown.")] |
15 |
public float minThrowDistance = 0.3f; |
16 |
|
17 |
[Tooltip("Maximum time in seconds, used to consider the ball being thrown.")] |
18 |
public float timeThrowLimit = 0.3f; |
19 |
|
20 |
[Tooltip("Velocity scale.")] |
21 |
public float velocityScale = 5f; |
22 |
|
23 |
[Tooltip("GUI-Text to display information messages.")] |
24 |
public GUIText infoText; |
25 |
|
26 |
public enum BallState : int { Hidden, HandRaise, BallThrow, BallWait } |
27 |
[Tooltip("Current state of the ball.")] |
28 |
public BallState currentState = BallState.Hidden; |
29 |
|
30 |
// public Transform ballP1; |
31 |
// public Transform ballP2; |
32 |
|
33 |
//public GUIText debugText; |
34 |
|
35 |
private KinectManager manager; |
36 |
private Quaternion initialRotation = Quaternion.identity; |
37 |
|
38 |
private long userId = 0; |
39 |
private int jointIndex = -1; |
40 |
|
41 |
// variables used for throwing |
42 |
private Vector3 lowestPos; |
43 |
private Vector3 handPos1, handPos2; |
44 |
private float handTime1, handTime2; |
45 |
|
46 |
// number of hits |
47 |
private int hitPoints = 0; |
48 |
|
49 |
|
50 |
void Start() |
51 |
{ |
52 |
if (ballObject) |
53 |
{ |
54 |
initialRotation = ballObject.rotation; |
55 |
} |
56 |
|
57 |
if (infoText) |
58 |
{ |
59 |
infoText.text = "Raise hand, throw the ball and try to hit the barrel."; |
60 |
} |
61 |
} |
62 |
|
63 |
void Update () |
64 |
{ |
65 |
manager = KinectManager.Instance; |
66 |
|
67 |
if(manager && manager.IsInitialized()) |
68 |
{ |
69 |
userId = manager.GetUserIdByIndex(playerIndex); |
70 |
|
71 |
switch (currentState) |
72 |
{ |
73 |
case BallState.Hidden: |
74 |
UpdateBallHide(); |
75 |
|
76 |
// try to catch |
77 |
currentState = BallState.HandRaise; |
78 |
break; |
79 |
|
80 |
case BallState.HandRaise: |
81 |
UpdateHandRaise(); |
82 |
break; |
83 |
|
84 |
case BallState.BallThrow: |
85 |
UpdateBallThrow(); |
86 |
break; |
87 |
|
88 |
case BallState.BallWait: |
89 |
break; |
90 |
} |
91 |
} |
92 |
|
93 |
if (infoText) |
94 |
{ |
95 |
//infoText.text = currentState.ToString(); |
96 |
} |
97 |
} |
98 |
|
99 |
|
100 |
private void UpdateBallHide() |
101 |
{ |
102 |
if (ballObject) |
103 |
{ |
104 |
ballObject.position = new Vector3 (0, 0, -10); |
105 |
ballObject.rotation = initialRotation; |
106 |
|
107 |
ballObject.GetComponent<Rigidbody>().isKinematic = true; |
108 |
} |
109 |
} |
110 |
|
111 |
|
112 |
private void UpdateHandRaise() |
113 |
{ |
114 |
jointIndex = -1; |
115 |
Vector3 vLowestPos = Vector3.zero; |
116 |
Vector3 vHandPos = Vector3.zero; |
117 |
|
118 |
// check for left hand raise |
119 |
if (manager.IsJointTracked(userId, (int)KinectInterop.JointType.ShoulderRight) && manager.IsJointTracked(userId, (int)KinectInterop.JointType.HandLeft)) |
120 |
{ |
121 |
vLowestPos = GetJointPositionInv(userId, (int)KinectInterop.JointType.ShoulderRight); |
122 |
vHandPos = GetJointPositionInv(userId, (int)KinectInterop.JointType.HandLeft); |
123 |
|
124 |
if (vHandPos.y > vLowestPos.y) |
125 |
{ |
126 |
jointIndex = (int)KinectInterop.JointType.HandLeft; |
127 |
|
128 |
lowestPos = vLowestPos; |
129 |
handPos1 = vHandPos; |
130 |
handTime1 = Time.realtimeSinceStartup; |
131 |
} |
132 |
} |
133 |
|
134 |
// check for right hand raise |
135 |
if (manager.IsJointTracked(userId, (int)KinectInterop.JointType.ShoulderLeft) && manager.IsJointTracked(userId, (int)KinectInterop.JointType.HandRight)) |
136 |
{ |
137 |
vLowestPos = GetJointPositionInv(userId, (int)KinectInterop.JointType.ShoulderLeft); |
138 |
vHandPos = GetJointPositionInv(userId, (int)KinectInterop.JointType.HandRight); |
139 |
|
140 |
if (vHandPos.y > vLowestPos.y) |
141 |
{ |
142 |
jointIndex = (int)KinectInterop.JointType.HandRight; |
143 |
|
144 |
lowestPos = vLowestPos; |
145 |
handPos1 = vHandPos; |
146 |
handTime1 = Time.realtimeSinceStartup; |
147 |
} |
148 |
} |
149 |
|
150 |
if (jointIndex >= 0 && ballObject) |
151 |
{ |
152 |
ballObject.position = vHandPos; |
153 |
currentState = BallState.BallThrow; |
154 |
} |
155 |
} |
156 |
|
157 |
|
158 |
private void UpdateBallThrow() |
159 |
{ |
160 |
// check for push |
161 |
if (jointIndex >= 0 && manager.IsJointTracked (userId, jointIndex) && GetJointPositionInv(userId, jointIndex).y >= lowestPos.y) |
162 |
{ |
163 |
handPos2 = GetJointPositionInv(userId, jointIndex); |
164 |
handTime2 = Time.realtimeSinceStartup; |
165 |
|
166 |
ballObject.position = handPos2; |
167 |
|
168 |
Vector3 throwDir = handPos2 - handPos1; |
169 |
float throwDist = throwDir.magnitude; |
170 |
float throwTime = handTime2 - handTime1; |
171 |
|
172 |
if ((throwTime <= timeThrowLimit) && (throwDist >= minThrowDistance) && (handPos2.z > handPos1.z)) |
173 |
{ |
174 |
// test succeeded - ball was thrown |
175 |
float velocity = throwDist / throwTime; |
176 |
Debug.Log(string.Format("Dist: {0:F3}; Time: {1:F3}; Velocity: {2:F3}", throwDist, throwTime, velocity)); |
177 |
|
178 |
// if (ballP1) |
179 |
// ballP1.position = handPos1; |
180 |
// if (ballP2) |
181 |
// { |
182 |
// ballP2.position = handPos2; |
183 |
// ballP2.forward = throwDir.normalized; |
184 |
// } |
185 |
|
186 |
if (ballObject) |
187 |
{ |
188 |
ballObject.forward = throwDir.normalized; |
189 |
Rigidbody rb = ballObject.GetComponent<Rigidbody>(); |
190 |
|
191 |
if (rb) |
192 |
{ |
193 |
rb.velocity = throwDir * velocity * velocityScale; |
194 |
rb.isKinematic = false; |
195 |
} |
196 |
|
197 |
currentState = BallState.BallWait; |
198 |
StartCoroutine (WaitForBall()); |
199 |
} |
200 |
} |
201 |
else if ((handTime2 - handTime1) > timeThrowLimit) |
202 |
{ |
203 |
// too slow, start new test |
204 |
handPos1 = handPos2; |
205 |
handTime1 = handTime2; |
206 |
} |
207 |
} |
208 |
else |
209 |
{ |
210 |
// throw was cancelled |
211 |
currentState = BallState.Hidden; |
212 |
} |
213 |
} |
214 |
|
215 |
|
216 |
private Vector3 GetJointPositionInv(long userId, int jointIndex) |
217 |
{ |
218 |
if (manager) |
219 |
{ |
220 |
Vector3 userPos = manager.GetUserPosition(userId); |
221 |
Vector3 jointPos = manager.GetJointPosition(userId, jointIndex); |
222 |
|
223 |
Vector3 jointDiff = jointPos - userPos; |
224 |
jointDiff.z = -jointDiff.z; |
225 |
jointPos = userPos + jointDiff; |
226 |
|
227 |
return jointPos; |
228 |
} |
229 |
|
230 |
return Vector3.zero; |
231 |
} |
232 |
|
233 |
|
234 |
private IEnumerator WaitForBall() |
235 |
{ |
236 |
// wait 3 seconds |
237 |
yield return new WaitForSeconds(3f); |
238 |
|
239 |
// if (ballP1) |
240 |
// ballP1.position = new Vector3(0, 0, -10); |
241 |
// if (ballP2) |
242 |
// ballP2.position = new Vector3(0, 0, -10); |
243 |
|
244 |
// start over |
245 |
currentState = BallState.Hidden; |
246 |
} |
247 |
|
248 |
|
249 |
// invoked by BarrelTrigger-script, when the barrel was hit by the ball |
250 |
public void BarrelWasHit() |
251 |
{ |
252 |
hitPoints++; |
253 |
|
254 |
if (infoText) |
255 |
{ |
256 |
infoText.text = "Barrel hits: " + hitPoints; |
257 |
} |
258 |
} |
259 |
|
260 |
} |