Alithinos Δημοσ. 15 Μαΐου 2018 Δημοσ. 15 Μαΐου 2018 (επεξεργασμένο) Καλησπέρα φίλοι του insomnia. Λύνω πολλά προβλήματα, αλλά μια στο τόσο εμφανίζονται κάποια που κολλάει το μυαλό μου και δε βρίσκω τη λύση τους, και μετά από αρκετές ώρες αν δε το βρω, αποφασίζω να ζητήσω βοήθεια. Ένα τέτοιο πρόβλημα εμφανίστηκε τώρα. Λοιπόν το πρόβλημα έχει ως εξής: Σε ένα τρισδιάστατο χώρο υπάρχει ένας παρατηρητής. Ο παρατηρητής έχει ένα component "κάμερας" μέσα απ' το οποίο βλέπει στο τρισδιάστατο χώρο. Στο χώρο ενδέχεται να συμβεί ένας σεισμός, ο οποίος έχει μια κατεύθυνση Χ ή Ζ. Θέλουμε όταν συμβαίνει ένας σεισμός, ανάλογα το προς τα που έχει στραφεί ο παρατηρητής, να περιστρέφουμε το κατάλληλο άξονα της κάμερας, ώστε να φαίνεται πως ο παρατηρητής κουνιέται προς την ίδια κατεύθυνση από όπου έρχεται το σεισμικό κύμμα. Έχω λοιπόν το εξής enum για τη κατεύθυνση του σεισμικού κύμματος: public enum ShockWaveDirection {HorizontalX, HorizontalZ, Vertical, MixedXZ,} Για το παρόν πρόβλημα δε μας ενδιαφέρει η MixedXZ μιας και σε αυτή τη περίπτωση η κάμερα κουνιέται και προς τις 2 κατευθύνσεις ισόβαθμα, ενώ η Vertical στον άξονα Υ που δε μας ενδιαφέρει τώρα. Έχουμε επίσης έναν τρόπο απ' το framework, ο οποίος μας δίνει ένα float από το -0.999... έως το 1 για τη κατεύθυνση που κοιτά ο παρατηρητής, όπου στο 1 και το 0 κοιτά στον Ζ, ενώ στο 0.5 και στο -0.5 κοιτά στον Χ. Απ αυτό μπορούμε να βρούμε τη γενική κατεύθυνση προς την οποία κοιτάει αν είναι η Χ ή η Ζ, ώστε όταν κοιτάει περισσότερο προς τη κατάλληλη μεριά, να περιστρέφεται και η κάμερα προς τη κατάλληλη μεριά. Το έκανα με τον εξής κώδικα: private WatcherLookDirection FindRotationDirection(float lookDirection) { if (lookDirection >= -0.25f && lookDirection <= 0.25f) return WatcherLookDirection.Z; else if (lookDirection >= 0.75f | lookDirection <= -0.75f) return WatcherLookDirection.Z; else if (lookDirection > 0.25f && lookDirection < 0.75f) return WatcherLookDirection.X; else return WatcherLookDirection.X; } Και σε άλλο σημείο υπάρχει η switch (direction) { case ShockWaveDirection.HorizontalX: if (FindRotationDirection(camTransform.rotation.y) == WatcherLookDirection.Z) RotateZ(magnitude); else RotateX(magnitude); break; case ShockWaveDirection.HorizontalZ: if (FindRotationDirection(camTransform.rotation.y) == WatcherLookDirection.Z) RotateX(magnitude); else RotateZ(magnitude); } Με αυτό το τρόπο η κάμερα ή θα περιστρέφεται στο Χ, ή θα περιστρέφεται στο Ζ ανάλογα τη κατεύθυνση που κοιτά ο παρατηρητής, αλλά απότομα, διότι είτε θα περιστρέφεται στο Χ είτε στο Ζ, και ποτέ δεν θα περιστρέφεται και στον Χ και στον Ζ ταυτόχρονα. Θέλουμε όμως η αλλαγή κατεύθυνσης περιστροφής της κάμερας να είναι ομαλή και ανάλογη της ακριβής κατευθύνσεως που κοιτά ο παρατηρητής. Δηλαδή αν ο παρατηρητής κοιτά για παράδειγμα στο 0.25, να εφαρμοστούν στη κάμερά του σε ίσο βαθμό τόσο περιστροφή στον Χ, όσο και στον Ζ, κοκ. Η ποσότητα περιστροφής της κάμερας να είναι ανάλογη της κατεύθυνσης που κοιτά ο παρατηρητής. Και αυτό να το κάνουμε χωρίς ένα ξεχωριστό case για κάθε μια από τις διαφορετικές γωνίες θέασης, (-0.9999... ~ 1). Πως να το κάνω αυτό ; Είμαι σίγουρος ότι θα υπάρχει πιο σύντομος και πρακτικός τρόπος. Αλλά έχει κολλήσει το μυαλό μου και δεν το βρίσκω. Επεξ/σία 15 Μαΐου 2018 από Alithinos
Moderators Kercyn Δημοσ. 15 Μαΐου 2018 Moderators Δημοσ. 15 Μαΐου 2018 Η αλήθεια είναι ότι δεν κατάλαβα ακριβώς τι θες να κάνεις, αλλά δε θα μπορούσες να έχεις βάρη για τον κάθε άξονα; lookDirection * magnitude ή κάτι τέτοιο.
Alithinos Δημοσ. 16 Μαΐου 2018 Μέλος Δημοσ. 16 Μαΐου 2018 (επεξεργασμένο) Χρειάζεται κάτι πιο περίπλοκο. Διότι αν lookDirection = 0 ή lookDirection = 1, τότε θέλουμε να έιναι magnitude * 1. Ενώ αν lookDirection = 0.5 ή lookDirection = -0.5 θέλουμε magnitude * 0. Για τον ένα άξονα, ενώ για τον άλλο το αντίστροφο. Ώστε όταν κοιτά ακριβώς προς 1 άξονα να κινείται η κάμερα προς 1 μόνο άξονα, ενώ αν κοιτά ανάμεσα σε 2 άξονες, να κινείται και στους 2 άξονες, δηλαδή το magnitude του κάθε άξονα να είναι αντιστρόφως ανάλογο απ' το άλλο. Επεξ/σία 16 Μαΐου 2018 από Alithinos
Alithinos Δημοσ. 16 Μαΐου 2018 Μέλος Δημοσ. 16 Μαΐου 2018 (επεξεργασμένο) Το πάλεψα αλλά το βρήκα, με αρκετό trial and error. Λοιπόν. Σκοπός ήταν να περιστρέφεται και στους 2 άξονες Χ,Ζ, αλλά η τιμή του ενός άξονα να είναι αντιστρόφως ανάλογη απ' τη τιμή το άλλου, δηλαδή όταν ο ένας είναι 0 ο άλλος 1, και το αντίστροφο. Και θέλαμε αυτό να καθορίζεται απ' τη κατεύθυνση που κοιτάει ο παρατηρητής, όπου αν κοιτάει στο 0.5 ή στο -0.5 κοιτά στον Χ, ενώ αν κοιτά στο 1 ή στο 0, κοιτά στον Ζ. Για να το βρούμε αυτό, πρέπει να πολλαπλασιάσουμε το magnitude, με ένα παράγωντα ο οποίος όμως δεν είναι το lookDirection, αλλά ένας που προκύπτει από μαθηματικά με το lookDirection. Για τον Χ έχουμε private float GetShakeAmountForX(float lookDirection) { if (lookDirection >= 0 && lookDirection < 0.5) return (lookDirection * 2); else if (lookDirection < 0 && lookDirection > -0.5) return (lookDirection * -2); else if (lookDirection >= 0.5 && lookDirection < 1) return (2 - (lookDirection * 2)); else return (2 + (lookDirection * 2)); } Και για τον Ζ: private float GetShakeAmountForZ(float lookDirection) { if (lookDirection < 0 && lookDirection > -0.5) return 1 + (lookDirection * 2); else if (lookDirection >= 0 && lookDirection < 0.5) return 1 - (lookDirection * 2); else if (lookDirection < 0.5 & lookDirection > -1) return -1f - (lookDirection * 2); else return -1 + (lookDirection * 2); } Αυτό που μου μένει τώρα είναι να αφαιρέσω το jitter. Γιατί όταν η τιμή ενός άξονα είναι πολύ μικρή περιστρέφεται τόσο λίγο σε απόσταση (αλλά γρήγορα) με αποτέλεσμα να φαίνεται σαν να δονείται κινητό, φαίνεται άσχημα. Επεξ/σία 16 Μαΐου 2018 από Alithinos
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα