Índice del curso de Unity 3D

  1. Introducción
  2. Instalación
  3. Interfaz
  4. Conceptos básicos
  5. Ejercicio: cubos
  6. Cambiar el color de algo
  7. Introducción a C#
  8. Conceptos para realización de juegos 2D
  9. Acceder a componentes desde código
  10. Uso del transform
  11. User Interface
  12. Elije tu propia aventura
  13. Acierta imagen
  14. Sprites
  15. Fall Down Game
  16. Galería de tiro
  17. Corrutinas
  18. Flappy Bird
  19. PONG
  20. Carreras
  21. Panel Animator
  22. Plataformas
  23. Plataformas
  24. Puzzle con Raycast
  25. Plataformas con RayCast
  26. Memory (juego de las parejas)
  27. Guardar y recuperar información almacenada
  28. Máscara
  29. Publicación
  30. Ejercicio: First Person Shooter
  31. Multijugador con Photon
>

Puzzle con RayCast

Seleccionar una pieza (lanzar un rayo 2D y 3D)

Para que funcionen los rayos, cada pieza debe tener un BoxCollider y un RigidBody.

GameObject pieza;

void Update(){
	if(Input.GetMouseButtonDown(0)){
		seleccionarPieza ();
	}
}

void seleccionarPieza(){
	//Si estamos trabajando con Colliders 2D
	//RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero);
	//if (hit)

	//Si estamos trabajando con Colliders 3D
	Ray rayo = Camera.main.ScreenPointToRay (Input.mousePosition);
	RaycastHit hit;
	if (Physics.Raycast (rayo, out hit)) {
		if (hit.collider.gameObject.tag == "piezapuzzle") {
			distanciaRayo = hit.distance; //distanciaRayo será un valor que utilizaremos más adelante
			pieza = hit.collider.gameObject;
			Debug.Log (pieza);
		}	
	}
	
}

Mover pieza con RayCast

void seleccionarPieza(){
	...
	estaPulsado=true;
	...
}	

void Update(){
	if(estaPulsado){
		moverPieza ();
	}	
}

void moverPieza(){
	Ray rayo = Camera.main.ScreenPointToRay (Input.mousePosition);
	Vector3 limiteRayo = rayo.GetPoint (distanciaRayo);
	limiteRayo = new Vector3 (limiteRayo.x, limiteRayo.y, 0);
	pieza.transform.position = limiteRayo;
}

Explicación del método mover pieza.

Un rayo es infinito. Nos interesa mover la pieza al punto correcto de profundidad; por eso utilizamos la variable longitudRayo.

limiteRayo será el segmento que va desde la cámara, hasta el punto en que colisionamos con el bounding box de la pieza. Sin embargo, si la pieza tiene profundidad z=0, la bounding box tendrá una profundidad diferente y cada vez que llamemos a moverPieza() cambiaremos su ubicación, porque el origen de coordenadas de la pieza no coincide con el punto de impacteato, y la pieza se desplazará.

Unity 3D bounding box

Poner las piezas que se están moviendo por delante

    void seleccionarPieza(){
	...
	if (hit){
		ultimaFichaOrden++;
		pieza.transform.GetChild(0).GetComponent<SpriteRenderer>().sortingOrder = ultimaFichaOrden;
		pieza.transform.GetChild(1).GetComponent<TextMeshPro>().sortingOrder = ultimaFichaOrden;

Arrastrar y soltar

...
	if (Input.GetMouseButtonUp (0)) {
		soltarPieza ();
	}
...
void soltarPieza(){
	if (estaPulsado) {
		estaPulsado = false;
		pieza = null;
	}
}

Comprobar si he dejado la pieza sobre un area de la pantalla

Evaluar la distancia entre una ficha y otra en el momento de soltarla

public List<GameObject> fichasMoviles;
public List<GameObject> fichasSolucion;
public void ComprobarDrop(){
	bool acierto = false; ;
	for (int i = 0; i < fichasSolucion.Count; i++){
		if (Vector2.Distance(pieza.transform.position, fichasSolucion[i].transform.position) < 1){
			if (pieza.name == fichasSolucion[i].name){
				fichasSolucion[i].transform.GetChild(1).GetComponent<TextMeshPro>().text = pieza.name;
				Destroy(pieza.gameObject); //ficha seleccionada y ficha solucion son gameObjects
				fichasSolucion.RemoveAt(i);
				contadorSolucionesCorrectas++;
				if (contadorSolucionesCorrectas == 10){
					Debug.Log("Ganaste");
				}
				acierto = true;
				break;
			}   
		}   
	}
	if (!acierto){
		colocarPiezaEnPosicionesIniciales();
	}
}

Comparar la posición poniendo el código en la pieza en lugar de en el gamecontroller

Para que funcionen los métodos OnTriggerEnter y OnTriggerExit debe estar marcada la check Is Trigger del componente Box Collider.

También debemos asignar un Rigid Body a los objetos que van a moverse.

Piezapublic class Pieza : MonoBehaviour {
	
	public bool estaTocando;

	void OnTriggerEnter(Collider col){
		if (name=="piezaRosa" && col.GetComponent<Collider>().gameObject.name == "rosita") {
			estaTocando = true;
		}	

		if ( name=="piezaMorada" && col.GetComponent<Collider>().gameObject.name == "morado") {
			estaTocando = true;
		}
	}

	void OnTriggerExit(Collider col){
		if (name=="piezaRosa" && col.gameObject.name == "rosita" ) {
			estaTocando = false;
		}
		if (name=="piezaMorada" && col.gameObject.name == "morado") {
			estaTocando = false;
		}
	}
}
ControlEscenavoid comprobarCubos(){
	if (pieza.GetComponent<Pieza> ().estaTocando == true) {
		Debug.Log ("toca");
		Destroy (pieza);
	}
}

Destroy con transición

pieza.GetComponent<Animator> ().enabled = true;
Destroy (pieza, 1.0f);

Encajar piezas

public float margenError = 2;
public Vector3 [] posicionesFinales;

void Start(){
	...
	posicionesFinales = new Vector3[piezas.Length];
	for (int i = 0; i < piezas.Length ; i++) {
		posicionesFinales [i] = piezas [i].transform.position;
	}
}
void soltarPieza(){
	if (estaPulsado) {
		estaPulsado = false;
		colocar ();
		pieza = null;
	}
}

void colocar(){
	int numAux = 0;
	for (int i = 0; i < piezas.Length; i++) {
		if (piezas [i].gameObject == pieza) {
			Debug.Log ("coinciden");
			numAux = i;
			break;
		}
	}
	if (Vector3.Distance (piezas [numAux].position, posicionesFinales [numAux]) <= margenError) {
		Debug.Log ("encaja "+ numAux);			
		piezas[numAux].position= posicionesFinales [numAux];
	}	
}

Desordenar piezas

void desordenar(){
	for (int i = 0; i < piezas.Length; i++) {
		piezas [i].transform.position = new Vector3 (Random.Range(-5,5), Random.Range(-2,2), 0);
	}
}

Desordenar piezas al cabo de un tiempo

Invoke("desordenar", 2.0f);
icono de mandar un mailPreguntame lo que quieras!
Pablo Monteserín
contacta conmigoPablo Monteserín

El servicio de resolución de dudas técnicas es sólo para los usuarios premium. Si tienes cualquier otra duda, usa el formulario de contacto. ¡Gracias!