Stap 9: Hand-besturingselementen met de Kinect
Het volgende script we maken zullen wij gebruiken in ons spel samen met het lichaam manager script. Het detecteert de staat van de hand en leiden tot de rotatie voor ons spel.
Hand Manager Script
Maak nu een ander script in dezelfde map als het lichaam manager script en lichaam view manager script. Noem het HandManager. Dit script zal veel lijken op ons lichaam-View-controller.
Voeg de volgende van BodyView aan ons HandManager-Script.
met behulp van UnityEngine;
met behulp van System.Collections;
met behulp van System.Collections.Generic;
met behulp van Kinect = Windows.Kinect;
openbare klasse HandManager: MonoBehaviour
{
openbare GameObject BodyManager;
privé PlatformRotate platformRotate;
privé OVRInfinitePlayerController ovrPlayerScript;
privé InfinitePlayerController playerScript;
privé woordenboek _Bodies = new Dictionary ();
privé BodyManager _BodyManager;
privé float flipTimer;
privé float flipDelay = 2;
int prevState = 0;
privé woordenboek _BoneMap = nieuwe Dictionary()
{
{Kinect.JointType.FootLeft}, Kinect.JointType.AnkleLeft,
{Kinect.JointType.AnkleLeft}, Kinect.JointType.KneeLeft,
{Kinect.JointType.KneeLeft}, Kinect.JointType.HipLeft,
{Kinect.JointType.HipLeft}, Kinect.JointType.SpineBase,
{Kinect.JointType.FootRight}, Kinect.JointType.AnkleRight,
{Kinect.JointType.AnkleRight}, Kinect.JointType.KneeRight,
{Kinect.JointType.KneeRight}, Kinect.JointType.HipRight,
{Kinect.JointType.HipRight}, Kinect.JointType.SpineBase,
{Kinect.JointType.HandTipLeft, Kinect.JointType.HandLeft}, //Need dit voor HandSates
{Kinect.JointType.ThumbLeft}, Kinect.JointType.HandLeft,
{Kinect.JointType.HandLeft}, Kinect.JointType.WristLeft,
{Kinect.JointType.WristLeft}, Kinect.JointType.ElbowLeft,
{Kinect.JointType.ElbowLeft}, Kinect.JointType.ShoulderLeft,
{Kinect.JointType.ShoulderLeft}, Kinect.JointType.SpineShoulder,
{Kinect.JointType.HandTipRight, Kinect.JointType.HandRight}, //Needthis voor Hand staat
{Kinect.JointType.ThumbRight}, Kinect.JointType.HandRight,
{Kinect.JointType.HandRight}, Kinect.JointType.WristRight,
{Kinect.JointType.WristRight}, Kinect.JointType.ElbowRight,
{Kinect.JointType.ElbowRight}, Kinect.JointType.ShoulderRight,
{Kinect.JointType.ShoulderRight}, Kinect.JointType.SpineShoulder,
{Kinect.JointType.SpineBase}, Kinect.JointType.SpineMid,
{Kinect.JointType.SpineMid}, Kinect.JointType.SpineShoulder,
{Kinect.JointType.SpineShoulder}, Kinect.JointType.Neck,
{Kinect.JointType.Neck}, Kinect.JointType.Head,
};
Nu we een variabele die niet in onze bodyview-script dat is de prevState-variabele toegevoegd.
int prevState = 0;
We hebben deze variabele om te voorkomen dat constant draaien. In de reguliere input controles van het spel dat we doen stijgt dit door enige rotatie activeren wanneer de toets die werd ingedrukt. Met de Kinect is het goed om een staat van de rest die moet worden bereikt als we willen draaien of spiegelen opnieuw. In ons geval is de rest staat elke hand die niet een rotatie signaleert; beide handen zijn wanneer bijvoorbeeld in vuisten.
Nu moeten we in de Update-methode het volgende aan toevoegen:
void Update(){ int state = 0; if (BodyManager == null) { return; } _BodyManager = BodyManager.GetComponent(); if (_BodyManager == null) { return; } Kinect.Body[] data = _BodyManager.GetData(); if (data == null) { return; } List<ulong> trackedIds = new List<ulong>(); foreach (var body in data) { if (body == null) { continue; } if (body.IsTracked) { trackedIds.Add(body.TrackingId); } } List<ulong> knownIds = new List<ulong>(_Bodies.Keys); // First delete untracked bodies foreach (ulong trackingId in knownIds) { if (!trackedIds.Contains(trackingId)) { Destroy(_Bodies[trackingId]); _Bodies.Remove(trackingId); } }}
Alle van de bovenstaande code is hetzelfde als Body weergave, die u kan helpen omdat we weten al hoe het werkt.
Het enige ding dat verschillend is is:
int state = 0;
Deze variabele zal houden van de stand van de hand, en aan het einde van de Update-methode, wij zal bewaart het in de vorige staat variabele.
Het volgende deel van de update-methode die anders is in de foreach lus.
VOID Update()
{
int status = 0;
Als (BodyManager == null)
{
terugkeer;
}
_BodyManager = BodyManager.GetComponent ();
Als (_BodyManager == null)
{
terugkeer;
}
Kinect.Body [] gegevens = _BodyManager.GetData();
Als (gegevens == null)
{
terugkeer;
}
Lijst van trackedIds = nieuwe lijst ();
foreach (var lichaam in gegevens)
{
Als (lichaam == null)
{
blijven;
}
Als (lichaam. IsTracked)
{
trackedIds.Add (body. TrackingId);
}
}
Lijst van knownIds = nieuwe lijst (_Bodies.Keys);
Eerst verwijderen ongevolgde organen
foreach (ulong trackingId in knownIds)
{
Als (! trackedIds.Contains(trackingId))
{
Destroy(_Bodies[trackingId]);
_Bodies.Remove(trackingId);
}
}
foreach (var body in data){ if (body == null) { continue; } if (body.IsTracked) { //Check Hand State if body is being Tracked state = CheckLeftHandState(body.HandLeftState) + (2*CheckRightHandState(body.HandRightState)); }}
}
We moeten de methoden CheckLeftHandState en CheckRIghtHandState te schrijven. Deze methoden nemen de Kinect.HandState-parameter die op een aftelbaar gesloten, Open of Lasso neerkomt. Beide geeft een int die we zullen gelijk is aan de variabele van de staat op het spel vertellen welk commando die wij willen uitvoeren.
private int CheckRightHandState(Kinect.HandState handState2){ int result = 0; switch (handState2) { //Normal case Kinect.HandState.Closed: result = 0; break; //Stop case Kinect.HandState.Open: result = 0; break; //Flip case Kinect.HandState.Lasso: result = 1; break; default: result = 0; break; } return result; }
private int CheckLeftHandState(Kinect.HandState handState1){ int result = 0; switch (handState1) { //Normal case Kinect.HandState.Closed: result = 0; break; //Flip case Kinect.HandState.Open: result = 3; break; //Left case Kinect.HandState.Lasso: result = 1; break; default: result = 0; break; } return result; }
Oorspronkelijk is het spel omgedraaid als beide handen waren in de lasso staat, maar dat is moeilijker te controleren, omdat voor een frame enerzijds misschien iets sneller dan de andere worden erkend, en dus het spel wordt ervan uitgegaan dat we draaien in plaats van spiegelen.
Dus nu het spel: draait rechts als alleen de rechterhand in lasso staat is; draait links als de linkerhand zich in lasso toestand; en flips als de linkerhand geopend is.
Met zowel de CheckLeftHandState als de CheckRightHandState methodes gedaan we kunnen terugkeren naar de methode Update en het afmaken. Momenteel willen we enkel zien als de Kinect onze hand-Staten goed registreert. Hiervoor maken we een instructie switch die gebruikmaakt van de huidige toestand en die vervolgens controleert wat was de vorige toestand, continue rotatie te voorkomen. Als de vorige toestand was de rustgevende vermelden we draaien, of in dit geval afdrukken naar het Debug scherm.
if (body.IsTracked){//Check Hand State if body is being Tracked state = CheckLeftHandState(body.HandLeftState) + (2*CheckRightHandState(body.HandRightState)); switch (state) { case 0: break; case 1: //Left if (prevState == 0) Debug.Log("Left"); break; case 2: //Right if (prevState == 0) Debug.Log("Right"); break; case 3: //Both if (prevState == 0) { Debug.Log("Both"); } break; default: break; } prevState = state;}}}
Oke dus laten we zien of dit werkt. Maak een andere lege doel van het spel in je scène en noemen het HandManager. Het handmanager script aan het koppelen. Vergeet niet om de BodyManager van de hiërarchie naar een tijdelijke aanduiding voor de BodyManger in de HandManager Inspector slepen.
AFBEELDING 1
Voer de code in eenheid.
AFBEELDING 2
Oke, maar we zien nog steeds het skelet. Nou, als we de bodyView deactiveren door het vakje van de linkerhand in het itemvenster kunnen we het project opnieuw uitvoeren.
AFBEELDING 3
BAM! Daar is het, en u weet dat het is nog steeds werken op basis van de Debugger, zelfs als u niet kunt het skelet niet meer zien!
Oke nu om toe te voegen dat in het spel. Eerste laten we de prefabs uit de HandManager en BodyManager objecten.
AFBEELDING 4
Als u eenmaal hebt gemaakt ze slepen de lichaam Manager uit de hiërarchie van de Prefab lichaam Manager die u hebt gemaakt. Doe hetzelfde met de Manager van de Hand. Nu als prefabs kan gemakkelijk gaan we die objecten en functionaliteit in onze belangrijkste spel scène!