#Bug - Paint holes creating hole but stil...

1 messages · Page 1 of 1 (latest)

pallid tiger
#

Which version of Unity are you on?

viral scroll
#

the current 2022 build

pallid tiger
#

and which version of URP

viral scroll
#

whatever came out of the box but let me confirm!

#

URP Version 13.1.8 - October 02, 2022

pallid tiger
#

thanks

viral scroll
#

I am modifying terrain and creating holes at runtime btw

#

I think another user with the problem mentioned the same

pallid tiger
#

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?

viral scroll
#

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

pallid tiger
#

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

viral scroll
#

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 😅

pallid tiger
#

No worries haha. I won't be judging

viral scroll
#

I don't know if there's some sort of update/redraw function I should be calling after my modifications or not

pallid tiger
#

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)

viral scroll
#

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

pallid tiger
#

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?

viral scroll
#

Windows 10

pallid tiger
#

Nice. ShaderGraph errors on a new project in this version of Unity

viral scroll
#

😎

#

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

pallid tiger
#

are you trying to generate courses procedurally, end goal?

viral scroll
#

yeah end goal

#

ideally an artist should be able to place the hole X/Z and the game should fix it at runtime

pallid tiger
#

neat

viral scroll
#

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

pallid tiger
#

seems to work for me?

#

Oh but this is on 2022.1.16f1

viral scroll
#

I'm on 2022.1.20f1

pallid tiger
#

ok. will try that one

viral scroll
#

I'm trying different renderer assets for my different quality settings but no luck so far

pallid tiger
#

Got the same results in 2022.1.20f1

viral scroll
#

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

pallid tiger
#

I think you can use UnityEngine.Object.Instantiate to create a copy of the TerrainData

pallid tiger
viral scroll
#

Thanks for working with me on that.