- Home /
Dynamically Change Length and Width of Cube by tracking Mouse
How do I access an object's mesh vertex? Id like to determine the distance between the X and Z distance from one vertex to the opposite. One of the extreme vertices would follow the mouse cursor based on a raycast, but when I attempt this it changes the size of the cube at the midpoints.
Below is a depiction of what I am trying to do:
UPDATE: So I implemented this into my game. Below is the code. You must use an empty gameobject as a parent. I aligned it so that the gameobject acts as a pivot point by placing it at the topleft corner of the cube. I then place the cube as a child to the block and attach this code:
using UnityEngine;
using System.Collections;
public class planBlock : MonoBehaviour {
public GameObject parent;
bool recordStart;
Vector3 startingposition;
float snapSize = 1;
void Start()
{
//get the parent
parent = this.transform.parent.gameObject;
}
private float Round(float input)
{
return BuildingManager.planSnapSize * Mathf.Round((input / snapSize)); //snapvalue of tile
}
// Update is called once per frame
void Update () {
//Debug.Log("Position: "+startingposition);
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit)) //need to ignore everything
{
if (Input.GetMouseButtonDown(0) && !recordStart)
{
recordStart = true;
startingposition = new Vector3(Round(hit.point.x), (Round(hit.point.y), Round(hit.point.z));
Debug.Log("Recorded"+ startingposition);
}
else if(Input.GetMouseButton(0)){
parent.transform.position = startingposition;
Vector3 scaleByMouse = new Vector3(Round(hit.point.x), 1, Round(hit.point.z));
//get difference from start to current
Vector3 difference = scaleByMouse - startingposition;
Debug.Log("Difference: " + difference);
Debug.Log("Scale by: " + scaleByMouse);
parent.transform.localScale = difference;
Debug.Log("Stay");
}
else if (Input.GetMouseButtonUp(0))
{
recordStart = false;
//to cancel
parent.transform.localScale = new Vector3 (1,1,1);
Debug.Log("OUT!");
}
else
{
parent.transform.position = new Vector3(Round(hit.point.x), (Round(hit.point.y), Round(hit.point.z));
}
}
}
}
Heres a gif of it in action:
Answer by cjdev · Jan 18, 2016 at 05:18 AM
You could get the vertices from the MeshFilter component, edit them directly, and then reassign the vertices to the mesh. The vertices are accessed like this:
yourCube.GetComponent<MeshFilter>().mesh.vertices
Also, you might want to use mesh.MarkDynamic();
if it's going to be moved around a lot.
Hello, thanks for your reply! Ill look into this but first, I just completed implementing this into my game. The original post has the code. Would my way be more performance efficient or should I go with the vertices?
Just to note there is only one Cube gameobject in the game and nothing else will be dynamically resized other than this single cube object. So performance may be negligible, correct?
Yeah, that's a clever way to implement it. I'd go with that if you don't need to move the block anymore afterwards, you might get problems with the scale affecting the translation and such in that case. And you're right, for just that object dynamically resizing it in pretty much any way isn't going to be an issue performance-wise.
Yea youre correct im getting issues with the scaling and planning. The translation of the parent to the child is offset and so when canceled and redone, the scaling messes up.
I had to do a quick fix where after I panned it, if the user canceled (in my cancel via right click on it) it will reset back to a cube attached to the cursor again. So undo the panning of the transform position relative to the parent and reset parents scale to 1,1,1: parent.transform.localScale = new Vector3(1, 1, 1); //reset box to be a regular cube
this.transform.localPosition = new Vector3(0.5f, 0, 0.5f); //reset the position of the transform in relation to cube
Thanks again for your help! Ill look into those vertices properties, ill find it useful soon. Also how would I do an efficient edge detection of my cube. Ie. The box is constructed but the user wants to grab an edge and pull it, kind of like re-sizing an OS native window (chrome for example).
For the edge detection, personally I'd get the location of the vertices that made up your edges. Then for each edge I'd transform them to screen coordinates with Camera.WorldToScreenPoint and create a 2d line equation on the screen with the two vertices of each edge. After that it would just be a matter of polling the mouse x,y position to see if it was a solution, or close to a solution, of one of the line segments.
Ah that makes perfect sense. Im researching and also found out I need to do a round for the float precision. Now ive worked with a lot of procedural mesh generation making static shapes but how would I go about to accomplish something like in the link below: I know it would involve procedural generating the mesh, update the extreme pair of vertices to the mouse vector 3 world position, rotating the vertices at fixed angles. But when completing the shape how would I attach or weld the beginning set of vertices to the last? Would I also call for a mesh update? Looking further into research right now is this spline based? I need a general idea, keywords or algorithms to look up as Im lost in the dark a bit.
Thanks for all your responses!
Your answer
Follow this Question
Related Questions
procedural generated mesh vertices are not connected in edges 1 Answer
What does mesh.MarkDynamic actually do? Documentation explains nothing. 1 Answer
Dynamic Tail Mesh 0 Answers
Creating 3D representation of procedurally generated 2D tile map 1 Answer
Why does this script put Unity into a not responding state? 0 Answers