Πως θα δημιουργήσουμε ένα μηχανισμό Point n Click

Point and Click

Σε αυτό το άρθρο, θα εξερευνήσουμε πώς μπορούμε να δημιουργήσουμε μια πολύ χρήσιμη λειτουργία στο Unity χρησιμοποιώντας τη γλώσσα προγραμματισμού C#. Συγκεκριμένα, θα μάθουμε πώς να κινήσουμε τον ήρωα του παιχνιδιού μας στο σημείο που επιθυμούμε, χρησιμοποιώντας το αριστερό κουμπί του ποντικιού. Είμαι βέβαιος ότι θα βρείτε αυτό το άρθρο πολύ ενδιαφέρον και χρήσιμο!

Προϋπόθεση για να ολοκληρώσουμε το παρακάτω είναι να έχουμε εγκατεστημένη τη Unity και να έχουμε δημιουργήσει ένα νέο project 3D.

Εάν δεν γνωρίζετε πώς να το κάνετε αυτό μπορείτε να βρείτε οδηγίες στους παρακάτω συνδέσμους.

Εγκατάσταση Unity & Visual Studio.

Δημιουργία νέου project στη Unity.

Αφού έχουμε ανοίξει το νέο μας project θα δημιουργήσουμε πρώτα το έδαφος κάνοντας δεξί κλικ στο Hierarchy window και κατόπιν πηγαίνοντας στο 3D object ⇒ Plane

Χωρίς να κάνουμε κλικ κάπου αλλού ονομάζουμε το plane που μόλις δημιουργήσαμε Ground.

Εάν για κάποιο λόγο κάναμε κλικ και δεν μπορούμε να δώσουμε όνομα στο αντικείμενο, κάνουμε δεξί κλικ πάνω στο Plane στο παράθυρο Hierarchy και επιλέγουμε Rename

Εάν δεν είναι κεντραρισμένο το αντικείμενο μας στη σκηνή, πηγαίνουμε στο παράθυρο του inspector, κάνουμε δεξί κλικ στο component Transform και επιλέγουμε Reset.

Τώρα θα αλλάξουμε το μέγεθος του εδάφους στο Χ και Ζ κατά πέντε

Κατόπιν κάνουμε πάλι δεξί κλικ μέσα στο παράθυρο Hierarchy και για να δημιουργήσουμε μία κάψουλα, πηγαίνουμε στην επιλογή 3D object και επιλέγουμε Capsule

Μηδενίζουμε τα transformations και για την κάψουλα όπως κάναμε παραπάνω για το Plane

Την μετακινούμε στον άξονα Y=1

Μετονομάζουμε την κάψουλα σε Player

Στο παρακάτω Link μπορείτε να μάθετε πως μετακινούμαστε μέσα στο περιβάλλον του Unity

Το περιβάλλον του Unity και πως μετακινούμαστε στον 3D κόσμο.

Τώρα θα δημιουργήσουμε μέσα στο παράθυρο του project ένα φάκελο κάνοντας δεξί κλικ και επιλέγοντας Create ⇒ Folder, τον οποίο θα τον ονομάσουμε Scripts και μέσα σε αυτό θα δημιουργήσουμε ένα νέο script με όνομα ClickAndMove κάνοντας δεξί κλικ στο φάκελο που δημιουργήσαμε και επιλέγοντας Create ⇒ C# Script

Για τα βασικές έννοιες προγραμματισμού στη C# για Unity μπορείτε να πατήσετε στον παρακάτω σύνδεσμο.

Βασικές έννοιες προγραμματισμού και εισαγωγή στη C# για Unity

Τώρα θα κάνουμε διπλό κλικ στο script που μόλις δημιουργήσαμε για να ανοίξει μέσα στο Visual Studio και εισάγουμε τον παρακάτω κώδικα.

 

using UnityEngine;
public class ClickAndMove : MonoBehaviour
{
    private Vector3 targetPosition;
    private float stopDistance = 0.1f;
    private void Update()
    {
        if (Vector3.Distance(transform.position, targetPosition) > stopDistance)
        {
            Vector3 moveDirection = (targetPosition – transform.position).normalized;
            float moveSpeed = 5;
            transform.position += moveDirection * moveSpeed * Time.deltaTime;
        }
        if (Input.GetMouseButtonDown(0))
        {
            Move(new Vector3(2,0,2));
        }
    }
    private void Move(Vector3 targetPosition)
    {
        this.targetPosition = targetPosition;
    }
}

Στην αρχή του παραπάνω κώδικα στο private Vector3 targetPosition; ορίζουμε μία μεταβλητή η οποία θα κρατάει τη θέση στην οποία θέλουμε να κινηθεί ο player

Στο private float stopDistance = 0.1f; ορίζουμε μία μεταβλητή η οποία θα είναι η απόσταση στην οποία θα σταματάει ο player από το σημείο που κάναμε κλικ

Μέσα στη μέθοδο Update έχουμε την κίνηση του player καθώς και τον έλεγχο για το πάτημα του ποντικιού.

Στην πρώτη συνθήκη if (Vector3.Distance(transform.position, targetPosition) > stopDistance) ελέγχουμε αν ο player έχει φτάσει ή όχι στο σημείο που κάναμε κλικ και αν έχει φτάσει αυτό σημαίνει ότι η απόσταση από το σημείο πού βρίσκεται (transform.position με το σημείο που κάναμε κλικ targetPosition είναι μικρότερο από το stopDistance. Σε αυτή την περίπτωση θα αγνοήσει τον παρακάτω κώδικα.

Εάν όχι θα εκτελέσει τον κώδικα:
Vector3 moveDirection = (targetPosition – transform.position).normalized;
float moveSpeed = 5;
transform.position += moveDirection * moveSpeed * Time.deltaTime;

Στην πρώτη γραμμή δημιουργούμε μία μεταβλητή η οποία κρατάει την κατεύθυνση στην οποία θα κινηθεί ο player.
Στη δεύτερη ορίζουμε την ταχύτητα και στην τρίτη γραμμή προσθέτουμε στην τωρινή θέση την κατεύθυνση * την ταχύτητα * το χρόνο που μεσολαβεί ανάμεσα σε δύο καρέ (Time.deltaTime)

Στην επόμενη συνθήκη:
if (Input.GetMouseButtonDown(0))
{
Move(new Vector3(2,0,2));
}

Ελέγχουμε για το πάτημα του αριστερού κουμπιού του ποντικιού και καλούμε την παρακάτω μέθοδο και για λόγους δοκιμής περνάμε το σημείο 2,0,2 σα σημείο προορισμού μέχρι να φτιάξουμε την κλάση η οποία θα διαβάζει το σημείο του ποντικιού.

Σε αυτή τη μέθοδο:
private void Move(Vector3 targetPosition)
{
this.targetPosition = targetPosition;
}

Εφαρμόζουμε στον Player την θέση προορισμού που την περνάμε σαν παράμετρο στην προηγούμενη συνθήκη Move(new Vector3(2,0,2).

Μόλις ολοκληρώσουμε τον κώδικα κάνουμε αποθήκευση και επιστρέφουμε στον editor

Εκεί θα εφαρμόσουμε το script που δημιουργήσαμε στον Player κάνοντας Drag and Drop

Κάνουμε δοκιμή πατώντας το Play.

Θα παρατηρήσουμε ότι μόλις κάνουμε κλικ ο Player μπαίνει στο έδαφος. Αυτό γίνεται γιατί λέμε στον κώδικά μας να μετακινηθεί ο χαρακτήρας μας στο 2,0,2 όπου στο Y δίνουμε 0

Για να το διορθώσουμε αυτό υπάρχουν διάφοροι τρόποι όπως για παράδειγμα να προσθέσουμε ένα στο Y.

Ένας άλλος τρόπος που θα μας βοηθήσει και σε άλλες περιπτώσεις είναι να βάλουμε την κάψουλα μέσα σε ένα άδειο αντικείμενο όπου θα βρίσκεται στο έδαφος (0,0,0) και να εφαρμόσουμε σε αυτό το script.

Τώρα αν κάνουμε δοκιμή θα δούμε ότι ο Player δεν μπαίνει στο έδαφος.

Το επόμενο που πρέπει να κάνουμε είναι να παίρνουμε το πάτημα του ποντικιού και να περνάμε το σημείο που πατήσαμε στη μέθοδο Move που δημιουργήσαμε στην κλάση ClickAndMove.

Για αυτό θα δημιουργήσουμε μία νέα κλάση(script) με όνομα PointAtMouseClick και θα την εφαρμόσουμε σε ένα άδειο αντικείμενο με το ίδιο όνομα.

using UnityEngine;
public class PointAtMouseClick : MonoBehaviour
{
    private static PointAtMouseClick Instance;
    [SerializeField] private LayerMask mousePlaneLayerMask;
    private void Awake()
    {
        Instance = this;
    }
    public static Vector3 GetPosition()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        Physics.Raycast(ray, out RaycastHit raycastHit, float.MaxValue, Instance.mousePlaneLayerMask);
        return raycastHit.point;
    }
}

Στον παραπάνω κώδικα πρώτα δημιουργούμε ένα στατικό αντικείμενο της ίδιας κλάσης private static PointAtMouseClick Instance; για να μπορούμε να έχουμε πρόσβαση από παντού χωρίς να χρειάζεται να δημιουργήσουμε ένα αντίγραφο αυτής.

Μετά δημιουργούμε ένα LayerMask για να μπορούμε να διαχωρίσουμε τα πατήματα του ποντικιού μόνο σε αντικείμενα που θέλουμε.

Στη μέθοδο Awake δημιουργούμε το αντίγραφο της κλάσης.

Στη στατική μέθοδο GetPosition() ελέγχουμε με τη μέθοδο Physics.Raycast με μία Ray που ελέγχει την ακτίνα από την κάμερα μέχρι το σημείο που βρίσκεται το ποντίκι και εάν το πάτημα του ποντικιού πραγματοποιήθηκε σε ένα αντικείμενο που ανήκει στο ίδιο layer με το LayerMask τότε επιστρέφουμε το σημείο αυτό.

Τώρα θα πάμε μέσα στον κώδικα του ClickAndMove και θα κάνουμε την εξής αλλαγή:
if (Input.GetMouseButtonDown(0))
{
Move(PointAtMouseClick.GetPosition());
}

Αποθηκεύουμε τα script και επιστρέφουμε στον editor

Εδώ θα πρέπει να κάνουμε τα εξής:
Πρώτα να δημιουργήσουμε ένα νέο layer επιλέγοντας το Ground και από τον Inspector στην επιλογή Layer να επιλέξουμε Add layer

Και στο User Layer 6 θα βάλουμε την ετικέτα Ground

Μετά επιλέγουμε ξανά το αντικείμενο Ground και από την επιλογή Layer επιλέγουμε το Ground.

Τώρα επιλέγουμε το αντικείμενο PointAtMouseClick και από τη λίστα Mouse Plane Layer Mask επιλέγουμε το Ground

Τώρα αν θα τρέξουμε το παιχνίδι θα δούμε ότι μπορούμε να μετακινούμε τον χαρακτήρα εκεί που κάνουμε κλικ αλλά μόνο πάνω στο έδαφός.

Για παράδειγμα εάν δημιουργήσουμε ένα κύβο και κάνουμε κλικ πάνω σε αυτό, Player δε θα μετακινηθεί διότι ο κύβος δεν ανήκει στο layer Ground.

 

Ελπίζω το παραπάνω άρθρο να σας φάνηκε χρήσιμο και να σας βοήθησε στη δημιουργία του δικού σας παιχνιδιού!

ΘΕΛΕΤΕ ΝΑ ΜΑΘΕΤΕ ΠΩΣ ΝΑ ΔΗΜΙΟΥΡΓΕΙΤΕ ΕΝΑ ΟΛΟΚΛΗΡΩΜΕΝΟ ΠΑΙΧΝΙΔΙ