Noticias

¡RECUERDA QUE SI ERES UN NUEVO USUARIO, DEBES PRESENTARTE PARA PODER PUBLICAR MENSAJES! | TENEMOS CANAL OFICIAL DE TELEGRAM: t.me/unity3dspain

¿Reescalar objeto con cursor en ejes X y Z? [3D]

Iniciado por nightborn, Noviembre 17, 2015, 06:44:00 PM

Tema anterior - Siguiente tema
Hola, comunidad de Unity!He estado un tiempo off, pues he estado liado con el grado medio. Pero ahora he vuelto un poco por Unity, y esta vez con una duda. Tengo pensado hacer un juego donde necesitas construir (para nada está de moda). El caso es que no sé muy bien como hacer para construir un objeto en los ejes x y z: me explico.Quiero que tengas que crear unos cimientos para construir las paredes y demás encima de éstos. Para ello, tengo que saber cómo crear un cubo que ocupe unas dimensiones x & z, y que se reescale con el cursor. Esto sería muy parecido, por ejemplo, al sistema de construcción de los Sims.He intentado hacerlo de la siguiente manera, pero no ha funcionado del todo bien:
if (Input.GetMouseButton(0))
{
    GameObject foundation = objectToPlace;
    GameObject foundationCube = objectToPlace.transform.GetChild(0).gameObject;

    foundation.transform.position = new Vector3(
            firstClickPosition.x,
            0f,
            firstClickPosition.z
        );

    float x = firstClickPosition.x + hit.transform.gameObject.transform.position.x;
    float z = firstClickPosition.z + hit.transform.gameObject.transform.position.z;

    foundationCube.transform.localScale = new Vector3(x, foundationCube.transform.localScale.y, z);
}
¿Alguna idea de cómo hacerlo?¡Gracias por adelantado!

Yo es que no he entendido lo de reescalar. Pero según tu explicación pienso que quieres seleccionar el area donde vas a construir un edificio como todos estos juegos olvidados imposibles de encontrar en la store.En teoría, sin buscar por ahí entiendo que tienes que trasladar el puntero de la pantalla al mundo y donde colisiona tomas el puntero de inicio. Luego arrastras y tomas las coordenadas finales y las peudes limitar con math.clamp en ancho y profundo.
void OnMouseDown()
{
    screenPoint = Camera.main.WorldToScreenPoint(scanPos);


 offset = scanPos - Camera.main.ScreenToWorldPoint(
     new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));

}


void OnMouseDrag()
{
    Vector3 curScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z);


 Vector3 curPosition = Camera.main.ScreenToWorldPoint(curScreenPoint) + offset;
 transform.position = curPosition;

}
Creo que con eso podría servir. También hay ejemplos en la wiki incluso para dibujar un mesh creo recordar.

Noviembre 17, 2015, 08:04:38 PM #2 Ultima modificación: Noviembre 17, 2015, 08:05:07 PM por Edgargaza
Gracias por responder! ).

Noviembre 17, 2015, 10:37:02 PM #3 Ultima modificación: Noviembre 17, 2015, 10:41:59 PM por kaito
Lo he hecho de la siguiente manera. Tenemos 3 GameObjects:1º) GameObject a escalar. Un cubo.2º) Pivot o agarradera. Una esfera.3º) Quad invisible con collider, que servirá para obtener el hit.point. Desde un único script situado en el Pivot/Agarradera(Esfera), unimos estos tres elementos: 
using UnityEngine;
using System.Collections;

public class ResizeScript : MonoBehaviour {

public Transform GOAsociado; //GameObject a escalar
public MeshCollider meshCollider; //Plano-Collider para arrastrar(hit.point)
public Camera camara;

bool mouseDown = false;
Vector3 posicionInicialGOAsociado,
escalaInicialGOAsociado,
vector1 = Vector3.zero,
vector2 = Vector3.zero;



void Start(){

   this.posicionInicialGOAsociado = this.GOAsociado.position;
   this.escalaInicialGOAsociado = this.GOAsociado.localScale;

}

void Update () {

   if(this.mouseDown){

      if(Input.GetMouseButton(0)){

         Ray ray = this.camara.ScreenPointToRay(Input.mousePosition);
         RaycastHit hit;
         if(this.meshCollider.Raycast(ray,out hit,100f)){

            float hx = hit.point.x,          hz = hit.point.z;
            float tx = transform.position.x, tz = transform.position.z;
            vector1 += new Vector3(hx - tx, 0f, tz - hz);
            vector2 += new Vector3(hx - tx, 0f, hz - tz);

            this.GOAsociado.localScale = this.escalaInicialGOAsociado + vector1;
            this.GOAsociado.position   = this.posicionInicialGOAsociado + vector2 * 0.5f;
            this.transform.position    = hit.point;

         }

      } else this.mouseDown = false;

   }
      
}

void OnMouseDown(){

   this.mouseDown = true;

}

}
 Guardamos la posicion y escala inicial del GameObject a escalar(Cubo), y guardamos los incrementos de cambio de posicion en vector1(para calcular la escala) y vector2(para calcular la posicion). Enlace de descarga: http://www.speedyshare.com/dnuJw/resize.unitypackage">http://www.speedyshare.com/dnuJw/resize.unitypackage

[quote author=kaito date=1447796222" data-ipsquote="" data-cite="kaito" class="ipsQuote">Lo he hecho de la siguiente manera. Tenemos 3 GameObjects:1º) GameObject a escalar. Un cubo.2º) Pivot o agarradera. Una esfera.3º) Quad invisible con collider, que servirá para obtener el hit.point.    ...[/quote]Estoy un poco perdido. He descargado el paquete, he visto el ejemplo y he intentado adaptarlo a mis necesidades, pero no puedo. Necesitaría que se ajustase a un int (la escala, pues es un juego hecho por cubos). He puesto lo siguiente:
								

Noviembre 18, 2015, 02:41:56 PM #5 Ultima modificación: Noviembre 18, 2015, 02:42:06 PM por Edgargaza
¿Alguna ayuda más, por favor? BUMP

[quote author=Edgargaza" data-ipsquote-contapp="forums" data-ipsquote-contenttype="forums" data-ipsquote-contentclass="forums_Topic" data-ipsquote-contentid="34445" data-ipsquote-contentcommentid="123663">Estoy un poco perdido. He descargado el paquete, he visto el ejemplo y he intentado adaptarlo a mis necesidades, pero no puedo. Necesitaría que se ajustase a un int (la escala, pues es un juego hecho por cubos). He puesto lo siguiente:
Pero el Mathf.RoundToInt(...) no parece funcionar muy bien en este caso. Podrías hacerme una pequeña explicación? O si lo sacaste de algún tutorial, podrías pasarmelo, por favor?
 [/quote]He modificado el código y el proceso. Esta vez no necesitamos agarraderas. Pinchamos directamente sobre el objeto a escalar, el cubo, y utilizo la posición del ratón al que le aplico un factor de reducción para suavizar el escalado. Verás que es algo más sencillo: 
Vector3.zero;

void Start(){

   this.escalaInicial = this.GOAsociado.localScale;
   this.posicionInicial = this.GOAsociado.position;

}

void Update () {

   if(this.mouseDown){

      if(Input.GetMouseButton(0)){

         Vector3 mouse = Input.mousePosition;

         vector1 = new Vector3((mouse.x - old.x) * this.factor + vector1.x, 0f, (mouse.y-old.y) * this.factor + vector1.z);

         Vector3 temp = new Vector3(this.escalaInicial.x + (int)vector1.x, this.escalaInicial.y, this.escalaInicial.z + (int)vector1.z);

         if(temp.x != 0f && temp.z != 0f) {

            this.GOAsociado.localScale =  temp;
            if(justificado) this.GOAsociado.position = this.posicionInicial + (this.GOAsociado.localScale - this.escalaInicial) * 0.5f;

         }

         this.old = mouse;


      } else this.mouseDown = false;

   }
      
}

void OnMouseDown(){

   this.mouseDown = true;
   this.old = Input.mousePosition;

}

}
 Enlace de descarga: http://www.speedyshare.com/uYjGF/resize.unitypackage

[quote author=kaito date=1447880348" data-ipsquote="" data-cite="kaito" class="ipsQuote"> He modificado el código y el proceso. Esta vez no necesitamos agarraderas. Pinchamos directamente sobre el objeto a escalar, el cubo, y utilizo la posición del ratón al que le aplico un factor de reducción para suavizar el escalado. Verás que es algo más sencillo: 
using UnityEngine;using System.Collections;

public class ResizeScript : MonoBehaviour {

public Transform GOAsociado; //GameObject a escalar
public float factor = 0.025f;
public bool justificado = true;

bool mouseDown = false;
Vector3 old,
      escalaInicial,
      posicionInicial,
      vector1 = Vector3.zero;

void Start(){

   this.escalaInicial = this.GOAsociado.localScale;
   this.posicionInicial = this.GOAsociado.position;

}

void Update () {

   if(this.mouseDown){

      if(Input.GetMouseButton(0)){

         Vector3 mouse = Input.mousePosition;

         vector1 = new Vector3((mouse.x - old.x) * this.factor + vector1.x, 0f, (mouse.y-old.y) * this.factor + vector1.z);

         Vector3 temp = new Vector3(this.escalaInicial.x + (int)vector1.x, this.escalaInicial.y, this.escalaInicial.z + (int)vector1.z);

         if(temp.x != 0f && temp.z != 0f) {

            this.GOAsociado.localScale =  temp;
            if(justificado) this.GOAsociado.position = this.posicionInicial + (this.GOAsociado.localScale - this.escalaInicial) * 0.5f;

         }

         this.old = mouse;


      } else this.mouseDown = false;

   }
      
}

void OnMouseDown(){

   this.mouseDown = true;
   this.old = Input.mousePosition;

}

}
 Enlace de descarga: http://www.speedyshare.com/uYjGF/resize.unitypackage">http://www.speedyshare.com/uYjGF/resize.unitypackage[/quote]Ah, ya entendí como funciona! Perfecto, modifiqué unas cositas para ajustarlo a lo que necesito, y va de maravilla. Muchísimas gracias!Por cierto, si has hecho tú el código, me encanta como escribes las líneas, parece profesional xD

Etiquetas: