Στην άσκηση αυτή θα συνεχίσετε τη σχεδίαση τρισδιάστατου περιβάλλοντος για παιχνίδια RPG χρησιμοποιώντας το λογισμικό Unity 3D, εισάγοντας επιπλέον λειτουργικότητα στον ήδη σχεδιασμένο "χάρτη" του παιχνιδιού που υλοποιήσατε σε προηγούμενο βήμα. Ο στόχος είναι να εξοικειωθείτε με τη μετεξέλιξη του παιχνιδιού σε ένα παιχνίδι περιήγησης και ρόλων εισάγοντας νέα στοιχεία και συνδέοντάς τα με τμήματα κώδικα, γνωρίζοντας μέσω της πράξης τις τεράστιες δυνατότητες της 3D engine του περιβάλλοντος Unity 3D. Ας ξεκινήσουμε λοιπόν την υλοποίηση! ΒΗΜΑ 1: Από το κεντρικό μενού επιλέξτε File -> Open Scene και ανοίξτε το αρχείο που υλοποιήσατε στην προηγούμενη άσκηση ή ανοίξτε το βοηθητικό αρχείο game.unity που κατεβάσατε μαζί με την εκφώνηση της άσκησης (θυμηθείτε ότι είχαν χρησιμοποιηθεί τα πακέτα λειτουργικότητας Character Controller, Particles, Physic Materials, Script, Skyboxes, Terrain Assets, Tree Creator και Water και 3D ως setup defaults για το project). Η πρώτη πρόσθετη λειτουργικότητα που μπορεί να εισαχθεί στη σχεδίαση είναι η ανίχνευση συγκρούσεων (collisions), δηλαδή η επαφή μεταξύ δύο αντικειμένων, κάτι που είναι απαραίτητο για τα ρεαλιστικά παιχνίδια. Αυτό θα επιτευχθεί με τη χρήση Colliders, δηλαδή ενσωματωμένων στοιχείων (components) στη Unity τα οποία παρέχουν δυνατότητα ανίχνευσης σύγκρουσης μέσω των περιβαλλουσών καμπυλών σε διάφορες γεωμετρίες στο χώρο (επισημαίνονται με πράσινο χρώμα γύρω από το αντικείμενο/σχέδιο). Η ανάμειξη των colliders δύο ή περισσότερων σχημάτων είναι διαχειρίσιμη μέσω διαφόρων συναρτήσεων και συνήθως αποτελεί γεγονός που ενεργοποιεί (trigger) μια διαδικασία ή γενικά ένα σενάριο. Αρχικά λοιπόν, θα εισάγουμε colliders ώστε να εμποδίσουμε τον παίχτη ήρωα από το να περνά ανάμεσα από τα δέντρα ή να πέφτει στο χείλος του γκρεμού στις άκρες της σκηνής, κάτι το οποίο δεν είναι αληθοφανές. Σχεδίαση περιβάλλοντος παιχνιδιού RPG στη Unity 3D - Λιβανός Γ. Σελίδα 1
ΒΗΜΑ 2: Δημιουργήστε ένα κενό GameObject μέσω του μενού GameObject > Create Empty, μετονομάστε το σε 'Boundaries' και βεβαιωθείτε ότι είναι τοποθετημένο στο σημείο (0, 0, 0). Δημιουργήστε ένα διπλότυπο του αντικειμένου επιλέγοντας δεξί κλικ > Duplicate (Ctrl + D), μετονομάστε το σε 'Bottom' και σύρετε το αντικείμενο αυτό στο αντικείμενο 'Boundaries' ώστε να το κάνετε "απόγονό" του (το αντικείμενο Boundaries θα ελέγχει τη λειτουργία του). Με το αντικείμενο 'Bottom' επιλεγμένο, εισάγετε έναν Box Collider Component χρησιμοποιώντας το μενού Component > Physics > Box Collider και από την εργαλειοθήκη Inspector ορίστε τη θέση του σύμφωνα με το διπλανό σχήμα. Κάντε κλικ στο άξονα Y (πράσινος) από το εργαλείο Scene Gizmo στην πάνω δεξιά γωνία του παραθύρου της σκηνής, μεταβείτε σε Top View και εστιάστε στη σκηνή σύμφωνα με το σχήμα. Δημιουργήστε τρία αντίγραφα του αντικειμένου 'bottom' και μετονομάστε τα σε 'Right', 'Left' και 'Top' και ορίστε τα χαρακτηριστικά των Box Collider για το καθένα σύμφωνα με τα παρακάτω σχήματα: Σχεδίαση περιβάλλοντος παιχνιδιού RPG στη Unity 3D - Λιβανός Γ. Σελίδα 2
ΒΗΜΑ 3: Στο σημείο αυτό θα πρέπει η σκηνή να περιβάλλεται και από τις τέσσερις πλευρές από ένα παραλληλεπίπεδο και όταν το παιχνίδι τρέξει ο παίχτης να μην μπορεί να υπερβεί τα όρια του "χάρτη". Από το Project Window επιλέξτε το αντικείμενο Alder Tree (ή όποιο πρότυπο δέντρων θέλετε) εντός του φακέλου 'Terrain Assets / Trees Ambient-Occlusion /', σύρετέ το στη σκηνή καθ τοποθετήστε το κοντά στο αντικείμενο First Person Controller. Με το δέντρο επιλεγμένο από την εργαλειοθήκη Hierarchy εισάγετε ένα αντικείμενο Capsule Collider μέσω του μενού 'Component > Physics > Capsule Collider'. Στο πλαίσιο διαλόγου που ανοίγει αποδεχτείτε την προειδοποίηση ξαθ πατήστε Add. Αναπαράγετε το παιχνίδι και παρατηρήστε ότι ο παίχτης δεν μπορεί να διαπεράσει το συγκεκριμένο αντικείμενο-δέντρο. Η απόσταση στην οποία μπορεί να πλησιάσει εξαρτάται από τις διαστάσεις του περιβλήματος του αντικειμένου collider, οπότε ρυθμίστε τις από την κατάλληλη καρτέλα. Για να γίνουν αποδεκτές οι ρυθμίσεις πρέπει να σταματήσετε την αναπαραγωγή του παιχνιδιού και να έχετε μεταβεί στη σχεδίαση της σκηνής. Τι θα συμβεί όμως με τα δέντρα τα οποία έχουν ήδη εισαχθεί στη σκηνή; Σχεδίαση περιβάλλοντος παιχνιδιού RPG στη Unity 3D - Λιβανός Γ. Σελίδα 3
ΒΗΜΑ 4: Από το παράθυρο Project δημιουργήστε ένα φάκελο με το όνομα 'Prefabs' και εντός του δημιουργήστε ένα νέο αντικείμενο Prefab με το όνομα 'tree-prefab'. Αντιστοιχήστε το δέντρο με τον ενσωματωμένο Collider στο αντικέιμενο Prefab επιλέγοντάς το από το παράθυρο Hierarchy και σύροντάς το στο αντικείμενο Prefab. Στη συνέχεια, διαγράψτε το από τη λίστα στο παράθυρο Hierarchy. Για να εφαρμοστεί λοιπόν αυτό το πρότυπο αντικείμενο-δέντρο σε όλα τα αντικείμενα-δέντρα της σκηνής, επιλέξτε το αντικείμενο Terrain από το παράθυρο Hierarchy και εντός της καρτέλας Inspector επιλέξτε το εργαλείο 'Place Trees' για να τοποθετήσετε τα δέντρα πάνω στο έδαφος. Το τρέχον επιλεγμένο πρότυπο για το χάρτη είναι το 'Alder', οπότε επιλέξτε το και πατήστε την επιλογή 'Edit Trees...' για να εμφανίσετε το αντίστοιχο πλαίσιο διαλόγου. Κάντε κλικ στον κύκλο δεξιά από τη λέξη Alder κι επιλέξτε το treeprefab από το πλαίσιο διαλόγου Select GameObject. Όλα τα δέντρα τώρα έχουν αντικατασταθεί από το πρότυπο που δημιουργήσαμε, το οποίο διαθέτει τη λειτουργικότητα σύγκρουσης. Για να ολοκληρώσετε τη διαδικασία, επιλέξτε το αντικείμενο terrain και στο κάτω μέρος της καρτέλας Inspector ελέγξτε αν η επιλογή 'Create Tree Collisions' είναι ενεργή. ΒΗΜΑ 5: Το επόμενο βήμα είναι η εισαγωγή λειτουργικότητας συλλογής αντικειμένων (pickup). Κατεβάστε αυτό το Unity package και εισάγετέ το στο φάκελο Projects Asset κάνοντας διπλό κλικ ή εισάγετέ το μέσω του μενού που εμφανίζεται στη διπλανή εικόνα, οπότε και θα δημιουργηθεί ένας φάκελος και ένα νέο αντικείμενο Prefab. Σχεδίαση περιβάλλοντος παιχνιδιού RPG στη Unity 3D - Λιβανός Γ. Σελίδα 4
Για να μαζέψει ο χρήστης αντικείμενα θα πρέπει αυτά να εισαχθούν στη σκηνή, είτε χειροκίνητα είτε αυτόματα (π.χ. σε τυχαία σημεία μέσω ενός αρχείου κώδικα). Δημιουργήστε ένα φάκελο εντός του παραθύρου Project με το όνομα 'Scripts', δημιουργήστε ένα νέο αρχείο κώδικα κάνοντας δεξί κλικ στο φάκελο Scripts κι επιλέγοντας 'Create > JavaScript' και δώστε στο script το όνομα 'PickupController'. Κάντε διπλό κλικ για να ανοίξετε το αρχείο με τον προκαθορισμένο editor της Unity 3D και διαγράψτε την προκαθορισμένη συνάρτηση Update. Δημιουργήστε ένα κενό αντικείμενο GameObject, στην καρτέλα Inspector ορίστε τη θέση του ως (0, 0, 0) και μετονομάστε το σε 'PickupSpawnPoints'. Αυτό θα αποτελέσει το πατρικό αντικείμενο (parent object) το οποίο θα περιέχει τα δημιουργούμενα στοιχεία συλλογής (spawnpoints). Από την καρτέλα Hierarchy επιλέξτε το αντικείμενο Player και χρησιμοποιώντας το βασικό μενού εισάγετε άλλο ένα αντικείμενο Empty GameObject στη θέση του παίχτη, μετονομάστε το σε 'spawnpoint' και σύρετέ το πάνω στο αντικείμενο PickupSpawnPoints ώστε να κάνετε το τελευταίο το parent αντικείμενο του spawnpoint. Επιλέξτε το αντικείμενο spawnpoint και με τα εργαλεία Transform μετακινήστε το μπροστά από τον παίχτη και πάνω από το έδαφος. Σχεδίαση περιβάλλοντος παιχνιδιού RPG στη Unity 3D - Λιβανός Γ. Σελίδα 5
ΒΗΜΑ 6: Το επόμενο βήμα είναι να επισημανθούν (Tag) τα αντικείμενα SpawnPoints μέσω κώδικα ώστε το παιχνίδι να γνωρίζει αν ο παίχτης τα "μάζεψε" ή όχι. Για το σκοπό αυτό θα χρησιμοποιηθούν οι χρήσιμες συναρτήσεις της Unity GameObject.FindWithTag(...) και GameObject.FindGameObjectsWithTag(...). Η Unity διαθέτει αρκετά ενσωματωμένα Tags τα οποία είναι προσβάσιμα από την αναδιπλούμενη λίστα Tag στο πάνω μέρος της εργαλειοθήκης Inspector, ενώ υπάρχει και η δυνατότητα για δημιουρ-γία νέας ετικέτας. Ανοίξτε τον Tag Manager, είτε μέσω της επιλογής Add Tag της λίστας είτε από το μενού Edit > Project Settings > Tags και δημιουργήστε μια ετικέτα με το όνομα 'SpawnPoint' στο στοιχείο Element 0. Επιλέξτε το αντικείμενο spawnpoint από το παράθυρο Hierarchy και εφαρμόστε του τη νέα ετικέτα 'SpawnPoint' από το αναδιπλούμενο μενού. ΒΗΜΑ 7: Το επόμενο βήμα είναι να εμπλουτιστεί το αρχείο κώδικα PickupController Script με στοιχεία λειτουργικότητας, οπότε προσθέστε τις ακόλουθες γραμμές (χωρίς την αρίθμηση γραμμών): // the pickup prefab, assigned via the Inspector public var pickupprefab:gameobject; // the spawnpoint that our pickup will be spawned at private var spawnpoint:gameobject; function Awake() // retrieve GameObject tagged as 'SpawnPoint' within the 'PickupSpawnPoints' GameObject which this script is a Component of spawnpoint = gameobject.findwithtag("spawnpoint"); // spawn the pickup SpawnPickup(); function SpawnPickup() // retrieve the position and rotation of the pickup's spawn point var spawnedpickupposition:vector3 = spawnpoint.transform.position; Σχεδίαση περιβάλλοντος παιχνιδιού RPG στη Unity 3D - Λιβανός Γ. Σελίδα 6
var spawnedpickuprotation:quaternion = spawnpoint.transform.rotation; // instantiate (create) the pickup prefab with the above position and rotation var spawnedpickup:gameobject = Instantiate(pickupPrefab, spawnedpickupposition, spawnedpickuprotation); // set the spawned pickup as a child of the 'PickupSpawnPoints' gameobject that this script is a Component of spawnedpickup.transform.parent = spawnpoint.transform; Μια μικρή εξήγηση του κώδικα: Υπάρχουν δύο μεταβλητές, μία public η οποία χρειάζεται να αντιστοιχηθεί με κάποιο αντικείμενο μέσω της εργαλειοθήκης Inspector και μία private για χρήση εντός της συνάρτησης Awake. Η συνάρτηση Awake, ενεργοποιείται όταν ένα αρχείο "φορτώνεται" και ανακτά το spawnpoint GameObject μέσω της ετικέτας του και το αντιστοιχεί στη μεταβλητή spawnpoint του κώδικα. Η συνάρτηση SpawnPickup ανακτά τη θέση και την περιστροφή του αντικειμένου spawnpoint και στη συνέχεια φτιάχνει ένα στιγμιότυπο του pickupprefab στις συγκεκριμένες θέσεις, το αποθηκεύει ως spawnedpickup και δημιουργεί το αντικείμενο - παιδί του spawnpoint με την ανάθεση της ιδιότητας parent του κατάλληλου Τransform Component. Τι λείπει; Η αντιστοίχηση του script ως Component σε κάποιο GameObjects της σκηνής. Απλά σύρετε το αρχείο κώδικα από το παράθυρο Console στο αντικείμενο PickupSpawnPoints κι ελέγξτε ότι η αντιστοίχηση έχει γίνει στο κατάλληλο σημείο της εργαλειοθήκης Inspector. Αν τρέξετε το παιχνίδι θα λάβετε ένα μήνυμα λάθους, λόγω του ότι η μεταβλητή pickupprefab δεν έχει ανατεθεί σε κάποιο αντικείμενο. variable, so when the script attempts to instantiate the variable there is nothing (null) to instantiate and so it throws an error. Απλά σύρετε το pickup-prefab στη θέση κειμένου 'None (Game Object)' του PickupController Component του αντικειμένου PickupSpawnPoints GameObject. Αν τρέξετε πάλι το παιχνίδι το μήνυμα λάθους δεν εμφανίζεται πια, ο παίχτης όμως μπορεί να διαπερνά το αντικείμενο και όχι να το μαζεύει, οπότε απαιτούνται και άλλες ρυθμίσεις. Σχεδίαση περιβάλλοντος παιχνιδιού RPG στη Unity 3D - Λιβανός Γ. Σελίδα 7
ΒΗΜΑ 8: Το επόμενο βήμα είναι η δημιουργία πολλών αντικειμένων spawn points αυτόματα σε τυχαίες θέσεις. Διαγράψτε λοιπόν τις μεταβλητές στην αρχή του script και αντικαταστήστε τις με τις παρακάτω: // the pickup prefab, assigned via the Inspector public var pickupprefab:gameobject; // the number of pickups to have around the level at any one time public var numberofpickups:int = 2; // the ARRAY of spawnpoints that our pickup will be spawned at private var spawnpointlist:gameobject[]; // array of which spawn points are currently available for spawning at private var spawnindexavailablelist:array = []; // variable to hold the total number of spawn points, saves having to recalculate private var numberofspawnpoints:int; Η πρώτη μεταβλητή pickupprefab παραμένει ανεπηρέαστη ενώ η private μεταβλητή spawnpoint "εξελίχθηκε" σε ένα πίνακα (Array) GameObjects ώστε να μπορούν να εισάγονται και να αποθηκεύονται πολλαπλά αντικείμενα spawnpoints. Η μεταβλητή spawnindexavailablelist ουσιαστικά ελέγχει ποια αντικείμενα points είναι διαθέσιμα και δεν έχουν συλλεγεί από τον παίχτη ώστε να μη δημιουργηθούν καινούρια στις ίδιες θέσεις. Αντικαταστήστε τη συνάρτηση Awake() με την παρακάτω έκδοσή της: function Awake() // retrieve GameObjects tagged as 'SpawnPoint' within the 'PickupSpawnPoints' GameObject which this script is a Component of spawnpointlist = gameobject.findgameobjectswithtag("spawnpoint"); // retreive number of spawn points numberofspawnpoints = spawnpointlist.length; // make sure number of pickups doesn't exceed number of spawn points if (numberofpickups > numberofspawnpoints) numberofpickups = numberofspawnpoints; // make all spawn points available by setting each index to true for (var i:int = 0; i < numberofspawnpoints; i++) spawnindexavailablelist[i] = true; // spawn X amount of pickups according to numberofpickups for (var j:int = 0; j < numberofpickups; j++) SpawnPickup(); Σχεδίαση περιβάλλοντος παιχνιδιού RPG στη Unity 3D - Λιβανός Γ. Σελίδα 8
Η πρώτη αλλαγή αφορά στο γεγονός ότι χρησιμοποιείται η συνάρτηση FindGameObjectsWithTag(...) για να ανακτήσει όλες τις ετικέτες των αντικειμένων 'SpawnPoint', σε αντίθεση με τη συνάρτηση FindWithTag(...) η οποία "ανίχνευε" μόνο ένα αντικείμενο. Ο αριθμός των spawnpoints που βρίσκει ο παίχτης αποθηκεύεται σε μια μεταβλητή και για την αποφυγή λαθών, αυτός δεν πρέπει να είναι μεγαλύτερος από τον αριθμός των αντικειμλένων που έχουν ήδη δημιουργηθεί από το παιχνίδι. Κάθε στοιχείο της λίστας spawnindexavailablelist λαμβάνει την τιμή true, μιας και αρχικά όλα τα spawnpoints είναι διαθέσιμα για περισυλλογή. Η συνάρτηση SpawnPickup() ουσιαστικά υλοποιεί τη συλλογή αντικειμένων. Αντικαταστήστε τον κώδικα αυτής της συνάρτησης με τον ακόλουθο: function SpawnPickup() // generate a random integer to use as the index to select a spawn point from the list var randomspawnindex:int = Random.Range(0, numberofspawnpoints); // while the selected spawn index is unavailable regenerate another one while (!spawnindexavailablelist[randomspawnindex]) randomspawnindex = Random.Range(0, numberofspawnpoints); // retrieve the position and rotation of the pickups spawn point var spawnedpickupposition:vector3 = spawnpointlist[randomspawnindex].transform.position; var spawnedpickuprotation:quaternion = spawnpointlist[randomspawnindex].transform.rotation; // instantiate (create) the pickup prefab with the above position and rotation var spawnedpickup:gameobject = Instantiate(pickupPrefab, spawnedpickupposition, spawnedpickuprotation); // set the spawned pickup as a child of the 'PickupSpawnPoints' gameobject that this script is a Component of // this is so we can use SendMessageUpwards within scripts attached to the pickupprefab to call functions within this script spawnedpickup.transform.parent = spawnpointlist[randomspawnindex].transform; // set the name of the pickup as its index spawnedpickup.name = randomspawnindex.tostring(); // make the spawn index unavailable to prevent another pickup being spawned in this position spawnindexavailablelist[randomspawnindex] = false; Τι συμβαίνει τώρα; Σχεδίαση περιβάλλοντος παιχνιδιού RPG στη Unity 3D - Λιβανός Γ. Σελίδα 9
Αρχικά δημιουργείται ένας τυχαίος αριθμός αντικειμένων ανάμεσα στην τιμή 0 και την τιμή numberofspawnpoints χρησιμοποιώντας τη συνάρτηση Random.Range(...), η οποία και θα χρησιμοποιηθεί και για την ανάκτηση του spawnpoint από την αντίστοιχη θέση του πίνακα spawnpointlist. Η επαναληπτική δομή while ελέγχει αν υπάρχουν διαθέσιμα αντικείμενα ώστε ο παίχτης να μη συλλέξει πολλές φορές το ίδιο αντικείμενο στην ίδια θέση. Οι υπόλοιπες ενέργειες είναι παρόμοιες με αυτές του αρχικού κώδικα. Απομένει μόνο η μετατροπή του αριθμού θέσης του αντικειμένου σε ένα όνομα κειμένου μέσω της συνάρτησης ToString() και η επισήμναση ότι αυτό το αντικείμενο έχει συλλεγεί. Απομένει η η δημιουργία διπλοτύπων των αντικειμένων spawnpoint εντός του παραθύρου Hierarchy (δεξί κλικ> Duplicate ή Ctrl + D) και η τοποθέτηση στη σκηνή. Αρχικά δημιουργήστε 4 αντικείμενα για τον έλεγχο της υλοποίησης και στην τελική έκδοση συμπεριλάβετε όσα επιθυμείτε (π.χ. 25 spawn points και τιμή number of pickups για την ιδιότητα PickupController ίση με 15. ΒΗΜΑ 9: Το επόμενο βήμα είναι η συλλογή των αντικειμένων άρα η ενεργοποίηση της λειτουργικότητας Collider. Στο παράθυρο Project επιλέξτε το αντικείμενο pickup-prefab και εισάγετε έναν Box Collider από το μενού Component > Physics > Box Collider, οπότε και ο παίχτης δεν θα μπορεί να πλησιάσει πολύ κοντά στο αντικείμενο. Στο φάκελο Scripts δημιουργήστε ένα νέο script με το όνομα 'PlayerController' ώστε στη συνέχεια να ελέγξετε τη συλλογή των αντικειμένων. Επιλέξτε το αντικείμενο Player στην καρτέλα Hierarchy και αναθέστε του το αρχείο PlayerController ως Component απλά σύροντάς το στην κατάλληλη θέση της καρτέλας Inspector. Σχεδίαση περιβάλλοντος παιχνιδιού RPG στη Unity 3D - Λιβανός Γ. Σελίδα 10
Ανοίξτε το αρχείο κώδικα, διαγράψτε τη συνάρτηση Update() και προσθέστε το ακόλουθο τμήμα κώδικα: // the PickupController component of the 'PickupSpawnPoints' GameObject private var pickupcontroller:pickupcontroller; function Awake() // retrieve the PickupSpawnPoints gameobject var pickupspawnpoints:gameobject = gameobject.find("pickupspawnpoints"); // and then retreive the PickupController Component of the above PickupSpawnPoints gameobject pickupcontroller = pickupspawnpoints.getcomponent("pickupcontroller"); function OnControllerColliderHit (hit:controllercolliderhit) if (hit.gameobject.tag == "Pickup") // call the Collected(...) function of the PickupController Component (script) and // pass the pickup we hit as the parameter for the function pickupcontroller.collected(hit.gameobject); Τι υλοποιείται στον κώδικα; Η συνάρτηση Awake() ανακτά το αντικείμενο PickupSpawnPoints από τη σκηνή μέσω της συνάρτησης GameObject.Find(...) και το αποθηκεύει σε μια μεταβλητή. Ο PickupController Component του αντικειμένου PickupSpawnPoints ανακτάται μέσω της GameObject.GetComponent(...) και ανατίθεται στη μεταβλητή pickupcontroller. Η συνάρτηση OnControllerColliderHit(...) ενεεργοποιείται όταν η ιδιότητα CharacterController Collider του παίχτη "συγκρουστεί" είτε με ένα αντικείμενο RigidBody ή με ένα άλλο αντικείμενο Collider. Απο τη στιγμή που τα αντικείμενα pickup διαθέτουν BoxCollider, η επαφή των αντικειμένων ανιχνεύεται και ενεργοποιείται η συνάρτηση. Αυτή με τη σειρά της δημιουργεί την κατάλληλη πληροφορία για τις "συνθήκες σύγκρουσης" μέσω της παραμέτρου με τύπο ControllerColliderHit. Για τον έλεγχο της σύγκρουση με ένα αντικείμενο pickup χρησιμοποιείται μια συνθήκη if, οπότε και καλείται η μέθοδος Collected(...) του PickupController, με παράμετρο το αντίστοιχο GameObject με το οποίο "συγκρούστηκε". Πού είναι αυτή η μέθοδος; Θα την δημιουργήσετε τώρα! Σχεδίαση περιβάλλοντος παιχνιδιού RPG στη Unity 3D - Λιβανός Γ. Σελίδα 11
ΒΗΜΑ 10: Ανοίξτε το αρχείο PickupController και προσθέστε τον ακόλουθο κώδικα στο κάτω μέρος του : function Collected(pickupCollected:GameObject) // retrieve name of the collected pickup and cast to int var index:int = parseint(pickupcollected.name); // pickup has been destroyed so make the spawn index available again spawnindexavailablelist[index] = true; // destroy the pickup Destroy(pickupCollected); // spawn a new pickup SpawnPickup(); Η μέθοδος Collected(...) ανακτά το όνομα του αντικειμένου pickup που μάζεψε ο παίχτης και κάνει το σημείο spawnpoint που είχε τοποθετηθεί διαθέσιμο ξανά. Στη συνέχεια καλεί τη συνάρτηση Destroy(...) για να αφαιρέσει το αντικείμενο από τη σκηνή και δημιουργεί ένα νέο αντικείμενο με τη μέθοδο SpawnPickup(). Συνοψίζοντας, η λειτουργικότητα είναι η ακόλουθη: 1. Ο παίχτης συγκρούεται με ένα αντικείμενο pickup το οποίο λαμβάνει την ετικέτα 'Pickup'. 2. Η συνάρτηση Collect(...) του αρχείου PickupController καλείται με είσοδο το αντικείμενο που έχει συλλέξει ο παίχτης. 3. Το αντικείμενο Pickup "καταστρέφεται" και ένα νέο αντίγραφό του δημιουργείται μέσω της συνάρτησης SpawnPickup() ΒΗΜΑ 11: Επιλέξτε το αντικείμενο pickup-prefab στο παράθυρο Project και στο πάνω μέρος της καρτέλας Inspector επιλέξτε 'Add Tag' από την αναπτυσσόμενη λίστα Tag. Εντός της εργαλειοθήκης Tag Manager κάντε κλικ στο στοιχείο element 1 και πληκτρολογήστε 'Pickup' ώστε να δημιουργηθεί η ετικέτα. Εφαρμόστε την ετικέτα επιλέγοντας ξανά το pickup-prefab κι επιλέγοντας το κείμενο 'Pickup' από τη λίστα Tag. Τρέξτε το παιχνίδι και ελέγξτε τη λειτουργικότητα. Σχεδίαση περιβάλλοντος παιχνιδιού RPG στη Unity 3D - Λιβανός Γ. Σελίδα 12
ΒΗΜΑ 12: Ως μια τελευταία πινελιά στη σχεδίαση, θα εισάγετε μια χρονοκαθυστέρηση στη επαναδημιουργία των αντικειμένων spawn. Ανοίξτε το αρχείο PickupController και προσθέστε τις ακόλουθες μεταβλητές στην αρχή του κώδικα: // minimum and maximum spawn delay times public var minimumspawndelaytime:int = 1; public var maximumspawndelaytime:int = 5; Για τη δημιουργία καθυστέρησης, η Unity διαθέτει τη μέθοδο yield WaitForSeconds(...), η οποία καθυστερεί την εκτέλεση του κώδικα που έπεται αυτής τόσα δευτερόλεπτα όσα ο αριθμός που περνιέται ως παράμετρος στη συνάρτηση. Για τυχαία επιλογή αριθμού υπάρχει η συνάρτηση Random.Range(...) Προσθέστε το ακόλουθο τμήμα κώδικα πάνω από το σημείο κλήσης της SpawnPickup() εντός τη συνάρτησης Collected(...): // wait for a random amount of seconds between minimumspawndelaytime and maximumspawndelaytime yield WaitForSeconds(Random.Range(minimumSpawnDelayTime, maximumspawndelaytime)); ΒΗΜΑ 13: Από το μενού File -> Build Settings, πατήστε το κουμπί Add Current για να προσθέσετε την τρέχουσα σκηνή στο "χτίσιμο" του project και επιλέξτε την πλατφόρμα στην οποία θέλετε να δημιουργηθεί το εκτελέσιμο αρχείο του παιχνιδιού.. Επιλέξτε Build And Run, ορίστε το φάκελο αποθήκευσης και το όνομα του αρχείου, αναζητήστε το και "τρέξτε" το. Έχετε σχεδιάσει λοιπόν το "περιβάλλον" του παιχνιδιού, μια βασική λειτουργικότητα και ένα αρχικό σενάριο, θα μπορούσατε να εμπλουτίσετε την υλοποίηση με κινούμενα αντικείμενα για συλλογή, χρονοδιακόπτη, πίνακα συλλογής πόντων κλπ! Για όποιον επιθυμεί περισσότερη εμβάθυνση στα άδυτα των προγραμματιστικών δυνατοτήτων της Unity, οι παρακάτω σύνδεσμοι μπορούν να αποδειχθούν ιδιαίτερα χρήσιμοι: Unity Manual, Unity Reference Manual και ιδιαίτερα ο σύνδεσμος Unity Scripting Reference. Σχεδίαση περιβάλλοντος παιχνιδιού RPG στη Unity 3D - Λιβανός Γ. Σελίδα 13