프로젝트

일반

사용자정보

통계
| 개정판:

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
}