프로젝트

일반

사용자정보

통계
| 개정판:

t1 / TFDContents / Assets / KinectDemos / PhysicsDemo / Scripts / BallController.cs @ 3

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

1 3 KTH
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
}