Virtual Reality-spel och gör din kropp en Controller! (Unity + Visual Studio + Kinect + Oculus) (9 / 11 steg)
Steg 9: Hand kontroller med Kinect
Nästa skriptet skapar vi kommer att vara den som vi använder i vårt spel tillsammans med kroppen manager skriptet. Det kommer att upptäcka tillståndet hand och utlösa rotation för vårt spel.
Hand Manager Script
Nu skapa en annan i samma mapp som skriptet manager kropp och kropp Visa manager tecken. Kalla det HandManager. Detta skript kommer att se mycket ut vår kropp View controller.
Lägg till följande från BodyView vårt HandManager skript.
använder UnityEngine;
använder System.Collections;
använder System.Collections.Generic;
använda Kinect = Windows.Kinect;
allmän klass HandManager: MonoBehaviour
{
offentliga GameObject BodyManager;
privat PlatformRotate platformRotate;
privat OVRInfinitePlayerController ovrPlayerScript;
privat InfinitePlayerController playerScript;
privat ordlista _Bodies = ny ordbok ();
privat BodyManager _BodyManager;
privat float flipTimer;
privat float flipDelay = 2;
int prevState = 0;
privat ordlista _BoneMap = ny 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 detta för 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 för Hand
{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 har vi lagt till en variabel som inte är i vårt bodyview skript som är variabeln prevState.
int prevState = 0;
Vi har variabeln att förhindra konstant roterande. I de regelbundna ingående kontrollerna av spelet vi gör går detta genom att endast aktivera rotation när nyckeln är som trycktes, upp. Med Kinect är det bra att ha en vila stat som måste uppnås om vi vill rotera eller vända igen. I vårt fall är resten någon hand stat som inte signalerar ett rotationssystem. till exempel när båda händerna är i nävarna.
I metoden Update måste vi nu lägga till följande:
void Update()
{
int state = 0;
om (BodyManager == null)
{
hemkomst.
}
_BodyManager = BodyManager.GetComponent();
om (_BodyManager == null)
{
hemkomst.
}
Kinect.Body [] data = _BodyManager.GetData();
om (data == null)
{
hemkomst.
}
Lista < ulong > trackedIds = ny lista < ulong > ();
foreach (var kroppen i data)
{
om (kroppen == null)
{
fortsätta;
}
om (kropp. IsTracked)
{
trackedIds.Add (organ. TrackingId);
}
}
Lista < ulong > knownIds = ny lista < ulong > (_Bodies.Keys);
Först ta bort ospårad organ
foreach (ulong trackingId i knownIds)
{
om (! trackedIds.Contains(trackingId))
{
Destroy(_Bodies[trackingId]);
_Bodies.Remove(trackingId);
}
}
}
Alla koden ovan är samma som kroppen Visa, vilket är bra eftersom vi redan vet hur det fungerar.
Det enda som skiljer är:
int state = 0;
Denna variabel kommer att hålla hand nuläget, och vid slutet av metoden Update, vi kommer att spara den i tidigare statens variabeln.
Nästa del av metoden update som skiljer sig är på en foreach loop.
void Update()
{
int state = 0;
om (BodyManager == null)
{
hemkomst.
}
_BodyManager = BodyManager.GetComponent ();
om (_BodyManager == null)
{
hemkomst.
}
Kinect.Body [] data = _BodyManager.GetData();
om (data == null)
{
hemkomst.
}
Lista trackedIds = ny lista ();
foreach (var kroppen i data)
{
om (kroppen == null)
{
fortsätta;
}
om (kropp. IsTracked)
{
trackedIds.Add (organ. TrackingId);
}
}
Lista knownIds = ny lista (_Bodies.Keys);
Först ta bort ospårad organ
foreach (ulong trackingId i knownIds)
{
om (! trackedIds.Contains(trackingId))
{
Destroy(_Bodies[trackingId]);
_Bodies.Remove(trackingId);
}
}
foreach (var kroppen i data)
{
om (kroppen == null)
{
fortsätta;
}
om (kropp. IsTracked)
{
Kontrollera sidan om kroppen spåras
State = CheckLeftHandState (organ. HandLeftState) + (2 * CheckRightHandState (organ. HandRightState));
}
}
}
Vi behöver skriva CheckLeftHandState och CheckRIghtHandState metoder. Dessa metoder ta parametern Kinect.HandState som motsvarar en enumerable stängd, öppen eller Lasso. Båda återkommer en int som vi kommer att ställa lika med variabeln staten att berätta spelet vad kommandot vi vill genomföra.
privata int CheckRightHandState (Kinect.HandState handState2)
{
int resultatet = 0;
växel (handState2)
{
Normal
fall Kinect.HandState.Closed:
resultat = 0;
bryta;
Stanna
fall Kinect.HandState.Open:
resultat = 0;
bryta;
Flip
fall Kinect.HandState.Lasso:
resultat = 1;
bryta;
standard:
resultat = 0;
bryta;
}
returnera resultat;
}
privata int CheckLeftHandState (Kinect.HandState handState1)
{
int resultatet = 0;
växel (handState1)
{
Normal
fall Kinect.HandState.Closed:
resultat = 0;
bryta;
Flip
fall Kinect.HandState.Open:
resultat = 3;
bryta;
Vänster
fall Kinect.HandState.Lasso:
resultat = 1;
bryta;
standard:
resultat = 0;
bryta;
}
returnera resultat;
}
Ursprungligen spelet vänt om båda händerna var i lasso tillstånd, men det är svårare att kontrollera, eftersom för en ram ena sidan kanske kännas aningen snabbare än den andra, och således spelet förutsätter vi roterar istället för att vända.
Så nu spelet: roterar rätt om höger hand ensam är i lasso tillstånd. roterar vänster om vänster hand är i lasso tillstånd. och vänder om vänster hand är öppet.
Med både CheckLeftHandState och CheckRightHandState metoder gjort vi kan gå tillbaka till metoden Update och avsluta det. Just nu behöver vi bara se om Kinect registrerar våra hand stater ordentligt. För att göra detta skapar vi en switch-sats som använder det aktuella läget och sedan kontrollerar vad var det tidigare tillståndet, att förhindra kontinuerlig rotation. Om det tidigare var en vilsam vi rotera, eller den i detta fall skriva ut till Debug-skärmen.
om (kropp. IsTracked)
{
Kontrollera sidan om kroppen spåras
State = CheckLeftHandState (organ. HandLeftState) + (2 * CheckRightHandState (organ. HandRightState));
Switch (state)
{
fall 0:
bryta;
fall 1:
Vänster
om (prevState == 0)
Debug.Log("Left");
bryta;
fall 2:
Höger
om (prevState == 0)
Debug.Log("Right");
bryta;
fall 3:
Både
om (prevState == 0)
{
Debug.Log("Both");
}
bryta;
standard:
bryta;
}
prevState = staten.
}
}
}
Okej så låt oss se om detta fungerar. Skapa en annan tomt spel objekt i din scen och kallar det HandManager. Bifoga handmanager skriptet till den. Kom ihåg att dra av BodyManager från hierarkin till platshållaren BodyManger i den HandManager granskare.
BILD 1
Kör koden i enighet.
BILD 2
Okej men vi ser fortfarande skelettet. Bra om vi avaktivera bodyView genom att markera rutan vänster hand i granskaren kan vi köra projektet igen.
BILD 3
BAM! Är där det, och du vet det är fortfarande arbeta utifrån Debugger även om du inte kan se skelettet längre!
Okej nu för att lägga till detta in i spelet. Första låt oss göra prefabricerade ur HandManager och BodyManager objekt.
BILD 4
När du har skapat dem dra kroppen Manager från hierarki till kroppen Manager Prefab du skapat. Gör samma sak med Hand Manager. Nu som prefabricerade kan vi enkelt flytta dessa objekt och funktioner i våra viktigaste spel scen!