Denna handledning kommer att lära dig hur man bygger ett knock-down-spel med Unity3D! Längs vägen kommer du att lära dig om vikten av att använda en fysikmotor och hur man gör det kommer att spara otaliga timmar med manuell animering. Läs vidare!
Vilken modern spelmotor skulle vara komplett utan en fysikmotor? Varje nuvarande spelmotor, antingen 3D eller 2D, har ett fysikbibliotek av något slag, och Unity är inget undantag. Realtime fysik är idealisk för att simulera komplexa interaktioner mellan objekt i ditt spel. En fysikmotor kan spara mycket av manuell kodning och animering för att uppnå en realistisk rörelse, kan göra att detekterar en bris i en träff och kan snabbt introducera en mängd nya spelmekanismer till dina spel.
I denna handledning använder vi fysikmotorn i Unity för att bygga ett 3D-knockdown-spel som liknar BoomBlox och Angry Birds. Vi lär oss att ge objekt olika fysikaliska egenskaper, göra dem kapabla att kollidera och till och med tillåta dem att förstöras om kollisionerna är tillräckligt starka.
En fysikmotor fungerar genom att simulera hur objekten reagerar med varandra när krafter appliceras på dem. Dessa krafter kan vara konstanta, som gravitation eller momentum i ett fordon, medan andra är korta och kraftfulla, som explosioner. En fysiksimulering kallas ibland en "sandbox" eftersom endast objekt inom simuleringen påverkas. Faktum är att inte alla föremål i ditt spel behöver vara en del av simuleringen. Detta är viktigt eftersom spelarrörelser ofta behöver vara orealistiska samtidigt som de reagerar realistiskt på kollisioner.
Colliders är vilka fysikmotorer som använder för att utföra träffdetektering. Till skillnad från maskobjekt, vet de när de kommit i kontakt med varandra. De är enkla former som lådor, sfärer eller kapslar som tilldelas dina GameObjects och följer dem runt. Du kan tänka på dem som något av ett "kraftfält".
Bekvämt, när ett GameObject skapas, tilldelas det automatiskt en lämplig collider. En kub får en BoxCollider, en sfär får en SphereCollider, en cylinder får en CapsuleCollider och så vidare.
Vi behöver så småningom några block att slå ner:
Om vi trycker på Spela, kommer blocket inte göra någonting. Medan den har en collider saknar den en stel kropp, så den påverkas inte av några fysiska krafter.
En stel kropp är det mest kritiska elementet i en fysikmotor. Varje GameObject det är anslutet till ingår i simuleringen.
Som standard påverkas en stel kropp av tyngdkraften och luftmotståndet, även känt som drag. Om vi trycker på Play, kommer blocket att falla, accelerera och så småningom träffa terminalhastigheten när tyngdkraften och draget utjämnar.
Vi måste skapa några fler element för att bygga en riktig nivå. Låt oss först lägga till en mark så att blocket har något att landa på.
Marken kommer automatiskt att ges en MeshCollider som förhindrar att styva ämnen passerar genom den. Tryck på Play och blocken ska falla och slå sig upp på marken.
Nu behöver vi en struktur för att slå ner. Välj Block och tryck på Ctrl + D i Windows, eller Cmd + D i OSX, för att duplicera blocket några gånger. Använd skalan och flytta verktygen för att sträcka och placera blocken i ungefär samma konfiguration som bilden nedan.
NOTERA: Det är en bra idé att använda exakta siffror för dina omvandlingar. Block bör ligga mot varandra, men inte överlappa varandra. Överlappningar kommer att få fysikmotorn att freak out och göra oförutsägbara saker.
Nu när vi har skapat vår vackra struktur, låt oss skriva ett manus som tillåter oss att flytta kameran så att vi kan beundra vår skapelse från alla vinklar.
Följande skript kommer att leda till att kameran kretsar runt i mitten av världen, liksom lutar upp och ner:
offentlig klass Cannon: MonoBehaviour void LateUpdate () float x = Input.GetAxis ("Mouse X") * 2; float y = -Input.GetAxis ("Mouse Y"); // vertikal lutningsflotta yClamped = transform.eulerAngles.x + y; transform.rotation = Quaternion.Euler (yClamped, transformer.eulerAngles.y, transformer.eulerAngles.z); // horisontell bana transform.RotateAround (ny Vector3 (0, 3, 0), Vector3.up, x);
Som en sista touch, låt oss göra det enklare att sikta genom att lägga en crosshair till vår kamera:
Att kunna titta på vår struktur är okej, men det här är tänkt att handla om fysik! Vi behöver ett sätt att slå ner det för att se fysiken i aktion. Vad vi behöver är något att skjuta!
Eftersom vi kommer att skjuta kanonkulor direkt från kameran kan vi redigera vårt befintliga kanonskript. Först lägger vi till ett offentligt attribut i toppen av klassen för vår prefabrikerade projektil.
offentlig klass Cannon: MonoBehaviour public GameObject projectilePrefab;
Vi lägger till en FixedUpdate-metod för att lyssna på "Fire1" -knappen som ska tryckas och sedan inställa en Cannonball prefab, placera den i kameran och lägg sedan en kraft till den för att flytta den framåt.
void FixedUpdate () if (Input.GetButtonDown ("Fire1")) GameObject projectile = Instantiate (projectilePrefab, transform.position, transform.rotation) som GameObject; projectile.rigidbody.AddRelativeForce (ny Vector3 (0, 0, 2000));
Du kanske har märkt att om en kanonkula är avfyrade tillräckligt mycket, kan den falla utanför kanten av vårt markplan. Denna kanonkula kommer att fortsätta att existera så länge spelet fortsätter att springa och dess fysik fortsätter att beräknas, så småningom sakta ner det. Vi måste skapa en gräns runt nivån och förstöra alla spelobjekt som lämnar denna gräns.
Nu måste vi skapa det manus som kommer att förstöra och föremål som strider utanför gränsen.
allmän klass Gräns: MonoBehaviour void OnTriggerExit (Collider andra) Destroy (other.gameObject);
Vi behöver ett sätt att vinna vår nivå. För att göra detta måste våra block förstöras om de tar tillräckligt med skador från påverkan.
I manuset ger vi prefaben en folkhälsa som kan anpassas i redaktören. Detta gör att olika block kan ha olika mängder hälsa.
offentlig klass Block: MonoBehaviour public float health = 20;
När en kollision detekteras mäts effektens storlek. Ju större omfattning desto mer skada som gjordes. Allt ovanför en ljuskran subtraheras från blockets hälsa. Om blockets hälsa faller under 0, förstör blocket sig. Det kontrollerar sedan för att se hur många andra block som finns kvar i scenen. Om det bara finns ett block kvar, är spelet över och det laddar om scenen för att spela igen.
void OnCollisionEnter (Kollisionskollision) // tillämpa kollisionskador om (collision.relativeVelocity.magnitude> 0.5) health - = collision.relativeVelocity.magnitude; // förstör om hälsan är för låg om (hälsa <= 0) Destroy(gameObject); // restart the scene if this was the last box GameObject[] boxes = GameObject.FindGameObjectsWithTag("Box"); if (boxes.Length <= 1) Application.LoadLevel("Main");
Hittills har vi bara använt träblock. De är lätta och relativt svaga, vilket gör strukturen för lätt att förstöra och ganska förutsägbar i hur den kommer att röra sig. Vi måste skapa en annan typ av block, en som är både tyngre och starkare.
Prova att byta ut några av korsdelarna med betongblock. Betongblocken ska vara svårare att slå över, falla med stor inverkan och vara svårare att förstöra med kanonkulor.
Nedan är det färdiga spelet som körs i Unity Web Player. Använd musen för att bana om kameran och tryck Ctrl eller Vänster musknapp för att skjuta kanonkulor.
Denna handledning skrapar bara ytan på vad Unity Physics Engine kan. Konstantiska krafter, explosiva krafter, fysiska material, gångjärn, fjädrar, ragdollar osv. Även om det här kan tyckas skrämmande passar elementen i Unity Physics-motorn alla, vilket gör det lätt att förstå och enkelt implementera fysik i dina spel.
För att lära dig mer om egenskaperna hos Unity Physics-motorn, besök:
http://docs.unity3d.com/Documentation/Manual/Physics.html