# help with dynamically creating a wall

Hi all,

Just wondering on the maths or programming approach to creating a dynamic ‘wall’ (lets worry about x,y only to simplify)

The steps to create our dimensions for the wall would be that the user can click on the screen - drag the mouse to a new position - and a ‘wall’ is created. This can be done with the line renderer but ultimately I would prefer to use a wall of sorts, so I can use a collider (extra problem perhaps?) to then utilize all the collision functions for later purposes.

I have tried a few experiments - scaling an object, creating objects at the mouse position etc, even mesh creation, but cant seem to imagine where to go next.

For a mesh - My stumbling block appears to be in calculating the coordinates
For a prefab - I dont know how I can click down on mouse to create a new wall ‘hold’ onto the end of a small wall and ‘drag’ it to another position and let mouse go to almost ‘draw’ the wall.

I like the mesh idea because in small steps I could

1. create the mesh
2. create the mesh at the mouse position
3. create the mesh at the mouse position and control certain coordinates while mouse down, to then ‘drag and drop’ the wall end point.

In fact, just typing that out gives me an idea on how I can achieve it in a way with step 3 haha…

Thoughts?

Cheers
Matt

I think this method:
You can Instantiate prefab walls with a fix size.
First, check the initial position of the click and then check the final position when you release the click.
Substract the first position to the final position to create the director vector.
Then check the vector’s magnitude and divide it by wall’s x size to get the number of walls needed
Create a new coordinated reference system from the initial position whit its x or z axis in the director vector direction.
Last, instantiate a wall using the number of walls obatained and the wall’s size.

I don’t know if you will get an answer worthy of action without explaining a lot more about your game. For example…

• Will this be in 3D?
• Is there a brick-like texture which can’t stretch or a procedural texture that doesn’t rely on UVs?
• Do you want to click an open end on this wall then drag out the new wall with a visual update of some kind? Does it have to be the wall or will a solid colored icon work? Is it possible to drag it out and fail a drop-point check, meaning are there plac
es where it can’t be droped? Should it snap in to place? etc…

Thanks Rafes, fair questions.

• The game is orthographic, top down - staring into Z.
• Essentially a swipe on the screen will draw the wall at a later stage, each swipe removing the previous wall and creating a new one from swipe start to swipe end.
• I dont have any critical textures for it. I can apply that later but I would probably just start with a straight material colour as you are viewing it top down.
• The wall is thin, with depth to cater for the Z axis and colliders which will come into play to block objects.
• The viewing area is to be fairly small, no scrolling, just the same view. So on screen is the entire playing area.
• Im not worried about snapping at this stage, and likely dont want it.

During some more testing, I initially thought I could ‘attach’ one side of the wall (is like a peg initially size:1,1,10), the attached side rotating and dragging the vertex points as I moved the mouse around till I released the mouse. I am drawing the ‘peg’ by creating an empty game object and adding the mesh. This way I can control the required vertices - once I work it out

Cheers

Cheers

Another possibility would be to skin a wall in a 3D package, like Maya (skin binding). Just use a flat heirarchy of two joints placed exactly at the edge of the mesh and skin the wall to them. Then in Unity you can put down one joint and drag the other.

Probably overkill, but just through I would share. I’d say a line renderer is a great choice though. Very light and easy to texture.

Does the line renderer render ‘depth’ ?
I might have a quick look at that object.

This is what I have so far - creating a box at the mouse position that rotates, but I cant figure out how to ‘drag’ the right edge to wherever the mouse goes, this is where my maths is failing me. Its the code if the ‘else’ block. I think initially I should rotate the ‘wall’ game object to be facing down the Z as well, its probably making my calculations goes extra screwed.

Thoughts?

I will investigate the line renderer.

Cheers

``````using UnityEngine;
using System.Collections;

public class Player : MonoBehaviour {

// wall material
public 	Material 	wall_material;
public 	GameObject 	camera; 		// main camera
private GameObject 	wall;			// the player wall, drawn by the player on screen (turn into array to support more then 1 line)
private Mesh 		mesh;			// the mesh we create and attach

#region wall vertex stuff

// builds our 'wall'
private Vector3[] vertices = new Vector3[]
{// Front face
new Vector3(-1.0f, -1.0f,  1.0f),
new Vector3( 1.0f, -1.0f,  1.0f),
new Vector3( 1.0f,  1.0f,  1.0f),
new Vector3(-1.0f,  1.0f,  1.0f),

// Back face
new Vector3(-1.0f, -1.0f, -1.0f),
new Vector3(-1.0f,  1.0f, -1.0f),
new Vector3( 1.0f,  1.0f, -1.0f),
new Vector3( 1.0f, -1.0f, -1.0f),

// Top face
new Vector3(-1.0f,  1.0f, -1.0f),
new Vector3(-1.0f,  1.0f,  1.0f),
new Vector3( 1.0f,  1.0f,  1.0f),
new Vector3( 1.0f,  1.0f, -1.0f),

// Bottom face
new Vector3(-1.0f, -1.0f, -1.0f),
new Vector3( 1.0f, -1.0f, -1.0f),
new Vector3( 1.0f, -1.0f,  1.0f),
new Vector3(-1.0f, -1.0f,  1.0f),

// Right face
new Vector3( 1.0f, -1.0f, -1.0f),  // 16
new Vector3( 1.0f,  1.0f, -1.0f),  // 17
new Vector3( 1.0f,  1.0f,  1.0f),  // 18
new Vector3( 1.0f, -1.0f,  1.0f),  // 19

// Left face
new Vector3(-1.0f, -1.0f, -1.0f),
new Vector3(-1.0f, -1.0f,  1.0f),
new Vector3(-1.0f,  1.0f,  1.0f),
new Vector3(-1.0f,  1.0f, -1.0f)
};

// these are the original vertices for the right side
private Vector3[] tempVertices = new Vector3[]
{
new Vector3( 1.0f, -1.0f, -1.0f),
new Vector3( 1.0f,  1.0f, -1.0f),
new Vector3( 1.0f,  1.0f,  1.0f),
new Vector3( 1.0f, -1.0f,  1.0f),
};

private int[] triangles =
{
0,  1,  2,      0,  2,  3,    // front
4,  5,  6,      4,  6,  7,    // back
8,  9,  10,     8,  10, 11,   // top
12, 13, 14,     12, 14, 15,   // bottom
16, 17, 18,     16, 18, 19,   // right
20, 21, 22,     20, 22, 23    // left
};

private bool mesh_created = false;

#endregion

// Use this for initialization
void Start ()
{

}

// Update is called once per frame
void Update ()
{
// create a new object, first get mouse position:
Vector3 mpos = Input.mousePosition;
mpos.z = Mathf.Abs(camera.transform.position.z);
Vector3 spos = camera.GetComponent<Camera>().ScreenToWorldPoint(mpos);

if (Input.GetMouseButton(0))
{
if (!mesh_created)
{
// instantiate wall with required mesh stuff
wall =  new GameObject();
wall.transform.position = spos;
wall.transform.rotation = Quaternion.identity;
//wall.transform.localScale = new Vector3(1.0f,0.1f,0.1f);

// lets create a new mesh for the game object
mesh = new Mesh();
wall.GetComponent<MeshFilter>().mesh = mesh;
mesh.vertices = vertices;
Vector2[] uvs = new Vector2[vertices.Length];

int i = 0;
while (i < uvs.Length)
{
uvs[i] = new Vector2(vertices[i].x, vertices[i].z);
i++;
}

// create uvs, triangles used and the normals!
mesh.uv = uvs;
mesh.triangles = triangles;
mesh.RecalculateNormals();

// set material
wall.transform.renderer.material = wall_material;
mesh_created = true;
}
else
{
// rotate with mouse
wall.transform.LookAt(spos);

// lets manipulate the vertices...
spos.z = 0;
vertices[12] = spos - tempVertices[0];
vertices[13] = spos - tempVertices[1];
vertices[14] = spos - tempVertices[2];
vertices[15] = spos - tempVertices[3];

mesh.vertices = vertices;
}
}

if (Input.GetKeyUp(KeyCode.Space))
{
Destroy(wall);
}

}
}
``````

Looks like the line renderer will not do what I was hoping, I really need it to be a ‘thick’ object, how thick can vary, but ideally I can finish off the script in the else block…

thoughts anyone?

Then the game isn’t orthographic and top-down. It is top-down but “perspective”. An orthographic camera would only see the top of the wall if looking straight down. I just wanted to point out this vocab for communications-sake. Sorry i don’t have time to dig in to code at the moment. I’m trying to get something released and I got distracted

On the plus side, the thing I’m trying to release is a constraint package for Unity and it will be free. If you can get your mesh doing what you want, you can use our look-at constraint to make the center look at the mouse position. It isn’t complex code but it is very convenient.

Thanks for the help Rafes,

The Camera is set to orthographic, starting down the Z, so haha not technically ‘top down’, but this is probably where I am making things awkward.

in a nutshell, that ‘wall’ you can draw should be able to be collided with, hence the idea that I need some kind of depth to it to account for a collider and all the goodness that comes with one.

2 ways to approach:

1. the current way, I am drawing the wall ‘live’ so to speak
2. plot the line initially, (mouse down, drag, mouse up) then draw in the box.

My head keeps telling me 2 would be easier, but 1 is much nicer, though 2 might help me understand where I am going wrong.

Thoughts?

Cheers

A box collider does not need a mesh to work, you can have a line with no depth and still have a box collider on the wall. You just have to set it’s size, etc, once you have a set wall, unless you need it to collide while drawing of course. You only need the mesh to render stuff you can actually see.

Rafes: Of course! I cant believe I forgot about that, I have done it previously when mucking about.

so :

1. Create GameObject,
2. Attach Line Renderer, try for ‘live’ draw option
3. Attach collider to Line Renderer
4. Increase Depth of collider as per requirements.

Mate, will give it a try later and let you know how it goes, thank you so much for the help so far!

One gotcha in this idea is that a box collider is not on the line renderer, it is on the GameObject with the line renderer component. You will need to orient the GameObject to match the line renderer to get the box to align before you can begin to set the size to match. I’m not sure if you can do this post “drop” or if you need to get the game object to point at the pointer in Y (or whatever) only.

You could try to generate the mesh yourself and attach colliders, but if I were in your position I’d look at UniTile in the asset store. It’s a tile editor that generates meshes for use in a top down or side scrolling game and automatically attaches colliders.

Sometimes having the source code that someone else wrote will help: http://www.mudloop.com/unitile

I’m not affiliated with UniTile, but I bought it.

Hi all see attached:

``````using UnityEngine;
using System.Collections;

public class Player : MonoBehaviour {

// wall material
public 	Material 	wall_material;
public 	GameObject 	camera; 		// main camera
private GameObject 	wall;			// the player wall, drawn by the player on screen (turn into array to support more then 1 line)
private LineRenderer lineRenderer;
private bool 		wall_created = true;

// Use this for initialization
void Start ()
{

}

// Update is called once per frame
void Update ()
{
// create a new object, first get mouse position:
Vector3 mpos = Input.mousePosition;
mpos.z = Mathf.Abs(camera.transform.position.z);
Vector3 spos = camera.GetComponent<Camera>().ScreenToWorldPoint(mpos);
spos.y = 0; // reset our Y

if (Input.GetMouseButtonDown(0))
{
if (wall_created)
{
// kill it first
Destroy(wall);

// instantiate wall
wall =  new GameObject();
wall.transform.position = spos;
wall.transform.rotation = Quaternion.identity;

// the line renderer!
lineRenderer.SetPosition(0,spos);
lineRenderer.SetWidth(0.1f,0.1f);

// add a material to the game object
wall.renderer.material = wall_material;

// we have not finished creating it until the mouse button is up....
wall_created = false;
}
}

if (Input.GetMouseButton(0))
if (wall) lineRenderer.SetPosition(1,spos);

if (Input.GetMouseButtonUp(0))
wall_created = true;
}
}
``````

Have ended up using the line renderer, but I also moved the camera to correctly stare down the Y for proper top down

In saying that I have been briefly playing with the colliders to find my best option, which appears to be a mesh collider.
Ideally I want to do from now is attach the collider with some depth in the Y.

In my perfect ‘it just worked this way’ world I would want to:

• Get the line renderer mesh coordinates in world space (or perhaps the actual mesh itself?)
• Create a mesh (or use the line renderer mesh)
• manipulate the mesh to give it the slight depth and extra width
• attach the mesh collider to the line renderer game object
• attach the new padded mesh I created to the mesh collider

If anyone can point me in a less painful direction that would be great, otherwise I will investigate a few options including the above.

Cheers

Mesh colliders are the slowest and your only mesh is the line renderer, which is all you need to render your game (it sounds like), so making more mesh just to use a slow collider only makes sense if you need a really complex shape. I would think a wall is square though, which means a cube collider (the second-fastest) would be perfect…?

Hey Mate,

I agree with you for sure except the box collider does not align itself around the plane nicely, it adds a heap of extra space along z and x when the line is drawn on an angle - and no y. Give it a try and attach a box collider, you’ll see my problem.

In saying that, the idea of getting the coordinates and making my own mesh is indeed to create my own box, but by supplying the actual coordinates of a simple box mesh, which then acts as the collider is so I dont have to try and manipulate any other collider to fit (change angles, use a heap of maths to turn it around and move it in to place)

I dont think its going to be a massive issue as the collider mesh I make is pretty much a box collider.

Actually - haha just talking about this gives me an idea - given I have the start and end coordinates of the line:

1. get new points using cross product of start and end coordinates to create points x distance away from ends (at a right angle) I would need to create 6 extra points (3 on each ‘end’), which I think I can do using the cross product as it always gets the point at the right angle…This creates the ‘edge’ quads.

2. then create the 6 quads needed for the box collider

3. attach as the mesh

4. hopefully drink a beer with a smile.

Thoughts?

Any mesh collider will be slow. It shouldn’t matter if you make a snake or a box since it will have to process the faces (I’m assuming). I’m not sure I understand why you can’t use a box. A box can be sized and oriented anyway you want.

• Find the center-point between the two end-points for the position of the game object.
• Then rotate the game object to point at one of the end points.
• The size of the box collider should be the distance between the two points (maybe divided by 2). The width would be based on the line width and the height is irrelevant except for working with the physics stuff.

I think this should work?

Thanks Rafes,

I will give this a try tonight, I think thats a sound idea. Much easier then my method!
I might have scared myself away from the box collider idea though due to orientation issues.

Im not able to check right now, but I believe the collider orientation is dependant on the game object orientation.

With this in mind, I will need to

• create the game object,
• get the angle as you mention (angle between two vectors)
• rotate
• attach the line.

Im my mind it presents itself nicely and the box should be immediately around the line ‘mesh’
I can then just increase the collider dimensions - but without testing in front of me haha, I am blowing hot air.

Thoughts?

That is how my mind makes it work too. I just hope Unity agrees =D

Damn!

Unfortunately this result ended up the same as before. Rotating the game object did nothing to change how the box collider creates itself by default.

However I came to realise I may not need depth on the wall anyway for the moment or indeed if at all.

As I will be testing it as a blocker for a ball or similar object, that object itself can have the collider depth/breadth/whatever and as long as it collides, even with a flat collider on the wall, thats fine.

Will do some more tests to check the collision function are entered.

Cheers