c # pass data from one class to another

1

Good! I had done an exercise where I created a button for each file that I read in an xml.In the code that I leave down in line 4 I pass the game data to the init of another class, and then in the other class I'm doing what I want with that data. I was wondering how I could do something similar but with this code.

Code to create buttons and then call the Init to pass the data

Código:
foreach (var juego in data.Juegos) {
            AppButton button = Instantiate(buttonPrefab);
            button.transform.SetParent(layout);
            button.Init(juego);
        }

init code that is in another class

Código:
public void Init(Juego game) {
        this.game = game;

        LoadTexture();
    }

and now with this code how could I do something similar to the above? I want to pass the data of data and images to the init that is in another class.

Código:
if (Directory.Exists(rutasapp))
        {
            foreach (string dataApp in Directory.GetDirectories(rutasapp))
            {
                GameObject button = Instantiate(buttonPrefab) as GameObject;
                button.transform.SetParent(layout);
                button.name = "Button" + layout.childCount;


                foreach (string data in Directory.GetFiles(@dataApp).Where(s => s.EndsWith(".exe") || s.EndsWith(".lnk")))
                {
                    if (Path.GetExtension(@data) == ".exe")
                    {
                        button.GetComponent<Button>().onClick.AddListener(() => Process.Start(data));
                    }
                }




                foreach (string imagenes in Directory.GetFiles(@dataApp).Where(s => s.EndsWith(".png") || s.EndsWith(".jpg")))
                {
                    if (Path.GetExtension(@imagenes) == ".png")
                    {
                        string imgPath = imagenes;

                    }
                }
            }

the init of the other class is the same as the one above, which I have to modify here?

Código:
public void Init(Juego game) {
        this.game = game;
        LoadTexture();
    }
    
asked by JuanPerez 09.04.2017 в 00:42
source

1 answer

1

There are many ways to do what you ask, I will leave some, not necessarily one is better than the other, will depend on many factors, in addition to their knowledge, as to how to use and when to use them.

tl; dr

  • have a variable of the type of the class that receives the data, within the class from which you want to send the data. assign the reference and call the method by passing the parameters. To assign the reference you can use:

    • based on Tag: su_variable = GameObject.FindWithTag("nombre_tag_gameobject").GetComponent<LaClaseQueReciveLosDatos>();

    • based on passing the GameObject from the editor and using su_variable = ob.GetComponent<LaClaseQueReciveLosDatos>();

  • using delegates;

  • using UnityEvents

1st basanda en tag;

look on the internet if you do not know how to create and use tag in unity and apply it to objects, I think the answer will be a little long , so yes, I have space I leave a catch, how it's done.

Once you have the tag put in GameObject .

We modified the code;

using System;
using System.Collections.Generic;
using UnityEngine;

//cambiar nombre por el nombre de la clase suya que tiene los datos (el script)
class LaClaseQueTieneLosDatos: MonoBehaviour{ 
//..

    //cambiar nombre por el nombre de la clase suya que va a recivir los datos (el script)    
    private LaClaseQueReciveLosDatos receptora = null; 
    private List<string> data = new List<string>();
    private List<string> imagenes = new List<string>();

    void Awake(){
        receptora = GameObject.FindWithTag("nombre_tag_gameobject").GetComponent<LaClaseQueReciveLosDatos>();
    }
//..

            foreach (string dataApp in Directory.GetDirectories(rutasapp))
            {
                GameObject button = Instantiate(buttonPrefab) as GameObject;
                button.transform.SetParent(layout);
                button.name = "Button" + layout.childCount;


                foreach (string data in Directory.GetFiles(@dataApp).Where(s => s.EndsWith(".exe") || s.EndsWith(".lnk")))
                {
                    if (Path.GetExtension(@data) == ".exe")
                    {
                        button.GetComponent<Button>().onClick.AddListener(() => Process.Start(data));

                     -->   this.data.Add(data); //añades en cada iterecion el string data
                    }
                }




                foreach (string imagenes in Directory.GetFiles(@dataApp).Where(s => s.EndsWith(".png") || s.EndsWith(".jpg")))
                {
                    if (Path.GetExtension(@imagenes) == ".png")
                    {
                        string imgPath = imagenes;

                       --> this.imagenes.Add(imagenes); //añades en cada iterecion el string imagenes
                    }
                }
            }

 //..
//Ahora la historia de pendera de si tienes acceso en esta clase a una instancia de Juego o similar "si se puede crear una ect"
//despues seguiremos aqui

}

if you have access to Juego in some way:

can add something like that in the class that is going to receive the data

LaClaseQueReciveLosDatos.cs

//..
private List<string> data = null
private List<string> imagenes = null

public void Init(Juego game, List<string> data, List<string> imagenes) {

    this.game = game;
    this.data = data;
    this.imagenes = imagenes;

    LoadTexture();
}
//..

if you DO NOT have access to Game in any way:

add something like that in the class that is going to receive the data

LaClaseQueReciveLosDatos.cs

//..
private List<string> data = null
private List<string> imagenes = null

public void Init(Juego game) {

    this.game = game;

    LoadTexture();
}
public void SetData(List<string> data) {

    this.data = data;
}
public void SetImagenes(List<string> imagenes) {

    this.data = data;
}

//..

IF you can use properties instead of using the seter like that, but remember that in unity you can not create properties with default values if you use the reflection "as far as I know" because it uses c # 4 and this I think is allowed only from c # 6.

Now going back to where we left off.

If we choose the first option we use this;

//..
receptora.Init(instacia_game, data, imagenes);
//..

If we choose the second option we use this;

//..
receptora.SetData(data);
receptora.SetImagenes(imagenes);
//..

if you use this last option you have to make sure that the instance of LaClaseQueReciveLosDatos (ie the object if it is inside the script) is already instantiated "I already believe it" ( IF YOU HAVE BEHAVIORS weird) of Script execution order but I'm not a fortune-teller, I only tell you so I can look on the internet to see how and how to use it.

2nd form, without using the tag , only the following is changed, the rest is the same.

//cambiar nombre por el nombre de la clase suya que tiene los datos
class LaClaseQueTieneLosDatos: MonoBehaviour{ 
//..
    public GameObject ob = null;
    //cambiar nombre por el nombre de la clase suya que va a recivir los datos
    private LaClaseQueReciveLosDatos receptora = null; 
    private List<string> data = new List<string>();
    private List<string> imagenes = new List<string>();

    void Awake(){
        receptora = ob.GetComponent<LaClaseQueReciveLosDatos>();
    }
//..

Now from the editor we drag the object , which has the script that Receive the data , in of the script field with the name ob, which is in the object that has the data .

3rd Now another way using delegates.

LaClaseQueTieneDatas.cs

using System;
using System.Collections.Generic;
using UnityEngine;

class LaClaseQueTieneLosDatos: MonoBehaviour{

    public int dato;

    public delegate void SeActualiza();
    public static event SeActualiza OnSeActualiza;

    void Start(){
        ActualizarDato(15);
    }

    void ActualizarDato(int dato){
        this.dato += dato;

        if(OnSeActualiza != null){
            OnSeActualiza();
        }
    }
}

LaClaseQueReciveLosDatos.cs

using UnityEngine;

class LaClaseQueReciveLosDatos: MonoBehaviour{
    void OnEnable(){
        //Subscribe to HealthUpdate event
        LaClaseQueTieneLosDatos.OnSeActualiza += HandleSiSeActualiza;
    }

    void HandleSiSeActualiza (){
        Debug.Log ("SeActualiza");
    }
}

link

If this way adapts to what you want, you just have to adjust it

4th is using UnityEvents.

I think it's better to look at the following link:

two are from the Unity documentation and another is a video, they are all in English, but you can look at them and if you have any questions you can look on the internet or post a specific question, about the part where you have doubts Well, I think that explaining it in text right now, it's a bit confusing to understand if you do not have some basis, and using images as support would be much longer.

    
answered by 16.04.2017 в 10:03