Benvenuto Visitatore(Log In|Registrati)

 
Reply to this topicStart new topic
> Unity tips, il topic dove si postano risoluzioni a problemi quotidiani
Lief
messaggio17 Apr 2018, 12:04
Messaggio #1





Gruppo: Gamer
Messaggi: 224
Iscritto il: 29 November 16
Utente Nr.: 21.351
BGE Deus Ex 1
Playing System Shock 2
SO Altro




Come forse qualcuno di voi saprà da un po' di tempo mi occupo dello sviluppo di giochi in Unity a livello personale (ma a livello professionale sono comunque Web Developer back e front end) e mi capita spesso di scontrarmi con problematiche di vario genere che possono far perdere giornate intere ma che non sempre hanno soluzioni realmente complesse.

Questo topic vuole semplicemente essere un elenco di suggerimenti aperto a tutti.
Io in particolare posterò suggerimenti relativi a Unity di tanto in tanto quando penserò che vale la pena farlo.

Come primo tips voglio iniziare con il problema che mi sono ritrovato ad affrontare più recentemente, problema che in un prossimo futuro non sarà più rilevante: il Remap dell'input in Unity a runtime.

Avete presente il menù per cambiare i comandi da usare nel gioco (esempio per cambiare il comando per saltare da Spazio ad un qualsiasi altro bottone)?
È una classica opzione che viene data ai giocatori PC (mentre è spesso assente su console) ed è anche una delle più grandi limitazioni del sistema di input attuale di Unity. Unity infatti permette il remap dell'Input solo prima di avviare il gioco in una schermata completamente separata dal gioco tipica dei videogiochi Unity.

Come risolvere il problema?
- Usare il nuovo Input System, che però è ancora in una fase di sviluppo molto embrionale, richiede una versione di Unity diversa da quella di default, è soggetto a bug e cambiamenti. In futuro ovviamente questa sarà la migliore opzione disponibile e il tutto sarà decisamente più semplice.
- Comprare sull'assets store o scaricare su git uno dei tanti sistemi di Input alternativi. Sono sistemi che però richiedono l'import di molto codice che spesso non ci interessa e che va mantenuto ad ogni aggiornamento di Unity, il che può essere giustificato ma è comunque qualcosa che è meglio evitare se si è in grado di farlo.
- Creare il nostro personalissimo sistema di Input.

Se avete deciso di usare il terzo sistema vi posso dare una mano.
Prima di tutto bisogna dire che rimappare semplicemente i tasti è decisamente semplice, vi basterà creare una mappa chiave, valore impostando la chiave a stringaNomeInput (esempio "Salto"), il valore al KeyCode a cui lo volete associare (esempio KeyCode.Space)... A quel punto fate due metodi un getter e un setter e, durante lo Start, settate tutti i valori.
Per ricavare l'input vi basterà sostituire nel codice i vostri vecchi:
if(Input.GetButtonDown("Salto"))

con

if(Input.GetKeyDown(VostraClasseInput.GetInput("Salto")))

se prima Input dipendeva da un sistema settato nell'InputManager di Unity, ora dipenderà dal vostro sistema che restituirà un KeyCode nella mappa a seconda della chiave passata e il tutto verrà letto con l'Input.GetKey GetKeyDown GetKeyUp del sistema di default di Unity.

Nel vostro menù di remap vi basterà richiamare il
VostraClasseInput.SetInput("Salto", key) (dove key è il KeyCode rilevato)
per cambiare il valore nella mappa e far rispondere il GetKeyDown ad un altro pulsante.

Principale problema:
Gli Axis non hanno KeyCode quindi come fare a rilevare il float relativo al movimento?

Per quanto riguarda la tastiera è sufficiente aggirare il problema:

float avanti = 0f;

if(Input.GetKey(VostraClasseInput.GetInput("Avanti")))
avanti = 1f;
else if(Input.GetKey(VostraClasseInput.GetInput("Indietro")))
avanti = -1f;
else
avanti = 0f;

Leggendo il float avanti possiamo sapere se l'utente sta premendo il pulsante per andare avanti, quello per andare indietro oppure non si sta muovendo.

Ovviamente il codice si può abbellire, ad esempio si può aggiungere un sistema per incrementare la variabile "avanti" da 0 ad 1 non in maniera istantanea:
avanti = avanti < 1f ? avanti + Mathf.Lerp(0, 1, Time.deltaTime * 5) : 1f;

il codice sopra significa: finché la variabile "avanti" è minore di 1 incrementa avanti da 0 a 1 in base al tempo moltiplicato per 5 (il che significa che potete variare questo tempo per rendere il tutto più lento o più veloce), in caso contrario (quando la variabile raggiunge 1) vogliamo che non venga più incrementata.

Tutto questo però è ok su tastiera, se volessimo usare un gamepad inizierebbero i problemi. I joystick infatti hanno un KeyCode variabile rilevabile solo quando si preme il joystick, non quando si stanno usando gli axis.
Inoltre, il sistema che abbiamo usato prima non ha senso per un joystick (visto che un joystick può rilevare valori intermedi tra 0 e 1 che possono venir utilizzati).

Cosa fare quindi?

L'idea è simile a quella usata in precedenza: usare il vecchio sistema di Input a nostro vantaggio. Questa volta l'idea è creare nel vecchio sistema di Input tutti gli Axis che siamo certi di voler utilizzare (esempio VerticalWindows, VerticalMac, VerticalLinux, VerticalIOS, VerticalAndroid) e settare quali assi dovranno leggere, di base tutti i joystick leggono un asse verticale e uno orizzontale (X e Y) per il joystick di sinistra, mentre la cosa varia per il joystick di destra e il d-pad a seconda della piattaforma (esempio su windows il joystick di destra è sugli assi 4 e 5, mentre su mac sono gli assi 3 e 4).

Nella nostra classe di input bisognerà aggiungere una mappa chiave valore stringa-stringa, la chiave sarà come richiameremo la lettura dell'asse nella get, mentre il valore sarà il reale nome del joystick settato nel vecchio InputManager.
Esempio

Nell'Input Manager abbiamo dato il nome "Vertical" e "Horizontal" agli assi X e Y, "RightVertical" e "RightHorizontal" agli assi 4 e 5.

Nella nostra mappa dovremo mappare questi assi in un modo simile a questo:
VostraClasseInput.SetJoypad("JoyVertical", "Vertical");
VostraClasseInput.SetJoypad("JoyHorizontal", "Horizontal");
VostraClasseInput.SetJoypad("JoyVertical2", "RightVertical");
VostraClasseInput.SetJoypad("JoyHorizontal2", "RightHorizontal");

Ovviamente se volessimo rimappare il tutto in modo da invertire ciò che vogliamo fare con joystick sinistro e destro, nel nostro sistema di remap, al passo di rilevare il joystick utilizzato (cosa che richiederebbe l'associazione di un keycode che varia da piattaforma a piattaforma e non sempre è disponibile (ad esempio non lo è sul dpad)) ci conviene settare il tutto dando semplicemente all'utente la possibilità di cambiare joystick di movimento /camera (esempi) con joystick sinistra, destra o dpad in un sistema di selezione.
VostraClasseInput.SetJoypad("JoyVertical", "RightVertical");
VostraClasseInput.SetJoypad("JoyHorizontal", "RightHorizontal");
VostraClasseInput.SetJoypad("JoyVertical2", "Vertical");
VostraClasseInput.SetJoypad("JoyHorizontal2", "Horizontal");


Per richiamare il tutto invece ci basta il sistema usato per i bottini con la sola differenza che ci serve Input.GetAxis al posto di GetKey.

Ovviamente sarebbe molto più semplice se unity fosse in grado di fare setaxis e setbutton e magari anche di rilevare l'axis usato ma sfortunatamente al momento non pare sia possibile (lo sarà con il prossimo sistema di input), ovviamente se avete idee per migliorare il mio tip scrivetele pure e spero che anche altri vorranno condividere i propri.

Al prossimo tip

Messaggio modificato da Lief il 17 Apr 2018, 12:32
 
Lief
messaggioIeri, 08:19
Messaggio #2





Gruppo: Gamer
Messaggi: 224
Iscritto il: 29 November 16
Utente Nr.: 21.351
BGE Deus Ex 1
Playing System Shock 2
SO Altro




Oggi vi lascio con un video (non mio) relativo ai comandi touch screen. A dirla tutta ho fatto qualche modifica a questo codice ma solo per renderlo più legato all'interfaccia Unity3d, zucchero sintattico insomma, il core è rimasto questo:


Penso che sia il modo migliore per creare un virtual joystick abbastanza professionale.
 
utdefault
messaggioIeri, 22:29
Messaggio #3



Gruppo icone

Gruppo: OldGamer
Messaggi: 218
Iscritto il: 28 December 13
Utente Nr.: 20.235
SO Altro




Grazie per le tips.
Per chi non conosce l'engine, tornano utili.

Il video postato non si vede. Se puoi ripostarlo, please, aggiungici anche il link originale; così da poterlo aprire esternamente se l'embedded non funzionasse ancora. ;>

In ultimo, una domanda su Unity: come gestisce le traduzioni? -- Cioè, se fa qualcosa di simile ad Ags oppure se va gestito da code.
 

Reply to this topicStart new topic
1 utenti stanno leggendo questa discussione (1 visitatori e 0 utenti anonimi)
0 utenti:

 

Modalità di visualizzazione: Normale · Passa a: Lineare · Passa a: Outline


Versione Lo-Fi Oggi è il: 24th April 2018 - 01:37