Generating Lookup Table For 3D Noise - c#

I'm having trouble understanding why my lookup table is not working. I currently have one that generates a table for 2D noise, which works fine.
int xOffset = chunk.Pos.x;
int zOffset = chunk.Pos.z;
// Generate a lookup table
int i = 0;
for (int z = 0; z<ni.noiseGen.Size; z++)
{
float zf = (z<<ni.noiseGen.Step)+zOffset;
for (int x = 0; x<ni.noiseGen.Size; x++)
{
float xf = (x<<ni.noiseGen.Step)+xOffset;
ni.lookupTable[i++] = NoiseUtils.GetNoise(noise.Noise, xf, 0f, zf, 75f, 100, noise.Gain);
}
}
When I try to iterate over a y axis, it does not work. An index out of range exception is thrown. Below is the attempted 3D lookup table.
int xOffset = chunk.Pos.x;
int yOffset = chunk.Pos.y;
int zOffset = chunk.Pos.z;
// Generate a lookup table
int i = 0;
for (int z = 0; z<ni.noiseGen.Size; z++)
{
float zf = (z<<ni.noiseGen.Step)+zOffset;
for (int y = 0; y<ni.noiseGen.Size; y++)
{
float yf = (y<<ni.noiseGen.Step)+yOffset;
for (int x = 0; x<ni.noiseGen.Size; x++)
{
float xf = (x<<ni.noiseGen.Step)+xOffset;
ni.lookupTable[i++] = NoiseUtils.GetNoise(noise.Noise, xf, yf, zf, 75f, 100, noise.Gain);
}
}
}
I'd assume it'd be as easy as that, but I was wrong and do not understand why. Any enlightenment would be appreciated, thanks!

Ah, after looking over how ni.lookupTable was declared I realized I forgot to multiply by the size one more time for 3D. It is now declared like this,
ni.lookupTable = pools.FloatArrayPool.Pop(ni.noiseGen.Size*ni.noiseGen.Size*ni.noiseGen.Size);
My apologies!

Related

Add Trees to Terrain C# with TreeInstance

I try to add trees to my terrain with the following code:
// Create Trees
for (int x = 0; x < terrainData.heightmapWidth; x++)
{
for (int z = 0; z < terrainData.heightmapWidth; z++)
{
if (GetBiome(x, z) == "Grasland")
{
int r = UnityEngine.Random.Range(0, 500);
if (r == 0)
{
Terrain terrain = GetComponent<Terrain>();
TreeInstance treeTemp = new TreeInstance();
treeTemp.position = new Vector3(x, 0, z);
treeTemp.prototypeIndex = 0;
treeTemp.widthScale = 1f;
treeTemp.heightScale = 1f;
treeTemp.color = Color.white;
treeTemp.lightmapColor = Color.white;
terrain.AddTreeInstance(treeTemp);
terrain.Flush();
}
}
}
}
the function GetBiome() works correctly, i checked that by placing the trees as GameObjects and it worked fine.
Is there something missing that i didn't thought of?
Because there's not a single tree generated.
The tree i want to generate is set up under PaintTrees:
Please read my notes as comments below, I hope this explains and resolves the issue.
I have tested this in unity to confirm.
// Create Trees
//make these float otherwise your position math below is truncated
for (float x = 0; x < terrainData.heightmapWidth; x++)
{
//heightmapHeight not heightmapWidth
for (float z = 0; z < terrainData.heightmapHeight; z++)
{
Terrain terrain = GetComponent<Terrain>();
int r = UnityEngine.Random.Range(0, 500);
if (r == 0)
{
TreeInstance treeTemp = new TreeInstance
//position is local and expects value between 0 and 1
treeTemp.position = new Vector3(x / terrainData.heightmapWidth, 0, z / terrainData.heightmapHeight),
treeTemp.prototypeIndex = 0;
treeTemp.widthScale = 1f;
treeTemp.heightScale = 1f;
treeTemp.color = Color.white;
treeTemp.lightmapColor = Color.white;
terrain.AddTreeInstance(treeTemp);
terrain.Flush();
}
}
}
A bit late but, instead of
int r = UnityEngine.Random.Range(0, 500);
if (r == 0)
do
int r = UnityEngine.Random.Range(0, 500);
if (r >= 0 && <= 1)
to check for range. Because you're checking for a impossible number it will always come close but never 0 for example 0.000230...f you will need to Math floor it or check for range like I did

Problems with 2-dimensional array in C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public static class noise
{
public static float[,] GenerateNoiseMap(int mapWidth, int mapHeight, float scale)
{
float[,] noiseMap = new float[mapWidth, mapHeight];
if (scale <= 0)
{
scale = 0.0001f;
}
for(int y = 0; y<mapHeight; y++)
{
for (int x = 0; y < mapWidth; x++)
{
float sampleX = x/(mapWidth * scale);
float sampleY = y/(mapHeight * scale);
float perlinValue = Mathf.PerlinNoise(sampleX, sampleY);
noiseMap[x, y] = perlinValue;
Debug.Log(noiseMap.GetLength(0));
Debug.Log(noiseMap.GetLength(1));
}
}
return noiseMap;
}
}
Above is the code that is giving me the error:
IndexOutOfRangeException: Array index is out of range.
noise.GenerateNoiseMap (Int32 mapWidth, Int32 mapHeight, Single scale) (at
Assets/Scripts/MapGeneration/noise.cs:24)
I'm not entirely familiar with how arrays work in C# (or at all) but my teachers says that the most common issue with arrays that yield an IndexOutOfRange error is that I'm starting at 1 instead of index 0. I've tried to fix this but that doesn't seem to be the problem in this section of code.
I am attempting to generate a Perlin noise map for my custom game.
What is throwing the error?
Thanks in advance.
Your problem is here:
for (int x = 0; y < mapWidth; x++)
it should be:
for (int x = 0; x < mapWidth; x++)

how to limit CreateCell c# procedural grid generation unity

I am learning C# for unity and could use some pointers.
I am following catlikecoding hex map tutorial but I have modified the grid for my own means.
http://catlikecoding.com/unity/tutorials/hex-map-1/
My goal is to create a pyramid of squares procedurally starting from a 7 * 7 grid. I am using a prefab plane
How do I place a limit on The CreateCell looped function so that cells with the (x,y) coordinates are not created when they meet the following expression
x + y > n - 1 where n = grid size (for example (6,1) or (5,6)
I have gotten as far as creating a rhombus of planes with the undesired planes below the ground plane.
The script is as follows.
public class HexGrid : MonoBehaviour {
public int width = 7;
public int height = 7;
public int length = 1;
public SquareCell cellPrefab;
public Text cellLabelPrefab;
SquareCell[] cells;
Canvas gridCanvas;
void Awake () {
gridCanvas = GetComponentInChildren<Canvas>();
cells = new SquareCell[height * width * length];
for (int z = 0 ; z < height; z++) {
for (int x = 0; x < width; x++) {
for (int y = 0; y < length; y++)
CreateCell(x, z, y);
}
}
}
void CreateCell(int x, int z, int y) {
Vector3 position;
position.x = x * 10f ;
position.y = ((y + 1) - (x + z)) * 10f + 60f;
position.z = z * 10f ;
Cell cell = Instantiate<Cell>(cellPrefab);
cell.transform.SetParent(transform, false);
cell.transform.localPosition = position;
Text label = Instantiate<Text>(cellLabelPrefab);
label.rectTransform.SetParent(gridCanvas.transform, false);
label.rectTransform.anchoredPosition =
new Vector2(position.x, position.z);
label.text = x.ToString() + "\n" + z.ToString();
}
}
Grid so far
A quick solution would be to add an if statement before the part of the code that creates a cell. In this case the method CreateCell(). That if statement should have your logic in code. You would also have to create two variables for the size to check. For example:
public int tempX;
public int tempY;
void Awake () {
gridCanvas = GetComponentInChildren<Canvas>();
cells = new SquareCell[height * width * length];
for (int z = 0 ; z < height; z++) {
for (int x = 0; x < width; x++) {
for (int y = 0; y < length; y++)
{
if (x + y < (tempX + tempY) - 1)
{
CreateCell(x, z, y);
}
}
}
}
}

Items not appearing inside a canvas c#/silverlight

I am just experimenting with Silverlight however I've run into an issue with a Canvas element. I am trying to generate a grid of rectangle based off a multidimensional array but when I run the code, the canvas has no elements. I wonder if you could offer some guidance for this?
public void generate(Rectangle[, ,] worldData)
{
int locx = 0, locy = 0;
Rectangle currentBlock = new Rectangle();
int z = 0;
for (int x = 0; x < worldData.GetLength(1); x++)
{
for (int y = 0; y < worldData.GetLength(2); y++)
{
currentBlock = worldData[z, x, y];
Canvas.SetTop(currentBlock, locy);
Canvas.SetLeft(currentBlock, locx);
locy = locy + 32;
gridDisplayCanvas.Children.Add(currentBlock);
}
locx = locx + 32;
locy = 0;
}
}
I figured out what is causing the issue, the images where being referenced with a \ but silverlight expects a \

What's wrong with this 2D array initializing code?

I am trying to take the positions of the cells of a game level and map them to a 2D array. I want to do this so I can make each ground cell (and NOT background cell) collidable with my player character.
Below is the current code that someone created for me:
int tileSize = 20;
int screenSizeInTiles = 30;
// initializing multidimensional array of points
var tilePositions = new System.Drawing.Point[screenSizeInTiles, screenSizeInTiles];
for (int x = 0; x < screenSizeInTiles; x++)
{
for (int y = 0; y < screenSizeInTiles; y++)
{
tilePositions[x, y] = new System.Drawing.Point(x * tileSize, y * tileSize);
}
}
It can be found here: How can I use a jagged array to record the x and y axes of these tiles?
along with a better description of what I'm trying to do.
So, when I run this code, I get an empty array in tilePositions. Well, the x, and y values are there, but the values are all 0. The values should be the position data for the cells.
Here is what the tilesPosition array looks like:
http://imgur.com/VYyxp
I'm still working on the collision code though... I need this to work before I can figure that part out.
Thank you all incredibly much, you have been so helpful! I am still a beginner, but am working around the clock to make myself a better programmer.
if you did
int tileSize = 20;
int screenSizeInTiles = 30;
// initializing jagged array of points
var tilePositions = new Point[screenSizeInTiles][screenSizeInTiles];
for (int x = 0; x < screenSizeInTiles; x++)
{
for (int y = 0; y < screenSizeInTiles; y++)
{
tilePositions[x][y] = new Point(x * tileSize, y * tileSize);
}
}
it would be jagged (an array of arrays.)

Categories

Resources