#Bug - Paint holes creating hole but stil...
1 messages · Page 1 of 1 (latest)
the current 2022 build
and which version of URP
whatever came out of the box but let me confirm!
URP Version 13.1.8 - October 02, 2022
thanks
I am modifying terrain and creating holes at runtime btw
I think another user with the problem mentioned the same
And you don't have any custom Terrain shaders?
oooooh
ok. and so that's when the holes don't work? but they do work if you paint them in the editor then build?
No they work at runtime in the editoractually
with the same script
I create a 2x2 (smallest possible) texel hole to stitch my golf cup mesh into it
I meant editor btw... everything works fine at runtime in the editor
and this seems to be a visual glitch as the hole is there in the terrain mesh
the ball falls through
are you able to share/comfortable with sharing the script? you can DM it to me in a code block if you don't want to share in the Unity server
absolutely
{
public Ball ball;
// Start is called before the first frame update
void Start()
{
var currentTerrain = ball.GetCurrentTerrainAtPosition(this.transform.position);
// get the normalized position of this game object relative to the terrain
Vector3 tempCoord = (this.transform.position - currentTerrain.gameObject.transform.position);
Vector3 coord;
coord.x = tempCoord.x / currentTerrain.terrainData.size.x;
coord.y = tempCoord.y / currentTerrain.terrainData.size.y;
coord.z = tempCoord.z / currentTerrain.terrainData.size.z;
// get the position of the terrain heightmap where this game object is
var posXInTerrain = (int)(coord.x * currentTerrain.terrainData.heightmapResolution);
var posZInTerrain = (int)(coord.z * currentTerrain.terrainData.heightmapResolution);
int size = 2;
// we set an offset so that all the raising terrain is under this game object
int offset = size / 2;
// get the heights of the terrain under this game object
float[,] heights = currentTerrain.terrainData.GetHeights(posXInTerrain, posZInTerrain - offset, size, size);
float averageHeight = CalculateAverageGroundHeight(size, heights);
SmoothGroundAroundCup(currentTerrain, posXInTerrain, posZInTerrain, size, offset, heights, averageHeight);
CreateHoleAndAlignCupHeight(currentTerrain, posXInTerrain, posZInTerrain);
MoveCupToCenterOfHole(currentTerrain, posXInTerrain, posZInTerrain);
}
private void CreateHoleAndAlignCupHeight(Terrain currentTerrain, int posXInTerrain, int posZInTerrain)
{
var worldHeightAtCenter = currentTerrain.terrainData.GetHeight(posXInTerrain, posZInTerrain);
var b = new bool[1, 1];
for (int i = 0; i < 1; i++)
{
for (int j = 0; j < 1; j++)
{
b[i, j] = false;
}
}
currentTerrain.terrainData.SetHoles(posXInTerrain, posZInTerrain - 1, b);
this.transform.position = new Vector3(this.transform.position.x, worldHeightAtCenter, this.transform.position.z);
this.transform.rotation = Quaternion.Euler(Vector3.zero);
}
private static void SmoothGroundAroundCup(Terrain currentTerrain, int posXInTerrain, int posZInTerrain, int size, int offset, float[,] heights, float averageHeight)
{
// we set each sample of the terrain in the size to the desired height
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
heights[i, j] = averageHeight;
// set the new height
currentTerrain.terrainData.SetHeights(posXInTerrain, posZInTerrain - offset, heights);
}
private static float CalculateAverageGroundHeight(int size, float[,] heights)
{
float averageHeight = 0;
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
{
averageHeight += heights[i, j];
}
averageHeight = averageHeight / (size * size);
return averageHeight;
}
private void MoveCupToCenterOfHole(Terrain currentTerrain, int posXInTerrain, int posZInTerrain)
{
var holeCorner1 = TerrainPosToWorld(currentTerrain, new Vector3(posXInTerrain, 0, posZInTerrain));
var holeCorner2 = TerrainPosToWorld(currentTerrain, new Vector3(posXInTerrain + 1, 0, posZInTerrain - 1));
var middle = holeCorner1 + ((holeCorner2 - holeCorner1) * .5f);
this.transform.position = new Vector3(middle.x, this.transform.position.y, middle.z);
}
private Vector3 TerrainPosToWorld(Terrain terrain, Vector3 pos)
{
return Vector3.Scale(pos, terrain.terrainData.size / (terrain.terrainData.heightmapResolution - 1)) + terrain.transform.position;
}
}```
wanted to post the entire script
the script gets the average height in the area and levels it, then cuts a small hole, then adjusts the golf cup mesh to be aligned perfectly inside of the created hole
I'm new to working with terrain so that's not cleaned up code 😅
No worries haha. I won't be judging
I don't know if there's some sort of update/redraw function I should be calling after my modifications or not
Ya. You might need to upload the texture data to GPU manually. But iirc, SetHoles should already do that
(still downloading the Editor)
(nvm. done)
would that be something that would make sense that it work in the editor but not in the build?
And that it would work somewhat? I think that's the weird part to me
2 of my golf holes render perfectly in the build and only 1 doesn't
In this case it would surprise me but we have some weird stuff in our code sometimes 😅
What platform are you running the build on?
Windows 10
Nice. ShaderGraph errors on a new project in this version of Unity
😎
Also Wyatt, I'm editing the terrain data directly instead of a runtime copy
which I honestly don't want to do
But the terrain already has a hole there because it was edited
So this hole is already created at the time of build
are you trying to generate courses procedurally, end goal?
yeah end goal
ideally an artist should be able to place the hole X/Z and the game should fix it at runtime
neat
same solution solves both issues
since the hole already exists in the terrain, I disable my Hole script completely and rebuilt
This is what I see in the Editor before I build
but yet the glitched hole is still rendered incorrectly
so even no runtime modifications, this visual bug exists?
I confirmed my Terrain shader is the URP default
I'm on 2022.1.20f1
ok. will try that one
I'm trying different renderer assets for my different quality settings but no luck so far
Got the same results in 2022.1.20f1
I moved the hole, used the unity hole tool and fill in the existing ones, and now I can't reproduce
I need to convert my script so that my terrain modifications don't persist after runtime in the editor
maybe I'm introducing weird behavior with that
Is Unity's Clone() method on TerrainData safe?
I found a Git script for a custom deep clone but it's very old
I think you can use UnityEngine.Object.Instantiate to create a copy of the TerrainData
Heya. So is this no longer an issue now?
I can’t reproduce it so as of now I’m fine ending the thread. I don’t think I fixed it but rather just temporarily fixed itself
Thanks for working with me on that.