• Benvenuto in Making Videogames!
  • Dai sfogo alla tua fantasia!
  • Crea il tuo Videogioco!
Benvenuto ospite! Login Registrati




Valutazione discussione:
  • 0 voto(i) - 0 media
  • 1
  • 2
  • 3
  • 4
  • 5
Attivare Script
#1
ciao a tutti ragazzi/e,vi spiego qual è la mia situazione ho due script:
1Script- contiene la variabile "punteggio",che all'inizio è 0 e tramite una funzione dopo viene richiamata e aumentata di valore.
2Script- chiamo la variabile "punteggio" per mostrare a video il punteggio (è uno script dove organizzo la schermata),questo funziona ma il "punteggio" rimane sempre a 0 e non si aggiorna.

Io avevo pensato di far caricare/leggere allo script 2 lo script 1,così si dovrebbe accorgere del cambiamento ma non so come si fa,avevo provato ad inserire:
void start()
{
        1Script();
}

ma lo da come errore.

Ditemi se riuscite a consigliarmi/risolvermi il problema,se queste informazioni non bastano carico i due script Wink 


p.s. Non sono molto pratico di questo settore,quindi potrebbe capitare che abbia usato parole poco corrette Undecided Huh ....
 
Rispondi
#2
E' un consiglio che do a tutti lo ripeto anche a te, seguite i tutorial ufficiali di Unity. Almeno il Roll a Ball e lo Space Shooter; se poi avete problemi a capirli chiedete pure che siamo disponibili ad aiutarvi.

Dalla descrizione che fai sembra più che altro un errore di architettura, di come l'hai pensata. Il punteggio è una cosa a se state e merita la dignità di un oggetto tutto per se che lo gestisca. Nel caso dello Space Shooter viene usato un oggetto (e quindi il suo script) che si chiama GameController (o GC in breve), in particolare questo oggetto per la sua natura deve essere UNICO in tutta la vita della partita, perché UNICO è il punteggio (gli asteroidi e gli spari non lo sono invece).

Osserva gli script https://unity3d.com/learn/tutorials/proj...list=17147 (magari riparti da tutto il tutorial).

Il GC possiede un punteggio (score) che rappresenta un attributo di questo oggetto (un suo dato) e una serie di metodi (le azioni che può fare), uno di questi metodi è AddScore (int newScoreValue), questo quando viene invocato da fuori va ad incrementare il punteggio di quel tot che gli viene passato ed è aggiornato a video con la GUI.

Nel primo script DestroyByContact che gestisce le collisioni tra gli spari e gli asteroidi viene dichiarato un oggetto GC con l'accorgimento di riconoscere che è il primo ed unico GC del gioco tramite il riconoscimento dei Tag (il GC quando è stato creato in Unity gli è stato dato un Tag apposta, un nome proprio diciamo).
Codice:
   public int scoreValue;
   private GameController gameController;

   void Start ()
   {
       GameObject gameControllerObject = GameObject.FindWithTag ("GameController");
       if (gameControllerObject != null)
       {
           gameController = gameControllerObject.GetComponent <GameController>();
       }
       if (gameController == null)
       {
           Debug.Log ("Cannot find 'GameController' script");
       }
   }


Poi se c'è collisione ecc.. si chiede a quel GC (il SOLO!) di incrementare il punteggio (AddScore) di un certo valore, per poi proseguire distruggendo sparo e asteroide :
Codice:
       gameController.AddScore (scoreValue);
       Destroy(other.gameObject);
       Destroy(gameObject);

Il GC (che ricordo è UNICO) dentro il suo codice fa quello che abbiamo detto:
Codice:
   public void AddScore (int newScoreValue)
   {
       score += newScoreValue;
       UpdateScore ();
   }

Quindi per riassumere, il punteggio deve appartenere allo script2 che deve essere un oggetto UNICO, che si deve occupare di incrementarlo quando lo script1 (o tutti gli altri) lo richiede e deve anche mostrarlo (e questo già lo fa se ho capito bene).

Più semplice è la soluzione di Roll a Ball https://unity3d.com/learn/tutorials/proj...list=17141 qui usa sempre un oggetto unico il PlayerController (che gestisce il movimento e le collisioni della pallina, anche lui per sua natura UNICO). Questo oggetto ha la variabile punteggio ed è lui stesso ad incrementarla con le collisioni e ad aggiornare a video il testo.

Mi auguro di non averti fatto più confusione, ci sono molti modi per gestire la faccenda dei punti e questo è uno di quelli.
 
Rispondi
#3
(19-10-2016, 09:09 PM)Chip Ha scritto: E' un consiglio che do a tutti lo ripeto anche a te, seguite i tutorial ufficiali di Unity. Almeno il Roll a Ball e lo Space Shooter; se poi avete problemi a capirli chiedete pure che siamo disponibili ad aiutarvi.

Dalla descrizione che fai sembra più che altro un errore di architettura, di come l'hai pensata. Il punteggio è una cosa a se state e merita la dignità di un oggetto tutto per se che lo gestisca. Nel caso dello Space Shooter viene usato un oggetto (e quindi il suo script) che si chiama GameController (o GC in breve), in particolare questo oggetto per la sua natura deve essere UNICO in tutta la vita della partita, perché UNICO è il punteggio (gli asteroidi e gli spari non lo sono invece).

Osserva gli script https://unity3d.com/learn/tutorials/proj...list=17147 (magari riparti da tutto il tutorial).

Il GC possiede un punteggio (score) che rappresenta un attributo di questo oggetto (un suo dato) e una serie di metodi (le azioni che può fare), uno di questi metodi è AddScore (int newScoreValue), questo quando viene invocato da fuori va ad incrementare il punteggio di quel tot che gli viene passato ed è aggiornato a video con la GUI.

Nel primo script DestroyByContact che gestisce le collisioni tra gli spari e gli asteroidi viene dichiarato un oggetto GC con l'accorgimento di riconoscere che è il primo ed unico GC del gioco tramite il riconoscimento dei Tag (il GC quando è stato creato in Unity gli è stato dato un Tag apposta, un nome proprio diciamo).
Codice:
   public int scoreValue;
   private GameController gameController;

   void Start ()
   {
       GameObject gameControllerObject = GameObject.FindWithTag ("GameController");
       if (gameControllerObject != null)
       {
           gameController = gameControllerObject.GetComponent <GameController>();
       }
       if (gameController == null)
       {
           Debug.Log ("Cannot find 'GameController' script");
       }
   }


Poi se c'è collisione ecc.. si chiede a quel GC (il SOLO!) di incrementare il punteggio (AddScore) di un certo valore, per poi proseguire distruggendo sparo e asteroide :
Codice:
       gameController.AddScore (scoreValue);
       Destroy(other.gameObject);
       Destroy(gameObject);

Il GC (che ricordo è UNICO) dentro il suo codice fa quello che abbiamo detto:
Codice:
   public void AddScore (int newScoreValue)
   {
       score += newScoreValue;
       UpdateScore ();
   }

Quindi per riassumere, il punteggio deve appartenere allo script2 che deve essere un oggetto UNICO, che si deve occupare di incrementarlo quando lo script1 (o tutti gli altri) lo richiede e deve anche mostrarlo (e questo già lo fa se ho capito bene).

Più semplice è la soluzione di Roll a Ball https://unity3d.com/learn/tutorials/proj...list=17141 qui usa sempre un oggetto unico il PlayerController (che gestisce il movimento e le collisioni della pallina, anche lui per sua natura UNICO). Questo oggetto ha la variabile punteggio ed è lui stesso ad incrementarla con le collisioni e ad aggiornare a video il testo.

Mi auguro di non averti fatto più confusione, ci sono molti modi per gestire la faccenda dei punti e questo è uno di quelli.

Parto col dirti che ho dato una letta veloce alla tua risposta e ti ringrazio,la soluzione che mi hai proposto tu l'avevo gia vista in precedenza,ma visto che ho aggiornato unity,il "giochino" che avevo fatto,nella nuova versione non si apriva quindi ho riiniziato da capo tutto e questa volta non ho seguito i tutorial ma ho usato un po di intuito fino ad arrivare a questo punto dove mi sono bloccato per una stupidezza.
ti posto i due script :
Codice:
using UnityEngine;
using System.Collections;

public class HUD : MonoBehaviour
{
    ShopController shopcontroller = new ShopController();
    Enemy enemy = new Enemy();
    public int score;

    void Awake()
    {
        shopcontroller.Start ();
    }

    void Update ()
    {
        shopcontroller.TempoRimanente -= Time.deltaTime;
        enemy.Update();
    }
    public void OnGUI()
    {
        if (shopcontroller.TempoRimanente > 0)
        {
            GUI.Label (new Rect (Screen.width / 10, Screen.height / 10, 100, 50), "Time:" + (int)shopcontroller.TempoRimanente);
            Debug.Log ("Start");
        }
        else if (shopcontroller.TempoRimanente <= 0)
        {    
            GUI.Label (new Rect (Screen.width / 10, Screen.height / 10, 100, 50), "Game Over:");
            Debug.Log ("GAME OVER");
        }
        GUI.Label (new Rect (Screen.width / 10, Screen.height / 8, 100, 50), "score:" + score);
        GUI.Label (new Rect (Screen.width / 10, Screen.height / 5, 100, 50), "Colpi:" + shopcontroller.colpi);
    }
}
Codice:
using UnityEngine;
using System.Collections;

public class Enemy : MonoBehaviour
{
    public int score;
    public int newscore = 1;
    public GameObject[] m_Enemy = new GameObject[3];
    EnemyController enemy = new EnemyController();

    public void Start()
    {
        m_Enemy [0] = transform.FindChild ("Cylinder").gameObject;
        m_Enemy [1] = transform.FindChild ("Cylinder (1)").gameObject;
        m_Enemy [2] = transform.FindChild ("Cylinder (2)").gameObject;

    }
    public void Update()
    {
        Addscore ();
    }

    public void Addscore()
    {
        if (m_Enemy [0] == null)
        {
            m_Enemy[0] = transform.FindChild ("scoreG").gameObject;
            {
            score += newscore;
            Debug.Log ("punteggio");
            }
        }
        if (m_Enemy [1] == null)
        {
            m_Enemy[1] = transform.FindChild ("scoreG").gameObject;
            {
                score += newscore;
            }
        }
        if (m_Enemy [2] == null)
        {
            m_Enemy[2] = transform.FindChild ("scoreG").gameObject;
            {
                score += newscore;
            }
        }
    }
}
 
Rispondi
#4
A parte il fatto che non è ben applicato il concetto di programmazione ad oggetti salta subito all'occhio l'errore della classe Enemy (che estende Monobehaviour) instanziata con la keyword new.
 
Rispondi
#5
(20-10-2016, 11:31 AM)carloss Ha scritto: A parte il fatto che non è ben applicato il concetto di programmazione ad oggetti salta subito all'occhio l'errore della classe Enemy (che estende Monobehaviour) instanziata con la keyword new.

grazie per il tuo feedback,potresti dirmi in che cosa sbaglio(nel concetto)?l'errore che intendi è questo:
Codice:
public class HUD : MonoBehaviour
{
   ShopController shopcontroller = new ShopController();
   Enemy enemy = new Enemy(); <-------- QUESTO????
   public int score;
.......
o questo
Codice:
using UnityEngine;
using System.Collections;

public class Enemy : MonoBehaviour <--------- QUESTO???
{
.......
e perchè è sbagliato?
 
Rispondi
#6
Sinceramente il concetto di programmazione ad oggetti non sono in grado di spiegartelo in poche parole ma è quello che ha cercato di farti capire Chip. Ti verrà naturale applicarlo col tempo dopo aver fatto molta pratica, ti consiglio di iniziare con piccoli progetti.

Riguardo alla classe che estende Monobehaviour questa può essere instanziata aggiungendola a un game object tramite la funzione addcomponent().

Un altro errore che ho notato è che nella classe HUD vai a chiamare il metodo Enemy.Update(). Enemy essendo una classe che estende Monobehaviour va a chiamare in automatico Update() ad ogni ciclo. il metodo Update non può essere chiamato da una classe esterna.

Puoi risolvere dichiarando la classe Enemy senza estenderla a Monobehaviour e eliminando Start e Update, vai a chiamare il metodo AddScore() dalla classe HUD.
In questo modo risolvi l'errore ma resta il fatto che concettualmente non è il massimo, non dovrebbe essere l'HUD ad aggiornare lo stato della classe Enemy. E' importante la modularità soprattutto quando il progetto diventa di un certo peso.

Poi per ottimizzare il codice non usare metodi Find ad ogni Update, piuttosto usa delle variabili per salvare cosa ti serve.
 
Rispondi
#7
Ragazzi/e ho un grandissimo problema.....oggi che ho un po ti tempo voglio,anzi volevo sistemare i miei script usando i vostri consigli,però non so come mai quando carico il "gioco" si blocca Unity e non si sblocca più,ho provato liberare memoria pensando che magari c'era poca memoria per gestire il programma,ma niente...
Sapete darmi qualche consiglio??
 
Rispondi
  


Discussioni simili
Discussione Autore Risposte Letto Ultimo messaggio
  attivare eventi con i collider NatakuZ 5 715 13-02-2013, 11:52 AM
Ultimo messaggio: NatakuZ

Vai al forum:


Browsing: 1 Ospite(i)