Unity Pomoc przy optymalizacji kodu.

0

Bawie sie w unity i zrobilem podnoszenie i respawn ale nie dziala do konca tak jak chcialem. Nie moge zebrac wszystkich Od razu drzew poniewaz odradza sie ostatnie. Musze czekac az pierwsze drzewo ktore podnioslem sie z respawnuje potem kolejne i czekac i tak w kolko. Co tu w tym kodzie zmienic ? Czy wgl napisac to wszystko od nowa tylko na co zwrocic uwage?
Licznikdrzew.cs -

using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using UnityEngine;
using UnityEngine.UI;

public class LicznikDrzew : MonoBehaviour
{
    RespawnDrzew respawnDrzew;
    int numberOfDrzewa;
    public Text counterView;
    public Text sellDrzewoText;
    private bool wlaczliczenie;
    public Vector3 vecto;//wektor drzewa do odrodzenia
    // Start is called before the first frame update
    void Start()
    {
        respawnDrzew = GameObject.Find("PickUpDrzewa").GetComponent<RespawnDrzew>();
        if (respawnDrzew == null)
        {
            Debug.LogError("respawn nie znaleziono");
        }
        //wlaczliczenie = true;
        resCounter();
        //StartCoroutine(waiter());
    }

    public void IncrementCounter()
    {
        numberOfDrzewa++;
        counterView.text = numberOfDrzewa.ToString();
        sellDrzewoText.text = counterView.text;
        wlaczliczenie = true;
        StartCoroutine(waiter());
    }
    public void resCounter()
    {
        numberOfDrzewa = 0;
        counterView.text = numberOfDrzewa.ToString();
    }
    
    IEnumerator waiter()
    {      
        //
        yield return new WaitForSecondsRealtime(4);
        if (wlaczliczenie == true)
        {
                respawnDrzew.reSpawn();
                wlaczliczenie = false;   
        }

    }
}

RespawnDrzewa.cs

using System.Collections;
using System.Security.Cryptography;
using UnityEngine;

public class RespawnDrzew : MonoBehaviour
{
   public GameObject myPrefObj;
    LicznikDrzew licznikDrzew;
    void Start()
    {

        licznikDrzew = GameObject.Find("Manager").GetComponent<LicznikDrzew>();
        if (licznikDrzew == null)
        {
            Debug.LogError("Licznik drzew nie znaleziono");
        }

    }
    public void reSpawn()
    {
        Debug.LogError("Doszedlem tu");
        Debug.LogError(licznikDrzew.vecto.ToString());
        Instantiate(myPrefObj, licznikDrzew.vecto, transform.rotation);
    }
    // Update is called once per frame
    void Update()
    {
        
    }
}

PickUpDrzewo.cs

using System.Collections;
using UnityEngine;

public class PickUpDrzewo : MonoBehaviour
{
    LicznikDrzew licznikDrzew;
    void Start()
    {
        licznikDrzew = GameObject.Find("Manager").GetComponent<LicznikDrzew>();
        if(licznikDrzew == null)
        {
            Debug.LogError("Licznik drzew nie znaleziono");
        }
    }
    // Update is called once per frame
    void OnTriggerEnter2D(Collider2D other)
    {
        if(other.gameObject.name == "Player")
        {
            Destroy(this.gameObject);
            licznikDrzew.vecto = gameObject.transform.position;
            licznikDrzew.IncrementCounter();
        }
    }
}
0

Przydałoby się to jeszcze raz napisać.

Licznik drzew jest tylko jeden na scenie, prawda?
On posiada jedną wspólną zmienną wlaczliczenie dla wszystkich Coroutine waiter. A ta korutyna może być uruchomiona wiele razy przy każdym zebranym drzewku.
Pewnie jest więcej źle, ale to tak na początek...

Każde drzewko powinno być odpowiedzialne za swój respawn. Nie niszcz obiektu, tylko ukrywaj (SetActive(false/true)).
Pamiętaj tylko, że jeśli drzewko będzie miało coroutine, to obiekt z jego skryptem nie może być nieaktywny. Deaktywujesz tylko grafikę, która jest child objectem.

0

Zrobilem cos takiego ale nie chce sie pojawic. Co zrobilem zle ?

using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using UnityEngine;
using UnityEngine.UI;

public class PickUpApple : MonoBehaviour
{
    public Text textApple;
    public GameObject DoUkrycia;
    private bool objVisible = true;
    public int CzasOdrodzenia = 0;
    int number;
    // Start is called before the first frame update
   void OnTriggerEnter2D(Collider2D other)
    {
        if(other.gameObject.name == "Player")
        {
            number = Int32.Parse(textApple.text);
            number += 1;
            textApple.text = number.ToString();
            objVisible = false;
            DoUkrycia.SetActive(objVisible);
            StartCoroutine(ReSpawn());
        }
    }
    IEnumerator ReSpawn()
    {
        yield return new WaitForSecondsRealtime(1);
        if(objVisible == false)
        {
            objVisible = true;
            DoUkrycia.SetActive(objVisible);
        }
    }
}
0

Nie chce się pojawić, ale znika poprawnie?

Czy obiekt wskazywany przez DoUkrycia to dziecko obiektu, do którego jest podpięty skrypt PickUpApple?

1

Odpowiedź do komentarza, który nie powinien być komentarzem...

Hierarchy

Wyobraź sobie, że Twój obiekt ze skryptem "PickUpApple" to Parent, a obiekt "DoUkrycia" to Child.

0

Zrobilem cos takiego i dziala dla wielu obiektow. Pytanie czy ta opcja jest zla ?

using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using UnityEngine;
using UnityEngine.UI;

public class PickUpApple : MonoBehaviour
{
    public Text textApple;
    public GameObject DoUkrycia;
    private bool objVisible = true;
    public int CzasOdrodzenia = 0;
    int number;
    // Start is called before the first frame update
    
   void OnTriggerEnter2D(Collider2D other)
    {
        if(other.gameObject.name == "Player")
        {
            number = Int32.Parse(textApple.text);
            number += 1;
            textApple.text = number.ToString();
            objVisible = false;
            DoUkrycia.SetActive(objVisible);
            //StartCoroutine(ReSpawn());
            Invoke("ReSpawnn", 5);
        }
    }
    IEnumerator ReSpawn()
    {
        yield return new WaitForSecondsRealtime(1);
        if(objVisible == false)
        {
            objVisible = true;
            DoUkrycia.SetActive(objVisible);
        }
    }
    void ReSpawnn()
    {
        if (objVisible == false)
        {
            objVisible = true;
            DoUkrycia.SetActive(objVisible);
        }
    }
}
1

Nieźle kombinujesz ;)

Ale ja wolałbym używać Coroutine, bo przy refaktorze musisz pamiętać o stringu w Invoke...

Nawet w dokumentacji to zalecają https://docs.unity3d.com/ScriptReference/MonoBehaviour.Invoke.html

For better performance and maintability, use Coroutines instead.

1 użytkowników online, w tym zalogowanych: 0, gości: 1