Search Unity

Code not working.. What'd I miss?

Discussion in 'Scripting' started by RavenWoodsDE, Feb 21, 2016.

  1. RavenWoodsDE

    RavenWoodsDE

    Joined:
    Jul 13, 2015
    Posts:
    12
    Hello everyone,

    I've been going over this problem lots of times.
    Checked if "worldPos" is correct,
    got feedback wether the terrain was too steep or water (only steepness triggered, but it works),
    tried to set details[x,y] to -1 instead of 0..

    No luck. It always puts details on the chosen terrain, wether my bool returns true or false.

    If "density" is set to 0, it clears the terrain as it should. But the condition is ignored.
    Either that or I completely overlooked something obvious. I hope you see my mistake and are
    willing to point it out to me..

    Thanks in advance. Now here's the code.
    A seperate monobehavior script references it.


    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. [System.Serializable]
    6. public class MassGrass
    7. {  
    8.     [Range(0, 32)] public int density;
    9.     [Range(0,359)] public int maxAngle;
    10.     public bool               start;
    11.  
    12.     public void Process(Terrain map)
    13.     {
    14.         // Vars
    15.         TerrainData data = map.terrainData;
    16.  
    17.         // Fill Layers
    18.         for (int i = 0; i < data.detailPrototypes.Length; i++)
    19.         {
    20.             // Fill Tiles
    21.             int[,] details = new int[data.detailWidth, data.detailHeight];
    22.             for (int x = 0; x < data.detailWidth; x++)
    23.             {
    24.                 for (int y = 0; y < data.detailHeight; y++)
    25.                 {
    26.                     details[x, y] = 0;
    27.                     if (IsValid(x, y, data))
    28.                     {
    29.                         details[x, y] = density;
    30.                     }
    31.                 }
    32.             }
    33.             // Apply to Layer
    34.             data.SetDetailLayer(0, 0, i, details);
    35.         }
    36.      
    37.         // Apply to Map
    38.         map.Flush();
    39.     }
    40.  
    41.     bool IsValid(float x, float y, TerrainData mapData)
    42.     {
    43.         // World Position
    44.         Vector3 worldPos = Vector3.zero;
    45.         worldPos.x = (x / mapData.detailWidth) * mapData.size.x;
    46.         worldPos.z = (y / mapData.detailHeight) * mapData.size.z;
    47.  
    48.         // Raycast
    49.         RaycastHit hit = new RaycastHit();
    50.         if (Physics.Raycast(worldPos + (Vector3.up * 100), Vector3.down, out hit, 200))
    51.         {
    52.             if (hit.collider.gameObject.layer != 9)
    53.             {
    54.                 return false;
    55.             }
    56.             else if (Vector3.Angle(hit.normal, Vector3.up) > maxAngle)
    57.             {
    58.                 return false;
    59.             }
    60.         }
    61.         return true;
    62.     }
    63. }
     
    Last edited: Feb 21, 2016
  2. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Where is the problem? Does IsValid actually return true and false?
     
  3. RavenWoodsDE

    RavenWoodsDE

    Joined:
    Jul 13, 2015
    Posts:
    12
    Yes, it returns false if either the raycast didn't hit a ground layer or if the hit normals return an angle higher than maxAngle.
    Other than that it returns true. The problem is that this isn't actually applied when using the bool to check wether to use 0 or the preset density for these details-layers.