Ancoreig 20 Report post Posted April 26, 2020 (edited) Buenas a todos, hay un concepto que no entiendo y leyendo el título no os habréis enterado de nada, me explico. Estoy empezando en Unity y estoy siguiendo tutoriales básicos. El primer tutorial que estoy siguiendo se trata de un juego básico que eres un cuadrado y que tienes que comerte a tus enemigos (círculos) con un contador de por medio; si llega a 0 sin haberte comido a todos los enemigos pierdes, y si te los comes a todos antes de llegar a 0 pues ganas. Os dejo 2 de los scripts; el Jugador y el contador: public class Player : MonoBehaviour { //las variables que son public, aparecen en Unity y, por ejemplo, podríamos modificar la velocidad del jugador desde //unity, no así enemiesKilled por ejemplo, ya que no es pública public float velocidadJugador; int enemiesKilled; public Text countDownText2; //nos creamos un objeto de nuestra clase EnemySpawner public EnemySpawner enemySp; // Start is called before the first frame update void Start(){ } // Update is called once per frame void Update(){ //comprobamos que el usuario está pulsando la tecla de Flecha arriba if(Input.GetKey(KeyCode.UpArrow)){ //movemos la posición de Y hacia arriba 1 en un segundo, y dejamos la posición X igual transform.position = new Vector2(transform.position.x, transform.position.y + velocidadJugador * Time.deltaTime); } else if(Input.GetKey(KeyCode.DownArrow)){ transform.position = new Vector2(transform.position.x, transform.position.y - velocidadJugador * Time.deltaTime); } else if(Input.GetKey(KeyCode.LeftArrow)){ transform.position = new Vector2(transform.position.x - velocidadJugador * Time.deltaTime, transform.position.y); } else if(Input.GetKey(KeyCode.RightArrow)){ transform.position = new Vector2(transform.position.x + velocidadJugador * Time.deltaTime, transform.position.y); } } void OnTriggerEnter2D(Collider2D other){ //comprobamos el choque por el tag del objeto. El objeto tiene que tener seteado el tag if(other.CompareTag("Enemy")){ Destroy(other.gameObject); enemiesKilled++; //comprobamos si los enemigos que hemos matado es igual al número de enemigos totales gracis a a nuestro método que nos creamos en nuestra clase EnemySpawner //(tenemos que poner la variable pública y en nuestro player asignársela en unity) if(enemiesKilled == enemySp.GetNumberOfEnemies()){ countDownText2.text = "Ganaste"; //paralizamos el tiempo para mostrar que hemos ganado -> establecido a 0 es tiempo congelado, fijado a 1 es //tiempo normal (supongo que 2 será el doble de rápido, etc) Time.timeScale = 0; } } } public void SetVelocidadJugador(float velocidadModificada){ velocidadJugador = velocidadModificada; } } using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class CountDown : MonoBehaviour{ Text countDownText; float timer; int countDownNumber = 20; public Player jugador; // Start is called before the first frame update void Start() { //accedo al componente Text y lo asigno a mi variable countDownText = GetComponent<Text>(); //accedo a la propiedad texto de mi objeto Texto y se lo cambio a 20, que es el valor al que la he iniciado countDownText.text = countDownNumber.ToString(); } // Update is called once per frame void Update() { //básicamente, Time.deltaTime es igual a 1 segundo. timer += Time.deltaTime; //Así pues, si ha pasado 1 segundo Y countDownNumber es mayor que cero, le restaré uno al contador if(timer >=1 && countDownNumber > 0){ countDownNumber--; countDownText.text = countDownNumber.ToString(); timer = 0; //si el tiempo llega a 0, mostramos que hemos perdido y ralentizamos al jugador if(countDownNumber == 0){ countDownText.text = "Perdiste"; jugador.SetVelocidadJugador(1); } } } } No venía en el tutorial y se me ocurrió que, por ejemplo, cuando perdieses se modificase la velocidad del jugador a 1 (está a 5 en el inspector). Así que en el script del jugador le hice un setter de la velocidad y en el script del contador me instancié un objeto del jugador y se lo seteé a 1 su velocidad. En este punto es donde no entiendo el concepto, es decir, creía que con el seteo ese iba a ser suficiente, pero después de probar el juego unas cuantas de veces no iba. Así que después de darle un par de vueltas, en mi script del contador, hice público mi objeto Player y ya en el inspector, le asigné al objeto contador el script del jugador y ahí sí que ya funcionó, pero sigo sin entender el por qué no funciona solo con el seteo. Un saludo! Edited April 26, 2020 by Ancoreig Share this post Link to post Share on other sites
Alex 43 Report post Posted April 26, 2020 Tal vez porque la variable que almacenaba a tu jugador en el script contador estaba vacía, dices que creaste un setter en el player y otro en el contador, pero nunca dices que hiciste referencia entre los dos para activar la función. Para que un objeto tenga influencia a otro, debe tener una referencia de él, puedes obtener el objeto, Transform, el script o crear un namespace para hacer referencia a la función del otro GameObject. 1 Share this post Link to post Share on other sites
AngelFG 15 Report post Posted April 26, 2020 (edited) Es lo que dice Alex. En programación orientada a objetos, el definir un objeto que pertenece a una clase no llega (tú defines un objeto de nombre 'jugador' que pertenece a la clase Player (que es el nombre del Script). Después de definir un objeto de una clase tienes que instanciarlo (es decir, darle memoria) o modificar su referencia para que 'apunte' a otro objeto ya instanciado previamente (que es lo que haces gráficamente cuando arrastras a la ventana Inspector el GameObject Player. Lo que haces realmente es asociar al componente Player (que es un script) a la variable public que defines en tu script CountDown). Normalmente (o por lo menos es lo que hago yo), al GameObject Player se le suele asociar el tag Player y después, dentro del script, se referencia al player de la siguiente forma: public class CountDown : MonoBehaviour { private Player player; private void Awake() { GameObject goPlayer = GameObject.FindGameObjectWithTag("Player"); if (goPlayer == null) { Debug.Log("Tag Player no encontrado"); } else { player = goPlayer.GetComponent<Player>(); } } } Si no sabes como asociar un Tag a un GameObject puedes consultar este enlace Edited April 26, 2020 by AngelFG 1 Share this post Link to post Share on other sites
Ancoreig 20 Report post Posted April 27, 2020 Gracias a ambos! Me queda más claro Share this post Link to post Share on other sites