El cuadro de selección
Ahora vamos a hacer el cuadro de selección. Para ello vamos a utilizar unaGUITexture, a la que le he metido una textura que he hecho fácilmente con cualquier programa que maneje transparencias. Consiste en una imagen PNG de un único pixel verde a la que he añadido una transparencia del 15% llamada «selection.png» que he puesto en una carpeta nueva llamada «Textures».
Los elementos GUI se dibujan directamente en pantalla, es decir, no tienen ninguna profundidad y, por tanto, no ocupan un espacio tridimensional. Esto es imprescindible para hacer los menús, el HUD, o este cuadro de selección.
Igual que hicimos con los cazas, vamos a crear un Prefab llamado «SelectionBox» dentro de la carpeta «Resources» (¡¡recordad que si no no nos funcionará!!), y vamos a arrastrar el GUITexture que hemos creado en él. Y ya podemos borrarlo del Hierarchy.
Ahora vamos a hacer que nuestro cuadro se dibuje. Para ello volvemos al «GameLogicScript» y esta vez vamos a trabajar sobre el Update. ¿Qué vamos a hacer?
Cuando el usuario inicie un cuadro de selección, vamos a tirar un rayo (clase Ray) desde la posición de nuestro puntero, y vamos a guardar el primer punto 3D en el que colisione (propiedad RaycastHit.point). ¿Por qué? Porque si guardásemos simplemente el punto de la pantalla, al mover la cámara éste cambiaría con respecto a la malla tridimensional, que es donde realmente está apuntando el jugador. Una vez sepamos dónde comienza nuestro cuadro de selección, a la hora de dibujarlo tan sólo necesitaremos pasar sus coordenadas de mundo a las coordenadas de pantalla respecto a la posición actual de la cámara. De este modo, el cuadro no hará cosas raras cuando se mueva la cámara.
El nuevo código del «GameLogicScript» va a quedar así:
- using UnityEngine;
- using System.Collections;
- using System.Collections.Generic;
- public class GameLogicScript : MonoBehaviour
- {
- InputHandlerScript _input;
- //Lista de cazas
- List<gameobject> _fighters;
- //Cuadro de selección
- GameObject _selectionBox;
- //Origen de la selección actual
- Vector3 _selectionOrigin;
- //Con esta variable sabemos si hemos comenzado una selección
- bool _selecting;
- // Use this for initialization
- void Start ()
- {
- //Guardamos la referencia al input en nuestra clase
- _input = this.GetComponent<InputHandlerScript>();
- //Inicializamos la lista
- _fighters = new List<GameObject>();
- //Vamos a crear 3 cazas
- GameObject fighter = Resources.Load(«FighterObject») as GameObject;
- GameObject fighter1 = GameObject.Instantiate(fighter, new Vector3(831, 1, 961), Quaternion.identity) as GameObject;
- GameObject fighter2 = GameObject.Instantiate(fighter, new Vector3(841, 1, 961), Quaternion.identity) as GameObject;
- GameObject fighter3 = GameObject.Instantiate(fighter, new Vector3(851, 1, 961), Quaternion.identity) as GameObject;
- //Añadimos los cazas a la lista
- _fighters.Add(fighter1);
- _fighters.Add(fighter2);
- _fighters.Add(fighter3);
- }
- // Update is called once per frame
- void Update ()
- {
- DrawSelectionBox();
- }
- void DrawSelectionBox()
- {
- if (!_selecting)
- {
- //Si no estamos seleccionando, comprobamos que si se ha pulsado la tecla de selección
- if (_input._selectingBegins)
- {
- RaycastHit hit;
- Ray ray;
- //Lanzamos un rayo desde la pantalla de nuestra cámara, tomando como punto la posición de nuestro puntero
- ray = Camera.main.ScreenPointToRay(_input._mousePosition);
- if (Physics.Raycast(ray, out hit))
- {
- //Guardamos el punto tridimensional en el que colisiona nuestro rayo.
- _selectionOrigin = hit.point;
- //Creamos el cuadro de selección
- _selectionBox = GameObject.Instantiate(Resources.Load(«SelectionBox»)) as GameObject;
- _selectionBox.guiTexture.pixelInset = new Rect(_input._mousePosition.x, _input._mousePosition.y, 1, 1);
- //Indicamos que hemos empezado una selección
- _selecting = true;
- }
- }
- }
- else
- {
- //Si ya hemos comenzado una selección, comprobamos que ésta no ha acabado
- if (_input._selectingEnds)
- {
- //Destruimos el cuadro de selección
- Destroy(_selectionBox);
- //Indicamos que hemos finalizado nuestra selección
- _selecting = false;
- }
- else
- {
- //Estos son los límites de nuestro cuadro de selección
- Rect bound = _selectionBox.guiTexture.pixelInset;
- //Con esta sencilla función pasamos el origen de la selección a coordenadas de pantalla
- Vector3 selectionOriginBox = Camera.main.WorldToScreenPoint(_selectionOrigin);
- //Recogemos los límites de nuestro cuadro en función del punto de origen y la posición actual del puntero
- bound.xMin = Mathf.Min(selectionOriginBox.x, _input._mousePosition.x);
- bound.yMin = Mathf.Min(selectionOriginBox.y, _input._mousePosition.y);
- bound.xMax = Mathf.Max(selectionOriginBox.x, _input._mousePosition.x);
- bound.yMax = Mathf.Max(selectionOriginBox.y, _input._mousePosition.y);
- //Cambiamos el pixelInset de nuestro cuadro de selección
- _selectionBox.guiTexture.pixelInset = bound;
- }
- }
- }
- }
- </gameobject>
Nos fijamos que hemos introducido unas cuantas propiedades más en nuestro proyecto. Si lo lanzamos ya deberíamos ver cómo se dibuja perfectamente nuestro cuadro de selección, manteniendo la coherencia respecto al espacio tridimensional aún cuando movemos la cámara.
Me encants está sección *O* ,antes daba un poco de programación,nada del otro mundo pero ya se me ha olvidado casi todo T^T
hace un mes o dos colgamos un tutorial más simple para mover un objeto por la pantalla =P
Sí, la verdad es que este tutorial me ha quedado un poquito bastante denso.
Espero que con el código fuente, por lo menos la gente pueda trastear y ver cómo está todo si se pierden en algún punto del tutorial y no les sale ;).
Buenas, estaba trasteando y me he quedado un poco colgado en la primera parte con el script, me da un error en la linea 14
«GameObject fighter = Resources.Load(“FighterObject”)»
Podrias poner de nuevo la fuente de ejemplo para ver como está la jerarquia y despejar mis dudas? Porque da error.
Gracias