Alithinos Δημοσ. 20 Οκτωβρίου 2017 Δημοσ. 20 Οκτωβρίου 2017 (επεξεργασμένο) Έχω ένα dictionary με custom τύπους: Dictionary<Quest, List<JournalEntry>> QuestEntries; Και έχω και 2 panels στο GUI που το καθένα αντιστοιχεί είτε στο key είτε στο value του dictionary. Το κάθε key εμφανίζεται στο panel ως GUI button, και για κάθε JournalEntry της λίστας εμφανίζεται ένα label με το string. Σκοπός είναι: όταν ο χρήστης κάνει κλικ σε κάποιο key, τότε στο δεύτερο panel να εμφανίζονται οι πληροφορίες που περιέχει το κάθε στοιχείο της List<JournalEntry> που αντιστοιχεί στο key. Το button έχει ένα scriptάκι το οποίο όταν γίνεται κλικ καλεί αυτή τη μέθοδο περνόντας της το διακριτικό που λαμβάνει απ' το Quest object στο οποίο αντιστοιχεί: public void ShowQuestEntries(string questName) { RemoveAllChildren(entryContent); List<JournalEntry> entries = GetEntriesList(questName); for (int i = 0; i < entries.Count; i++) { GameObject entry = (GameObject)Resources.Load("Systems/Journal/Entry"); Instantiate(entry, entryContent.transform); entry.GetComponent<JournalEntry>().EntryText = entries[i].EntryText; entry.GetComponent<JournalEntry>().FillText(); } } 1) Καταρχάς απ' ότι φαίνεται σβήνονται όλα τα 'παιδιά' του panel. (Επειδή τα buttons προστίθονται ως παιδιά του panel). 2) Λαμβάνεται η λίστα που αντιστοιχεί στο Key που επέλεξε ο παίκτης κάνοντας κλικ στο αντίστοιχο button. Η λίστα λαμβάνεται με αυτό το τρόπο: private List<JournalEntry> GetEntriesList(string questName) { var query = from n in QuestEntries where n.Key.Name == questName select n.Value; return query.First(); Στη συνέχεια για κάθε στοιχείο της λίστας: 3) Ορίζω το GUI object το οποίο θα είναι αυτό που θα εμφανιστεί στο panel. 4) Το εμφανίζω στο panel κλωνοποιώ με την Instantiate() 5) Θέτω τo string στο script του GUI object που εμφάνισα να είναι το ίδιο με το string του στοιχείου της λίστας. 6) Καλώ τη FillText() ώστε το string να τυπωθεί στο GUI object. Ο παραπάνω κώδικας όμως δεν δίνει τη συμπεριφορά που θέλω και ανέφερα παραπάνω. Αντ' αυτού, κάνει το εξής: A) Τη πρώτη φορά που ο χρήστης θα κάνει κλικ σε ένα button που αντιστοιχεί σε key, στο δεύτερο panel θα εμφανιστούν σωστά τα entry strings. Αν στη συνέχεια ο χρήστης κάνει κλικ σε άλλο button, όλα τα entry strings της νέας επιλογής θα εμφανιστούν κανονικά εκτός από το τελευταίο, το οποίο θα εμφανίσει το string της προηγούμενης επιλογής του χρήστη. Γ) Αν ο χρήστης κάνει ξανά κλικ στο ίδιο button, τότε το λάθος string θα αντικατασταθεί με το σωστό. Επειδή έχει κολλήσει το μυαλό μου και παιδεύομαι ενώ μπορεί και να είναι κάτι απλό που ήταν μέσα στα μάτια μου τόσες ώρες, μήπως το βλέπετε εσείς ? Που είναι το λάθος ? update: Λύθηκε το πρόβλημα! Οφειλόταν στο ότι ξέχασα τι ακριβώς κάνει η Instantiate(), και νόμιζα πως δημιουργεί στο GUI το instance που δημιούργησα "στο κώδικα" στην από πάνω γραμμή, ενώ δημιουργεί κλώνο του instance της προηγούμενης γραμμής. Αντί δηλαδή τα βήματα 5 & 6 να τα κάνω στο κλώνο τα έκανα στο template στο οποίο βασίζεται ο κλώνος. Επεξ/σία 20 Οκτωβρίου 2017 από Alithinos
defacer Δημοσ. 20 Οκτωβρίου 2017 Δημοσ. 20 Οκτωβρίου 2017 Άσχετο τώρα με όλα αυτά, χάζευα λίγο και παραξενευόμουν μόνος μου με κάποια πράγματα... Γιατί έχεις Dictionary<Quest, T> από τη στιγμή που ουσιαστικά δε χρησιμοποιείς το Quest το ίδιο ως key και κάνεις σούξου μούξου στη GetEntriesList? Φαίνεται πως στο domain της εφαρμογής ισχύει ότι "ένα Quest χαρακτηρίζεται μονοσήμαντα από το όνομά του", οπότε γιατί ασχολείσαι με strings και δεν κάνεις το απλό class Quest : IEquatable<Quest> { // από τη στιγμή που το όνομα "είναι" το object, αυτό να γίνει backed από readonly field public string Name { get; private set; } public bool Equals(Quest other) { return other != null && this.Name == other.Name; } // επίσης σωστό implementation bool Equals(object other) και int GetHashCode() } Μετά απλά χρησιμοποιείς το Quest κατευθείαν σαν key: var list = QuestEntries[quest];
Alithinos Δημοσ. 20 Οκτωβρίου 2017 Μέλος Δημοσ. 20 Οκτωβρίου 2017 Γιατί έχεις Dictionary<Quest, T> από τη στιγμή που ουσιαστικά δε χρησιμοποιείς το Quest το ίδιο ως key και κάνεις σούξου μούξου στη GetEntriesList? Επειδή η Quest πέρα απ' το πως χρησιμοποιείται για το συγκεκριμένο use case με το GUI όπου ο χρήστης ίσως να θέλει να διαβάσει τα JournalEntries, χρησιμοποιείται και για άλλους σκοπούς, και ήταν βολικό να υπάρχουν τα διαφορετικά Quests σε ένα data structure αντί να φτιάξω έναν αριθμό διαφορετικών για κάθε εργασία. Δεν θέλουμε μόνο να 'δεθεί' το κάθε Quest με μια λίστα JournalEntry, αλλά και να διαβάζονται και άλλα δεδομένα του, και να γίνονται πράγματα ανάλογα τις τιμές τους. Θα μπορούσα ίσως να περνάω στο script του κάθε button ένα reference του Quest στο οποίο αντιστοιχεί ώστε όταν καλείται η ShowQuestEntries() να περνά arg το Quest αντί για το Name το οποίο το λαμβάνει για να το εμφανίσει στο GUI, αλλά επειδή δε χρειάζεται το button συγκεκριμένα να ξέρει περισσότερα πράγματα, το έκανα όπως το έκανα.
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα