Cómo llamar funciones y leer variables de otro script en Unity. Comunicación entre Scripts

Introducción

En este artícu­lo vamos a ver cómo lla­mar fun­ciones y leer vari­ables que están definidas en otro Script en Uni­ty, además tienes un con­jun­to de vídeos impor­tantes que hablan en pro­fun­di­dad sobre este tema.

Esto de lla­mar fun­ciones y leer vari­ables que están definidas en otro script te va a ayu­dar a crear solu­ciones más potentes, ya que per­mite ten­er scripts espe­cial­iza­dos en tar­eas especí­fi­cas y que otros scripts lean su infor­ma­ción o util­i­cen sus fun­ciones cuan­do lo necesiten.

ACERCA DE ESTE VÍDEO

En este vídeo vemos cómo lla­mar a una FUNCIÓN que está defini­da en otro script y cómo ACCEDER A UNA VARIABLE que está en otro script en Unity.

MI LISTA DE REPRODUCCIÓN SOBRE UNITY
👇🏽

¿Qué se debe tener en cuenta?

Antes de ver una apli­cación conc­re­ta, dejo una lista de pun­tos a ten­er en cuen­ta que con­sidero son impor­tantes para enten­der todo el fun­da­men­to detrás de la inter­ac­ción entre Scripts.

Sobre los Scripts

En este caso vamos a ver un ejem­p­lo en Uni­ty, así que los dos Scripts que vamos a uti­lizar van a ser exten­sión de la clase MonoBe­hav­iour. Esto en tér­mi­nos prác­ti­cos sig­nifi­ca que al ini­ciar el juego, se eje­cu­tará un méto­do Start() y entre cada frame del juego se eje­cu­tará el méto­do Update().

Sobre la ejecución de los Scripts

Para que estos Scripts se eje­cuten, deben estar asig­na­dos a uno o más GameOb­jects de la jer­ar­quía. Es decir debe exi­s­tir una Instan­cia de la clase defini­da en el Script.

Instancias de una clase

Cuan­do añadi­mos un mis­mo Script a dos GameOb­jects dis­tin­tos esta­mos cre­an­do dos instan­cias sep­a­radas de la clase, es decir dos obje­tos que van a ser sim­i­lares porque pertenecen a la mis­ma clase, pero su esta­do no nece­sari­a­mente será el mis­mo. Aquí puedes ver las difer­en­cias entre las clases de pro­gra­mación y los obje­tos.

Contar con las REFERENCIAS de los objetos

Esto es uno de los pun­tos fun­da­men­tales a los que hay que prestar aten­ción e inten­tar enten­der en profundidad.

Los obje­tos son las instan­cias de una clase y para poder acced­er a su fun­cional­i­dad debe­mos ten­er la ref­er­en­cia de este obje­to, es decir encon­trar­lo de entre todos los obje­tos pre­sentes en el pro­gra­ma y ten­er­lo alma­ce­na­do en un cam­po para poder utilizarlo. 

Esto es sim­i­lar a cuan­do quer­e­mos usar una vari­able, nece­si­ta­mos ten­er defini­da dicha vari­able para poder uti­lizarla en el Script.

El operador punto

El oper­ador pun­to en var­ios lengua­jes de pro­gra­mación nos per­mite acced­er a los cam­pos y méto­dos definidos como públi­cos den­tro de una clase.

Si ten­emos la ref­er­en­cia del obje­to, podremos uti­lizar el oper­ador pun­to para eje­cu­tar cualquiera de sus méto­dos públi­cos o leer y escribir cualquiera de sus cam­pos públicos.

Ejemplo práctico de Comunicación entre Scripts en C# — Unity

Pasos previos

En un proyec­to cualquiera de Uni­ty creamos dos Scripts, Scrip­tA y ScriptB, en el primero definire­mos la fun­ción que será eje­cu­ta­da des­de el otro Script.

scripts c sharp que se comunican entre si en unity
Fig. 1: Creamos dos Scripts lla­ma­dos Scrip­tA y ScriptB.

En la jer­ar­quía vamos a crear dos emp­ty GameOb­jects para poder crear instan­cias de ambos Scripts.

jerarquia de un proyecto en unity, gameobjects
Fig. 2: Creamos dos Emp­ty GameOb­jects en la jer­ar­quía para que con­tengan ambos Scripts.

En el GameOb­jec­tA agreg­amos como com­po­nente el Scrip­tA y al GameOb­jectB el ScriptB. Esto podemos hac­er­lo des­de el inspec­tor con el botón Add Com­po­nent o hacien­do drag and drop.

boton add component para agregar componentes a los gameobjects en unity
Fig. 3: Selec­cionamos el obje­to A y en el inspec­tor, uti­lizan­do Add Com­po­nent, agreg­amos Scrip­tA a sus componentes.
inspector de un gameobject en unity, drag and drop de componentes
Fig. 4: Otra for­ma de agre­gar com­po­nentes es arras­trar­los direc­ta­mente al inspec­tor del GameObject.

Código dentro de los Scripts

Vamos a escribir las instruc­ciones que usare­mos para resolver la comu­ni­cación entre Scripts. En este caso uti­li­zo Visu­al Stu­dio como edi­tor de código.

Abri­mos ambos Scripts y nos encon­tramos algo de códi­go ya escrito.

scripts c sharp por defecto en unity
Fig. 5: Abri­mos ambos Scripts en algún edi­tor. Podemos ver algo de códi­go ya escrito.

En el primer Script vamos a escribir el sigu­iente código:

comunicacion entre dos scripts en unity, un script ejecuta una funcion definida en otro script
Fig. 6: Cam­pos y méto­dos pertenecientes al Script A.

Un string públi­co lla­ma­do "name" que nos servirá para iden­ti­ficar de qué instan­cia se trata.

Dos méto­dos lla­ma­dos Function1 y Function2, el primero públi­co y el segun­do privado.

El méto­do públi­co será la fun­ción que podremos eje­cu­tar des­de cualquier otro Script uti­lizan­do el oper­ador punto. 

Como vemos en la figu­ra 6 lo que hace es imprim­ir en con­so­la lo que devuelve el méto­do Function2. Este méto­do devuelve un tex­to con­cate­na­do que per­mite ver quién está eje­cu­tan­do el méto­do Function1 y de qué instan­cia de la clase Scrip­tA se tra­ta. Esto se enten­derá mejor más adelante.

Aho­ra vamos a tra­ba­jar en el Script B, que será el que llame a la fun­ción defini­da en el otro Script A. En la figu­ra 7 vemos las instruc­ciones del ScriptB.

comunicacion entre dos scripts en unity, un script ejecuta una funcion definida en otro script
Fig. 7: Cam­pos y méto­dos pertenecientes al Script B.

Defin­i­mos un string para asig­nar un nom­bre y saber de qué instan­cia se trata.

Para poder eje­cu­tar fun­ciones definidas en otro Script debe­mos ten­er la ref­er­en­cia del obje­to que es instan­cia de esa clase. Así que ten­emos que definir un obje­to de tipo Scrip­tA al que le damos el nom­bre "scrip­tA" (primera letra con minús­cu­la), como vemos en la línea 13 de la figu­ra 7.

Esto es sólo la mitad del tra­ba­jo, hemos declar­a­do que el ScriptB va a ten­er una ref­er­en­cia de un obje­to de tipo Scrip­tA, pero aún no hemos encon­tra­do dicha referencia.

Para encon­trar la ref­er­en­cia de un obje­to en un Script hay varias for­mas, en este caso voy a uti­lizar el méto­do Find­Ob­jectOfType<> de MonoBe­hav­iour, a este méto­do le ingre­samos el tipo de obje­to que tiene que bus­car y devolverá la ref­er­en­cia del primer obje­to de ese tipo que encuen­tre en la jer­ar­quía. Ver línea 18 de la figu­ra 7.

Ver otras for­mas de encon­trar ref­er­en­cias en Unity

Por últi­mo eje­cu­ta­mos la fun­ción defini­da en el otro Script A des­de este Script B (línea 20 de la figu­ra 7).

Operador punto

Como men­cionamos con ante­ri­or­i­dad, el oper­ador pun­to nos per­mi­tirá acced­er a todos los cam­pos y méto­dos públi­cos definidos den­tro de la clase.

En las fig­uras 8 y 9 vemos que uti­lizan­do la ref­er­en­cia del obje­to del Script A segui­da de un pun­to, podemos ver la lista de los cam­pos y méto­dos que podemos utilizar.

En la figu­ra 8 vemos el cam­po name que era el string definido como públi­co en el Scrip­tA y en la figu­ra 9 vemos el méto­do Function1, tam­bién definido como públi­co. Lo que no vemos es el méto­do Function2 ya que fue declar­a­do como privado.

operador punto para acceder a campos y metodos publicos definidos en un script, programacion basica, unity
Fig. 8: El oper­ador pun­to nos per­mite leer y escribir el cam­po "name", que es un string definido como público.

operador punto para acceder a campos y metodos publicos definidos en un script, programacion basica, unity
Fig. 9: El oper­ador pun­to nos per­mite eje­cu­tar el méto­do "Function1" definido como público.

Primera prueba de ejecución

Antes de dar­le al botón Play, selec­cionamos los GameOb­jects A y B e ingre­samos nom­bres en los cam­pos "name" que nos per­mi­tan saber de qué obje­to se trata.

La instan­cia del Script A se lla­mará "George (A)" y la instan­cia del Script B se lla­mará "Mike (B)", como vemos en las fig­uras 10 y 11.

inspector de un gameobject en unity, scripts que se comunican entre si, programacion basica en unity
Fig. 10: En el inspec­tor del GameOb­jec­tA, ponemos un nom­bre para saber que se tra­ta de esa instan­cia de la clase Script A.

inspector de un gameobject en unity, scripts que se comunican entre si, programacion basica en unity
Fig. 11: En el inspec­tor del GameOb­jectB, ponemos un nom­bre para saber que se tra­ta de esa instan­cia de la clase Script B.

Al cor­rer el juego vemos en el inspec­tor del GameOb­jectB que el cam­po Scrip­tA aho­ra mues­tra un obje­to (a difer­en­cia de la figu­ra 11 en la que decía "none").

Esto sig­nifi­ca que el ScriptB pudo encon­trar la ref­er­en­cia del ScriptA.

En la figu­ra 13 se mues­tra el men­saje en pan­talla, impre­so por el méto­do Function1 del Scrip­tA, que fue lla­ma­do des­de el ScriptB. 

El men­saje dice: "Mike(B) ha eje­cu­ta­do mi Function1. Por cier­to soy George(A)".

inspector de un gameobject en unity, scripts que se comunican entre si, programacion basica en unity
Fig. 12: Al cor­rer el juego se encuen­tra la ref­er­en­cia del obje­to Scrip­tA debido a la instruc­ción FindObjectOfType<>.

imprimir mensajes en consola en unity, scripts que se comunican entre si,programacion basica unity
Fig. 13: Este men­saje se imprime debido a que se eje­cu­ta un méto­do definido en Scrip­tA des­de el ScriptB.

Segunda prueba de ejecución

Vamos a pro­fun­dizar un poco el con­cep­to de obje­to de pro­gra­mación como instan­cia de una clase. 

Elegi­mos el GameOb­ject A de la jer­ar­quía y agreg­amos una segun­da instan­cia de la clase Scrip­tA usan­do el botón "Add Com­po­nent" o drag and drop.

Esta segun­da instan­cia se lla­mará "Luke (A)", en la figu­ra 14 vemos ambas instan­cias de la clase.

inspector de un gameobject en unity, scripts que se comunican entre si, programacion basica en unity
Fig. 14: Se agre­ga una segun­da instan­cia de la clase Scrip­tA al GameOb­jec­tA con un nom­bre distinto.

Al cor­rer el juego así como está, vemos en la con­so­la que Mike (B) ha eje­cu­ta­do el méto­do Function1 de Luke (A), ver figu­ra 15.

Lo que ha ocur­ri­do aquí es que la instruc­ción Find­Ob­jectOfType<> en la línea 18 de la figu­ra 7, ha encon­tra­do la ref­er­en­cia de un solo obje­to de tipo Scrip­tA, el que hemos lla­ma­do Luke (A).

imprimir mensajes en consola en unity, comunicacion entre scripts, programacion basica unity
Fig. 15: Al cor­rer el juego aho­ra vemos que se está eje­cu­tan­do el méto­do Function1 de la instan­cia lla­ma­da Luke.

Vamos a mod­i­ficar el códi­go en ScriptB para que sea capaz de encon­trar todas las ref­er­en­cias de Scrip­tA que haya en la esce­na y eje­cute el méto­do Function1 de cada una de ellas.

A con­tin­uación se mues­tra el prob­le­ma resuelto:

script c sharp que ejecuta funciones definidas en otros scripts, ejemplo en unity, comunicación entre scripts
Fig. 16: Mod­i­fi­camos de esta for­ma el ScriptB para que eje­cute las fun­ciones de las dos instan­cias de ScriptsA

En la declaración del obje­to aho­ra hemos definido un array o vec­tor de obje­tos tipo Scrip­tA (línea 13 figu­ra 16), esto quiere decir que podremos guardar muchas ref­er­en­cias de obje­tos ScriptsA.

En la línea 18 de la figu­ra 16 el cam­bio es algo sutil, en lugar de eje­cu­tar Find­Ob­jectOfType<> se eje­cu­ta Find­Ob­ject­sOfT­ype<>, esto hace que se encuen­tren todas las ref­er­en­cias que haya de ese objeto.

Lo últi­mo que hace­mos es recor­rer el array de obje­tos Scrip­tA uti­lizan­do un bucle fore­ach y eje­cu­tar­le a todos ellos el méto­do Function1, como se obser­va en las líneas 20 a 23 de la figu­ra 16.

inspector de un gameobject en unity, scripts que se comunican entre si, programacion basica en unity
Fig. 17: Al cor­rer el juego vemos que se encuen­tran las dos ref­er­en­cias de los obje­tos Scrip­tA y las ten­emos alma­ce­nadas en el array.

Al cor­rer nue­va­mente el juego, vemos que aho­ra en el inspec­tor del GameOb­jectB ten­emos las ref­er­en­cias de los obje­tos Scrip­tA (figu­ra 17), ten­emos un array de dimen­sión 2.

Como se obser­va en la figu­ra 18, en con­so­la aho­ra se impri­men dos men­sajes, el primero cor­re­sponde a la eje­cu­ción del méto­do Function1 de Luke y el segun­do a la eje­cu­ción de Function2 de George.

imprimir mensajes en consola en unity, comunicacion entre scripts, programacion basica unity
Fig. 18: En la con­so­la vemos que se eje­cu­tan los méto­dos Function1 de cada obje­to ScriptA.

Tercera prueba de ejecución

Vamos a mod­i­ficar nue­va­mente el ScriptB para ver otra for­ma de obten­er las ref­er­en­cias de los obje­tos y así poder lla­mar a sus fun­ciones des­de otro Script.

En este caso, en el ScriptB, vamos a declarar dos obje­tos tipo Scrip­tA seri­al­iza­dos (tam­bién pueden ser públi­cos, la idea es que aparez­can en el inspec­tor). Estos obje­tos se van a lla­mar "scrip­tALuke" y "Scrip­tA­George".

Luego en el méto­do Start vamos a eje­cu­tar los méto­dos Function1 direc­ta­mente usan­do estos obje­tos. En este caso no es nece­sario encon­trar las ref­er­en­cias ya que las asignare­mos direc­ta­mente en el inspector.

A con­tin­uación se mues­tra el ScriptB modificado. 

script c sharp que ejecuta funciones definidas en otros scripts, ejemplo en unity, comunicación entre scripts
Fig. 19: Mod­i­fi­camos el ScriptB de esta for­ma para pro­bar otra man­era de ten­er la ref­er­en­cia de los objetos.

En el inspec­tor podemos ver los nuevos cam­pos para los obje­tos tipo Scrip­tA (figu­ra 20).

inspector de un gameobject en unity, scripts que se comunican entre si, programacion basica en unity
Fig. 20: En el inspec­tor ten­emos cam­pos para dos obje­tos tipo ScriptA.

Vamos a mod­i­ficar un poco los GameOb­jects de la jer­ar­quía, vamos a ten­er un Emp­ty GameOb­ject lla­ma­do A‑Luke y otro lla­ma­do A‑George.

jerarquia de un proyecto en unity, gameobjects
Fig. 21: En lugar del GameOb­jec­tA vamos a ten­er dos emp­ty GameOb­jects para cada instan­cia de la clase ScriptA.

En cada GameOb­ject asig­namos el com­po­nente Scrip­tA y com­ple­ta­mos el nom­bre cor­re­spon­di­ente, ver fig­uras 22 y 23.

inspector de un gameobject en unity, scripts que se comunican entre si, programacion basica en unity
Fig. 22: En el GameOb­ject A‑Luke agreg­amos el com­po­nente Scrip­tA e ingre­samos el nom­bre correspondiente.

inspector de un gameobject en unity, scripts que se comunican entre si, programacion basica en unity
Fig. 23: En el GameOb­ject A‑George agreg­amos el com­po­nente Scrip­tA e ingre­samos el nom­bre correspondiente.

Aho­ra vamos a tomar los GameOb­jects de la jer­ar­quía y asig­nar­los en los cam­pos cor­re­spon­di­entes del ScriptB

jerarquia de un proyecto en unity, gameobjects
Fig. 24: Con estos GameOb­jects hare­mos drag and drop en los cam­pos de ScriptB.

En las fig­uras 25 y 26 vemos que las ref­er­en­cias han sido asig­nadas man­ual­mente, esto sig­nifi­ca que se podrán eje­cu­tar sus respec­tivos méto­dos Function1.

inspector de un gameobject en unity, scripts que se comunican entre si, programacion basica en unity
Fig. 25: Podemos asig­nar direc­ta­mente el GameOb­ject al cam­po cor­re­spon­di­ente siem­pre que entre sus com­po­nentes hay un obje­to de ese tipo.

inspector de un gameobject en unity, scripts que se comunican entre si, programacion basica en unity
Fig. 26: Las ref­er­en­cias de ambos obje­tos Scrip­tA han sido asig­nadas a los cam­pos correspondientes.

En con­so­la vemos que se impri­men los men­sajes pro­duc­to de la eje­cu­ción de Function1.

imprimir mensajes en consola en unity, comunicacion entre scripts, programacion basica unity
Fig. 27: Al cor­rer el juego vemos que se eje­cu­tan los méto­dos Function1 de ambas instancias.

Antes de ter­mi­nar me gus­taría cam­biar el orden de eje­cu­ción de los méto­dos Function1 en el ScriptB, como se ve en la figu­ra 28.

script c sharp que ejecuta funciones definidas en otros scripts, ejemplo en unity, comunicación entre scripts
Fig. 28: Inver­ti­mos el orden de las instruc­ciones y real­izamos otra prueba.

Al hac­er esto y cor­rer nue­va­mente el juego vemos que los men­sajes en con­so­la cam­bian de lugar, figu­ra 29.

imprimir mensajes en consola en unity, comunicacion entre scripts, programacion basica unity
Fig. 29: Vemos que los men­sajes cam­bian el orden de apari­ción en consola.

Conclusión

Hemos vis­to cómo lla­mar a fun­ciones que están definidas en un Script des­de otro Script, a lo que le dimos el nom­bre infor­mal "Comu­ni­cación entre Scripts".

Para que esto se pue­da hac­er, el méto­do o fun­ción a eje­cu­tar debe estar declar­a­do como públi­co, lo que per­mite acced­er­lo des­de con­tex­tos externos.

Además debe­mos ten­er la ref­er­en­cia del obje­to que con­tiene ese méto­do a eje­cu­tar, esto se puede lograr de varias for­mas, en este artícu­lo vimos tres man­eras de hac­er­lo, tenien­do en cuen­ta de que puede haber más de un obje­to que con­tiene el méto­do a ejecutar.

Enten­der en pro­fun­di­dad el con­cep­to de obje­to de pro­gra­mación, el cual es la instan­cia de una clase y de que para acced­er a sus cam­pos y méto­dos públi­cos debe­mos ten­er la ref­er­en­cia de ese obje­to, podemos con­stru­ir solu­ciones más com­ple­jas y vamos entran­do en el tema de la pro­gra­mación ori­en­ta­da a objetos.

Si pre­fieres algo más detal­la­do sobre cómo usar des­de un Script las fun­ciones que están definidas en otros Scripts te recomien­do ver el sigu­iente video, es más exten­so porque resuel­vo des­de cero un ejer­ci­cio que con­siste en dos Scripts que se comu­ni­can entre sí para pedirse infor­ma­ción o darse órdenes.

Ver índice de con­tenidos y tiem­pos de interés de este video

1 Comment
Inline Feedbacks
View all comments
YouTube
Scroll al inicio
Secured By miniOrange