Im fairly new to both Unity or C# or even anything GUI connected but im trying to make a simple hexagonal grid, i followed this tutorial: http://forum.unity3d.com/threads/procedural-hexagon-terrain-tutorial.233296/ and it created nice chunks of hexes. Now the thing is i'd like to make a borderline for each hex. I tried to use ToonShader but it doesn't seem to work with such structure. I also tried to make a LineRenderer in every hex, containing coordinates of it's edgepoints, but after some lurking I realised that I should probably use 6 LineRenderers for each hex. Here comes my question, does using so many LineRenderers makes any sense? Is there any more convinient (I'm sure there is) or prettier way to do this?
Thanks in advance.
LineRenderer supports more than one line, :) so you need only 1 LineRenderer per hex. You can do this:
LineRenderer lineRenderer = ... ; // Add or get LineRenderer component to game object
lineRenderer.SetVertexCount(7); // 6+1 since vertex 6 has to connect to vertex 1
for (int i = 0; i < 7; i++) {
Vector3 pos = ... ; // Positions of hex vertices
lineRenderer.SetPosition(i, pos);
}
Though this might be not very efficient depending on how many tiles you have. If you have a lot of them, but not too many, you could create a single LineRenderer for all tiles. And if you have really lots of them, then subdivide the map into regions containing X x Y tiles, and generate one LineRenderer per region. Also notice that adjacent hexes can share lines if you go with those methods.
If you don't mind spending about $20, Vectrosity is a nice Unity plugin that allows you to draw lines. I used it in a graph drawing application that I made with Unity to draw vertices between nodes.
Related
I'm trying to generate random terrain for my game (In Unity3D, C#). All I need is water and grass. No height to it (no mountains or hills.) I'd preferably like to do it by placing individual cubes. On top of that the terrain needs to be infinite.
I've searched every where for even a hint on how to do it, but everything I found had either height to it, didn't use individual cubes (edited the terrain as a whole), or wasn't infinite.
Any help would be much appreciated! :)
EDIT: I'm looking for something somewhat similar to a game called Factorio. Here's a screenshot: http://i.ytimg.com/vi/Uns15OfPWbo/maxresdefault.jpg As you can see there is a big body of water, and a ton of land. I want to create something that randomly does that every time (random bodies of water and random land shapes). Something like Minecraft without all the height.
I've heard about something called Perlin noise, but because of a lack of tutorials and documentation, I can't figure out for the life of me on how to use it to generate random terrain.
Perlin noise would be great for your needs.
It generates natural looking random noise. It is infinite in all directions, so basically how it works is you choose a random starting point and use that as a base or your (0,0) point. The you add to that a sampling point. If you pass to it the same sampling point, you will get the same result. All you have to do then is give it different sampling points to get different values and spread out in all directions like this:
for (int x = 0; x < Width; x++) {
for (int y = 0; z < Length ; y++) {
terrain[x,y] = Mathf.PerlinNoise(randomLocation.x + (float)x/scale, randomLocation.y + (float)y/scale);
}
}
where you could then expand your Width/Length in the desired direction based on where the player wants to go or where you want to generate new terrain.
Your terrain[,] would then contain floats from 0 to 1 and the as another comment suggested you'd interpret everything above .5 as land and bellow as water. Then you'd just instantiate a cube at that location, color it blue(water) if terrain[x,y] <0.5 and as brown (land) if terrain[x,y]>0.5 and that would be it.
Keep in mind that you can adjust scale to get bigger/smaller islands of land. But it has to be the same for X and Y, otherwise you'll get a stretched looking islands.
Hope this helps or isn't too late :)
I've been company many of question people post and all the answers you guys give, followed several tutorials and since all the links on my google search are marked as “already visited” I’ve decided to put my pride aside and post a question for you.
This is my first post so i don’t know if im doing that right sorry if not, anyway the problems is this:
I’m working in a C# planetary exploration game on unity 5, I’ve already built a sphere out of an octagon following some tutorials mentioned here, and also could build the perlin textures and heightmaps with them as well, the problem comes on applying them to the sphere and produce the terrain on the mesh, I know I have to map the vertices and UVs of the sphere to do that, but the problem is that I really suck at the math thing and I couldn’t find any step by step to follow, I’ve heard about Tessellation shaders, LOD, voronoi noise, perlin noise, and got lost on the process. To simplify:
What I have:
I have the spherical mesh
I have the heightmaps
I’ve assigned them to a material along with the proper normal maps
what I think I; (since honestly, I don’t know if this is the correct path anymore) need assistance with:
the code to produce the spherical mesh deformation based on the heightmaps
How to use those Tessellation LOD based shaders and such to make a real size procedural planet
Ty very much for your attention and sorry if I was rude or asked for too much, but any kind of help you could provide will be of a tremendous help for me.
I don't really think I have the ability to give you code specific information but here are a few additions/suggestions for your checklist.
If you want to set up an LOD mesh and texture system, the only way I know how to do it is the barebones approach where you physically create lower poly versions of your mesh and texture, then in Unity, write a script where you have an array of distances, and once the player reaches a certain distance away or towards the object, switch to the mesh and that texture that are appropriate for that distance. I presume you could do the same by writing a shader that would do the same thing but the basic idea remains the same. Here's some pseudocode as an example (I don't know the Unity library too well):
int distances[] = {10,100,1000}
Mesh mesh[] = {hi_res_mesh, mid_res_mesh, low_res_mesh}
Texture texture[] = {hi_res_texture, mid_res_texture, low_res_texture}
void Update()
{
if(player.distance < distances[0])
{
gameobject.Mesh = mesh[0]
gameobject.Texture = texture[0]
else
{
for(int i = 1; i < distances.length(); i++)
{
if (player.distance <= distances[i] && player.distance >= distances[i-1]):
{
gameobject.Texture = texture[i]
gameobject.Mesh = mesh[i]
}
}
}
}
If you want real Tesselation based LOD stuff which is more difficult to code: here are some links:
https://developer.nvidia.com/content/opengl-sdk-simple-tessellation-shader
http://docs.unity3d.com/Manual/SL-SurfaceShaderTessellation.html
Essentially the same concept applies. But instead of physically changing the mesh and texture you are using, you change the mesh and texture procedurally using the same idea of having set distances where you change the resolution of the mesh and texture inside of your shader code.
As for your issue with spherical mesh deformation. You can do it in a 3d editing software like 3dsMax, Maya, or Blender by importing your mesh and applying a mesh deform modifier and use your texture as the deform texture and then alter the level of deformation to your liking. But if you want to do something more procedural in real time you are going to have to physically alter the verticies of your mesh using the vertex arrays and then retriangulating your mesh or something like that. Sorry I'm less helpful about this topic as I am less knowledgeable about it. Here are the links I could find related to your problem:
http://answers.unity3d.com/questions/274269/mesh-deformation.html
http://forum.unity3d.com/threads/deform-ground-mesh-terrain-with-dynamically-modified-displacement-map.284612/
http://blog.almostlogical.com/2010/06/10/real-time-terrain-deformation-in-unity3d/
Anyways, good luck and please let me know if I have been unclear about something or you need more explanation.
I'm trying to make a spherical burst of rays for the purpose of checking collision, but having specific interactions happen based upon what or where each ray hit. Hence why I'm using rays rather then something simpler such as OverlapSphere.
The reason I'm looking for how to make a sphere is because I can use the same math for my rays, by having them go to the vertices of where the sphere would be. But every way I can find for making a sphere has the lines get closer the near to the poles, which makes sense, as its pretty easy to do. But as you can imagine, its not that useful for my current project.
TL;DR:
How do I make a sphere with equidistant vertices? If its not perfectly equidistant its fine, it just needs to pretty close. If this happens, it would be great if you could give how much the difference would be, and where, if applicable.
Extra notes:
I've looked at this and this, but the math is way over my head, so what I've been looking for might've just been staring me in the face this whole time.
You could use an icosphere. As the vertices are distributed on equilateral triangles, your vertices are guaranteed to be equidistant.
To construct the icosphere, first you make an icosahedron and then split the faces recursively in smaller triangles as explained in this article.
Are you aware that the sphere given to you by Unity is in fact designed
with this exact goal in mind?
ie, the entire raison d'etre of the sphere built-in to Unity is that the points are fairly smoothly space ...... roughly equidistant, as you phrase it.
To bring up such a sphere in Unity, just do this:
You can then instantly get access to the verts, as you know
Mesh mesh = GetComponent<MeshFilter>().mesh;
Vector3[] vv = mesh.vertices;
int kVerts=vv.Length
for (int i=0; i<kVerts; ++i)
Debug.Log ... vv[i]
Note you can easily check "which part of the sphere" they are on by (for example) checking how far they are from your "cities" (or whatever) or just check (for example) the z values to see which hemisphere they are in .. et cetera.
Furthermore...
Please note. Regarding your overall reason for wanting to do this:
but having specific interactions happen based upon what or where each ray hit
Note that it could not be easier to do this using PhysX. (The completely built-in game physics in Unity.) Indeed, I have never, ever, looked at a collision without doing something "specific" depending on "where it hit!"
You can for example get the point where the contact was with http://docs.unity3d.com/ScriptReference/RaycastHit-point.html
It's worth noting it is absolutely inconceivable one could write something approaching the performance of PhysX in casual programming.
I hope this makes things easier!
slice the sphere into N circles
compute perimeter of it
divide it by the same angle that create the slice
this gives you the number of vertexes
and also angle step inside circle
cast rays
This is how I coded it in C++ + OpenGL:
// draw unit sphere points (r=1 center=(0,0,0)) ... your rays directions
int ia,na,ib,nb;
double x,y,z,r;
double a,b,da,db;
na=16; // number of slices
da=M_PI/double(na-1); // latitude angle step
for (a=-0.5*M_PI,ia=0;ia<na;ia++,a+=da) // slice sphere to circles in xy planes
{
r=cos(a); // radius of actual circle in xy plane
z=sin(a); // height of actual circle in xy plane
nb=ceil(2.0*M_PI*r/da);
db=2.0*M_PI/double(nb); // longitude angle step
if ((ia==0)||(ia==na-1)) { nb=1; db=0.0; } // handle edge cases
for (b=0.0,ib=0;ib<nb;ib++,b+=db) // cut circle to vertexes
{
x=r*cos(b); // compute x,y of vertex
y=r*sin(b);
// this just draw the ray direction (x,y,z) as line in OpenGL
// so you can ignore this
// instead add the ray cast of yours
double w=1.2;
glBegin(GL_LINES);
glColor3f(1.0,1.0,1.0); glVertex3d(x,y,z);
glColor3f(0.0,0.0,0.0); glVertex3d(w*x,w*y,w*z);
glEnd();
}
}
This is how it looks like:
R,G,B lines are the sphere coordinate system axises X,Y,Z
White-ish lines are your Vertexes (White) + direction (Gray)
[Notes]
do not forget to include math.h
and replace the OpenGL stuff with yours
If you want 4, 6, 8, 12 or 20 vertices then you can have exactly equidistant vertices as the Platonic solid which all fit inside a sphere. The actual coordinates of these should be easy to get. For other numbers of vertices you can use other polyhedra and scale the verties so they lie on a sphere. If you need lots of points then a geodesic dome might be a good base. The C60 bucky-ball could be a good base with 60 points. For most of these you should be able to find 3D models from which you can extract coordinates.
I think the easiest way to control points on a sphere is by using spherical coordinates. Then you can control position of points around the sphere by using two angles (rho and phi) and the radius.
Example code for filling points uniformly around a rotating sphere (for fun):
var time = 1; // Increment this variable every frame to see the rotation
var count = 1000;
for (int i = 0; i < count; i++)
{
var rho = time + i;
var phi = 2 * Math.PI * i / count;
var x = (float)(radius * Math.Sin(phi) * Math.Cos(rho));
var z = (float)(radius * Math.Sin(phi) * Math.Sin(rho));
var y = (float)(radius * Math.Cos(phi));
Draw(x, y, z); // your drawing code for rendering the point
}
As some answers have already suggested, use an icosahedron based solution. The source for this is quite easy to come by (and I have written my own several times) but I find the excellent Primitives Pro plugin extremely handy under many other circumstances, and always use their sphere instead of the built-in Unity one.
Link to Primitives Pro component
Primitives Pro options
I have a set of points, drawn by the user. They will be drawing around some objects.
I need to somehow turn this set of points into a shape, so I can find the area to detect collisions.
An image will clarify:
Set of points represented as shape http://www.imagechicken.com/uploads/1277188630025178800.jpg
.
The best idea I have had so far involves iterating over every pixel determining if it is 'inside' or 'outside' the shape, but that would be horribly slow, and I'm not even sure how to do the determining 'inside'/'outside' bit...
Any hints? I am using .NET (C# and XNA) if that helps you help me!
You can think of your shape as an union of several shapes each of which is a simple closed polygon.
the check for every object if it is inside any of the polygons in the following manner:
All dots connected by lines - each line has an equation defining it.
For every object - build an equation for a line passing through this object.
now - for each object equation you need to check how many lines (those between the dots) intersects this object equation - but count only the intersection points that are in the rage between the two dots (and not in the rest of the line outside the two dots) and only the intersection points that are in one side of the object (pick a side - doesn't matter).
If the count is even - the object is outside the shape - otherwise it is inside.
Just a precursor to anything I will say, I have no experience in this field, this is just how I would go about the problem.
A tactic a lot of games use for this is known as Hit Boxes. It is much easier to detect if a point is inside a square than any other figure. But this doesn't give you an exact collision, it could be right outside your desired object.
I've seen Collision 'Bubbles' used before. Here is a link I found for you. This explains the use of Collision Bubbles in the console game Super Smash Brothers.
Given a point, the distance formula, and a radius, you can easily implement collision bubbles.
To take it even one step forward, I did a little bit of research, I saw a nifty little algorithm (more advanced that the top two suggestions), the "Gilbert-Johnson-Keerthi Collision detection algorithm for convex objects." Here is a link for ya. The implementation provided is written in D. If your working in C# it shouldn't be too hard to translate (I would highly suggest digesting the algorithm too).
Hope this gives you some direction.
Well I got it working thanks to some help on another forum.
I used the GraphicsPath class to do all the hard work for me.
This is what my method ended up looking like:
public bool IsColliding(Vector2 point)
{
GraphicsPath gp = new GraphicsPath();
Vector2 prevPoint = points[0];
for (int i = 1; i < points.Count; i++)
{
Vector2 currentPoint = points[i];
gp.AddLine(prevPoint.X, prevPoint.Y, currentPoint.X, currentPoint.Y);
prevPoint = currentPoint;
}
gp.CloseFigure(); //closing line segment
return gp.IsVisible(point.X, point.Y);
}
Thanks for your suggestions both of you
C# programmer, beginner DirectX.
Have created 2 meshes using Mesh.Cylinder but need to combine them into a single mesh. Is that possible?
Yeah thats doable. You have a transform matrix for both meshes presumably?
Lock both meshes and then take the 1st mesh (I will assume we add it to the second) and transform its vertices one by one by the matrix transformation transfoming from cylinder 1s local space to clyinder 2's local space (ie [cylinder 1 world transform] * [inverse cylinder 2 world transform]). Define up the correct indices and you have now added mesh 1 to Mesh 2.
It will get more compilcated if you want both meshes to intersect properly. If you want to do that I suggest you look into Constructive Solid Geometry (CSG). There are plenty of links to be found on google on the subject.