Στην άσκηση αυτή θα εξοικειωθείτε με τη βασική διαχείριση οντοτήτων μέσω εφαρμοζόμενων scripts στο περιβάλλον Unity 3D, σχεδιάζοντας τις βασικές οντότητες, αποδίδοντας τους ιδιότητες υλικού και προγραμματίζοντας τη λειτουργία τους ανάλογα με την είσοδο που δίνει ο χρήστης μέσω του πληκτρολογίου. Ο στόχος είναι η υλοποίηση ενός διαδραστικού ανταγωνιστικού παιχνιδιού τύπου "φλιπερ" μεταξύ υπολογιστή και χρήστη, με την παράλληλη ένδειξη εναλλαγής των μετρούμενων πόντων για κάθε παίχτη. Ας ξεκινήσουμε λοιπόν την υλοποίηση! Βασικές εισαγωγικές έννοιες Το λογισμικό Unity υποστηρίζει scripts για προγραμματισμό παιχνιδιών στις γλώσσες C++ και Java. Η λέξη προγραμματισμός δεν πρέπει να "τρομάζει", μιας και είναι αρκετά εύκολο για τους χρήστες του λογισμικού να προσαρμοστούν στη δομή κα τις εντολές στην αντίστοιχη γλώσσα αν έχουν κατανοήσει το μηχανισμό δημιουργίας και εφαρμογής τμημάτων κώδικα σε αντικείμενα και έχουν στο μυαλό τους το πλάνο λειτουργικότητας του εκάστοτε παιχνιδιού. Ένας εύχρηστος οδηγός εκμάθησης είναι το περιβάλλον C# Language Primer Microsoft. Κάποιος που έχει γνώσεις προγραμματισμού, μπορεί πολύ εύκολα να προσαρμοστεί στους συντακτικούς και γραμματικούς κανόνες της κάθε γλώσσας, καθώς και στις διαθέσιμες συναρτήσεις μέσω των αντίστοιχων βιβλιοθηκών. Η βασική ιδέα του αντικειμενοστραφούς προγραμματισμού (object oriented programming) είναι πως τα παραγόμενα προγράμματα αποτελούνται από δομικές μονάδες που ονομάζονται αντικείμενα, κάθε ένα από τα οποία διαθέτει τις δικές του ιδιότητες, μεταβλητές και συναρτήσεις, μέσω των οποίων μπορεί να αλληλεπιδρά με άλλα αντικείμενα. Τα αντικείμενα (Objects) προέρχονται από κλάσεις (classes), δηλαδή δομές-αρχεία τα οποία "δηλώνουν" τα χαρακτηριστικά τους. Στο περιβάλλον της Unity 3D, είναι πολύ εύκολη διαδικασία να εφαρμοστεί/συνδεθεί κώδικα (script) σε/με ένα αντικείμενο της σκηνής μέσω του κουμπιού Add component που βρίσκεται κάτω δεξιά στο περιβάλλον εργασίας: Πρώτα επιλέγουμε το αντικείμενο της σκηνής στο οποίο θέλουμε να εφαρμοστεί το script και μέσω της εργαλειοθήκης inspector κάνουμε κλικ στο κουμπί. Then, click on the Add Component. Επιλέγουμε new script, δίνουμε ένα όνομα και πατάμε το κουμπί create and add. Στην περιοχή Assets εμφανίζεται ένα νέο "αντικείμενο-αρχείο", το οποίο αποτελεί το τμήμα κώδικα που δημιουργήθηκε. Κάνοντας διπλό κλικ πάνω του, μπορούμε να το επεξεργαστούμε μέσω του ενσωματωμένου editor του λογισμικού Unity 3D Δημιουργία διαδραστικού παιχνιδιού υπολογιστή-χρήστη - Βασικές Ρυθμίσεις - Λιβανός Γ. Σελίδα 1
H δομή ενός αρχείου class π.χ. για τον έλεγχο της κατάστασης υγείας ενός παίχτη θα ήταν η ακόλουθη: using UnityEngine; public class Mook : MonoBehaviour { private float health; void Start () { health = 100; } } void Update() { if (health > 0) { //search for player //if you encounter the player on the road, kill him //if you get shot, remove a random amount of health } } Ας εξηγήσουμε λίγο τα εμπλεκόμενα στοιχεία: using UnityEngine; -Η γραμμή αυτή καθορίζει στη γλώσσα C τη χρήση της συγκεκριμένης βιβλιοθήκης της Unity που περιέχει τη "αναπαραγωγής" του παιχνιδιού". public class Mook : MonoBehaviour - Ορίζεται μια κλάση τύπου MonoBehaviour με το όνομα ( Mook ) private float health; -Ορίζεται μια private μεταβλητή κλάσης (class variable) η οποία μπορεί να χρησιμοποιηθεί μόνο από τα στοιχεία εντός της κλάσης void Start () - Ορίζεται η "ειδική" μέθοδος Start, οποία τρέχει μόνο μια φορά (στην αρχή του παιχνιδιού) κι ουσιαστικά καθορίζει την κατάσταση εκκίνησης του παιχνιδιού (π.χ. θέσεις αντικειμένων, χρώμα φόντου, κλπ) void Update() - Άλλη μια ειδική μέθοδος, η οποία όμως είναι η πιο βασική γιατί "τρέχει" συνέχεια, σε κάθε frame και εντός των ορίων της (ο χώρος ανάμεσα στα σύμβολα {}) γράφεται ο κώδικας που θα καθορίζει την εξέλιξη του παιχνιδιού! // -> Οι γραμμές που ξεκινούν με αυτά τα σύμβολα είναι σχόλια, βοηθητικά λόγια για τον προγραμματιστή, τα οποία όμως αγνοούνται τελείως από τον Compiler. Εκτός από την παραπάνω βασική δομή, ο προγραμματιστής μπορεί να δηλώσει δικές του μεθόδους, δίνοντας δική του ονομασία και χρησιμοποιώντας μεταβλητές που θα ορίσει και θα χρησιμοποιήσει ο ίδιος με δικό του τρόπο. Είναι σημαντικό να μπορούμε να καταλαβαίνουμε ποιες μέθοδοι και μεταβλητές είναι του λογισμικού και ποιες προέρχονται από τον προγραμματιστή-χρήστη. Δημιουργία διαδραστικού παιχνιδιού υπολογιστή-χρήστη - Βασικές Ρυθμίσεις - Λιβανός Γ. Σελίδα 2
Για παράδειγμα η παρακάτω συνάρτηση δηλώνεται από το χρήστη και υλοποιεί την πρόσθεση δύο αριθμών: public float addtwonumbers(float a, float b){ return a+b; } float result = addtwonumbers(1,2); myclass instance; float result = instance.addtwonumbers(1, 2); υλοποιήθηκε σε μια άλλη κλάση Πρωτότυπο συνάρτησης Κλήση συνάρτησης Κλήση συνάρτησης που Σημαντικό επίσης είναι να καταλάβουμε πως αν η μέθοδος έχει συνδεθεί με ένα αντικείμενο με ειδικές ιδιότητες οι οποίες δεν μπορούν να προσπελαστούν από την έτοιμη μέθοδο/συνάρτηση GameObject, τότε μπορεί να χρησιμοποιηθεί η εξειδικευμένη μέθοδος GetComponent: GetComponent<ParticleSystem>().Play(); Προκειμένου να περάσουμε στο δημιουργικό κομμάτι, ας θυμηθούμε πάλι τις εργαλειοθήκες του περιβάλλοντος Unity 3D. Στην άσκηση αυτή θα υλοποιηθεί ένα απλό, διαδραστικό παιχνίδι μεταξύ υπολογιστή-χρήστη,κατά το οποίο δύο μπάρες ελέγχου που ανεβοκατεβαίνουν προσπαθούν να ανταλλάξουν "μπαλιές" με σκοπό η μία να προλαβαίνει τις επιστροφές μπάλας της άλλης. Αξίζει τον κόπο να δείτε στο ακόλουθο σύνδεσμο Pong, πώς αυτό το παιχνίδι μπορεί να κατασκευαστεί με τεχνικά μέσα, προγραμματίζοντας ένα μικροελεγκτή. Δημιουργία διαδραστικού παιχνιδιού υπολογιστή-χρήστη - Βασικές Ρυθμίσεις - Λιβανός Γ. Σελίδα 3
Πώς θα σχεδιάζατε τα αντικείμενα στη σκηνή; Χρειαζόμαστε: Τα δύο αντικείμενα-ρακέτες μέσω των οποίων θα γίνεται η ανταλλαγή "μπαλιών" (cubes) Τη μπάλα (sphere) Ένα μηχανισμό για να επανεκκινεί τη μπάλα στη θέση της Ένα αντικείμενο για να συγκρατεί τη μπάλα από το να ξεφύγει προς τα πάνω (cube) Ένα αντικείμενο κειμένου στο οποίο θα μετράται το σκορ της "αναμέτρησης" (3D text) Αντικείμενα particles ώστε να δημιουργηθεί ένα συνοδευτικό εντυπωσιακό εφέ μαζί με την κίνηση της μπάλας (Particle System) Επιγραμματικά, τα βήματα σχεδίασης είναι τα ακόλουθα: Εισαγωγή κύβου Μεταβολή μεγέθους κύβου δημιουργία διπλότυπου εισαγωγή σφαίρας ανάμεσα στους κύβους Εισαγωγή κειμένου Δημιουργία διαδραστικού παιχνιδιού υπολογιστή-χρήστη - Βασικές Ρυθμίσεις - Λιβανός Γ. Σελίδα 4
Εισαγωγή particles και προσάρτησή τους στους δύο κύβους Ρύθμιση κάμερας ώστε το οπτικό της πεδίο να περιλαμβάνει όλα τα αντικείμενα της σκηνής Δημιουργία δύο επιπλέον αντικειμένων για οριοθέτηση της κίνησης πάνω-κάτω. Προκειμένου τα αντικείμενα αυτά να είναι αόρατα κατά την αναπαραγωγή του παιχνιδιού, απενεργοποιήστε την επιλογή mesh renderer στην καρτέλα inspector. Δημιουργία διαδραστικού παιχνιδιού υπολογιστή-χρήστη - Βασικές Ρυθμίσεις - Λιβανός Γ. Σελίδα 5
Η σχεδίαση ολοκληρώθηκε! Τι θα συμβεί αν πατήσουμε το κουμπί Play; Τίποτα! Απλά θα βλέπουμε τη σκηνή με τα αντικείμενα αλλά δεν θα υπάρχει αλληλεπίδραση αφού δεν έχουμε "προγραμματίσει" τη λειτουργία των αντικειμένων μέσω κώδικα! Σύνδεση αντικειμένων με κώδικα Μόλις ολοκληρώσετε τη δημιουργία ενός script, αυτό θα εμφανιστεί στο περιβάλλον της καρτέλας Assets (στο κάτω μέρος) και κάνοντας διπλό κλικ στο όνομα του αρχείου που περιέχει τον κώδικα μεταφέρεστε αυτόματα στον ενσωματωμένο editor της Unity (Monodevelop). Οι λέξεις κλειδιά για τη γλώσσα προγραμματισμού εμφανίζονται με μπλε γράμματα και μέσω αυτού του editor μπορείτε να κάνετε όποιες αλλαγές θέλετε, να προσθέστε ή να αφαιρέστε λειτουργικότητα. Για τον έλεγχο λαθών μπορείτε να πατήστε το κουμπί build. Δημιουργία διαδραστικού παιχνιδιού υπολογιστή-χρήστη - Βασικές Ρυθμίσεις - Λιβανός Γ. Σελίδα 6
Για τη σωστή σύνδεση λειτουργικότητας και αντικειμένου, χρειάζεται προσοχή στα ονόματα των αντικειμένων και των συναρτήσεων που χρησιμοποιούνται. Η λίστα συστατικών (elements) που μπορεί να έχει ένα αντικείμενο είναι οι εξής: Transform (Ελέγχει τις ιδιότητες θέσης ενός αντικειμένου) Cube (Mesh Filter) (Ελέγχει τις ιδιότητες πλέγματος ενός αντικειμένου) Box Collider (Ελέγχει τις ιδιότητες επαφής ενός αντικειμένου με ένα άλλο) Mesh Renderer (Ελέγχει τις ιδιότητες απόδοσης/εμφάνισης ενός αντικειμένου κατά την αναπαραγωγή της σκηνής) transform.position = newpositionvector3; transform.rotation = newrotationquaternion; transform. localscale = newscalevector3; transform.rotation = Quaternion.Euler(pitch, yaw, roll); Διαχείριση θέσης transform.position = Vector3.Slerp(startPositionVector3, newdestinationvector3, 1); renderer.enabled = false; renderer.material.color = new Color(0, 255, 0); renderer.material. maintexture = mytexture; renderer.material.shader = newshader; Διαχείριση εμφάνισης Για τον έλεγχο κίνησης μέσω της εφαρμογής ιδιοτήτων κινηματικής και φυσικής υπάρχει μια ενσωματώμενη μηχανή στη Unity (βλέπε physics engine ) μέσω της οποίας μπορεί να γίνει ο έλεγχος της φυσικής κίνησης. Παραδείγματα: rigidbody.angulardrag = 0.1f; rigidbody.mass = 100; rigidbody.iskinematic = false; rigidbody. usegravity = true; rigidbody.addforce(transform.forward * 100); Για τον έλεγχο επαφής μεταξύ αντικειμένων υπάρχει πάλι αντίστοιχη μέθοδος πρόσβασης και προγραμματισμού της λειτουργικότητας void OnCollisionEnter(Collision other){ //do things here } Για τον πολύ βασικό έλεγχο εισόδου/εξόδου ώστε να υπάρχει ανάδραση κι αλληλεπίδραση με το χρήστη υπάρχουν οι κατάλληλες μέθοδοι ελέγχου ποντικιού και πληκτρολογίου: Vector3 mousepos = Input.mousePosition; bool isleftclicking = Input.GetMouseButton(0); bool is-pressingspace = Input.GetKey(KeyCode.Space); Δημιουργία διαδραστικού παιχνιδιού υπολογιστή-χρήστη - Βασικές Ρυθμίσεις - Λιβανός Γ. Σελίδα 7
Προγραμματισμός του παιχνιδιού Για τον προγραμματισμό του παιχνιδιού χρειάζεστε τον αντίστοιχο κώδικα για κάθε αντικείμενο: BallHandler.cs -> Σύνδεση με το αντικείμενο - "μπάλα" PaddleHandler.cs -> Σύνδεση με το αντικείμενο - "παίχτης/χρήστης" EnemyAI.cs -> Σύνδεση με το αντικείμενο - "παίχτης/υπολογιστής" ScoreboardUpdater.cs -> Σύνδεση με το αντικείμενο - "πίνακας σκορ" Η σύνδεση των αρχείων με τα αντικείμενα μπορεί να γίνει και σε λειτουργία drag and drop, όπως και στην απόδοση υλικού, είτε με τον τρόπο που αναλύθηκε στη σελίδα 1! Δημιουργία διαδραστικού παιχνιδιού υπολογιστή-χρήστη - Βασικές Ρυθμίσεις - Λιβανός Γ. Σελίδα 8
Απομένουν μερικές βασικές ρυθμίσεις ακόμη! Η αντιστοίχηση αντικειμένου με κώδικα δε συνεπάγεται τη λειτουργική συμπεριφορά και προγραμματισμό της κίνησής του. Για να μπορέσει ένα στοιχείο - component να συμπεριφερθεί κινησιολογικά ακολουθώντας τους κανόνες της φυσικής, θα πρέπει να αποκτήσει τις κατάλληλες ιδιότητες. Αυτό θα γίνει με δύο τρόπους: απόδοση ιδιότητας φυσικής κίνησης μέσω του μενού Component -> Physics -> Rigidbody, οπότε και είναι η δυνατή η ρύθμιση ταχύτητας, επιτάχυνσης, κλπ. απόδοση ιδιότητας φυσικού υλικού μέσω των ενεργειών δεξί κλικ στο Assets Window -> Create -> Physic material, οπότε και είναι δυνατή η ρύθμιση ελαστικότητας, βαρύτητας, κύλισης, κλπ Τα συστατικά/χαρακτηριστικά (elements) rigidbody και transform είναι διαθέσιμα στην εργαλειοθήκη Inspector και προσβάσιμα στον κώδικα, όπου και μπορούν να ελέγχονται/προγραμματίζονται ανάλογα με τις ανάγκες του παιχνιδιού και το χειρισμό των αντικειμένων κατά τη διάρκεια του παιχνιδιού. Αντικείμενο - "μπάλα" Κώδικας που "ελέγχει" τη μπάλα έλεγχος θέσης έλεγχος επιτάχυνσης και ταχύτητας Δημιουργία διαδραστικού παιχνιδιού υπολογιστή-χρήστη - Βασικές Ρυθμίσεις - Λιβανός Γ. Σελίδα 9
Στην καρτέλα rigidbody, αξίζει να παρατηρήσουμε τις εξής δύο παραμέτρους/επιλογές: 1. την παράμετρο/επιλογή Use Gravity,η οποία καθορίζει αν το αντικείμενο θα ακολουθεί το νόμο της βαρύτητας κατά την κίνηση ή όχι (π.χ. αν είναι σε ύψος να αρχίσει να πέφτει) 2. την παράμετρο/επιλογή Is kinematic, η οποία καθορίζει αν το κινούμενο αντικείμενο θα καθορίζει τα χαρακτηριστικά ενός αντικειμένου με το οποίο συγκρούεται ή όχι (για παράδειγμα τα δύο αντικείμενα - παίχτες πρέπει να οριστούν kinematic γιατί καθορίζουν την κατεύθυνση της μπάλας όταν αυτή "ανακλαστεί" πάνω τους) Στα τρία κινούμενα αντικείμενα της σκηνής εφαρμόστε το στοιχείο rigidbody ως εξής: αντικείμενο-μπάλα: απενεργοποιημένες οι επιλογές Is kinematic και Use Gravity αντικείμενα παίχτες: απενεργοποιημένη η επιλογή Use Gravity και ενεργοποιημένη η επιλογή Is kinematic Και στα τρία αντικείμενα εφαρμόστε (αφού το δημιουργήσετε) το ίδιο φυσικό υλικό (physic material) με τις ιδιότητες που φαίνονται στο σχήμα. Μένει μια τελευταία κίνηση, η αντιστοίχηση public variables για όποια scripts τις περιέχουν με τα αντικείμενα της σκηνής που θα ελέγχουν: Δημιουργία διαδραστικού παιχνιδιού υπολογιστή-χρήστη - Βασικές Ρυθμίσεις - Λιβανός Γ. Σελίδα 10
Building / Compiling Σχεδίαση διαδραστικών παιχνιδιών στο περιβάλλον Unity 3D Για να "τρέξει" το παιχνίδι απαιτείται ο κώδικας να μην περιέχει λάθη (συντακτικά αλλά και λογικά)! Για αυτό θα χρειαστεί να ελέγξετε τις συνθήκες ελέγχου if-else εντός κάθε αρχείου κώδικα και να προσαρμόσετε τις αλλαγές θέσεων σύμφωνα με τις συντεταγμένες που έχετε τοποθετήσει τα αντικείμενα μέσα στη σκηνή. Μόλις αυτό εξασφαλιστεί επιλέγετε Build Settings από το μενού File ή πατάτε το συνδυασμό Ctrl-Shift-B, οπότε εμφανίζεται το ακόλουθο πλαίσιο διαλόγου ώστε να τρέξετε την υλοποίηση και να ορίσετε το φάκελο αποθήκευσης του εκτελέσιμου αρχείου και των απαιτούμενων δεδομένων! Εναλλακτικά, μπορείτε να πατήσετε το κουμπί Play στην καρτέλα Game. Δημιουργία διαδραστικού παιχνιδιού υπολογιστή-χρήστη - Βασικές Ρυθμίσεις - Λιβανός Γ. Σελίδα 11