Search Unity

Trying to Check if a GameObject is "Underwater"

Discussion in 'Getting Started' started by vegetamaker, Jun 12, 2017.

  1. vegetamaker

    vegetamaker

    Joined:
    Feb 28, 2017
    Posts:
    37
    Hello! Again, thanks so much for your time.

    After a time trying to do my own "steps sounds" scripts, I am very close to finish it. Here it is (sorry if I forget translate some spanish words, if it is an issue for understand my problem I'll change itimmediately).

    First my Script for check texture:

    Code (CSharp):
    1.  
    2. public class CheckingTexture : MonoBehaviour {
    3.  
    4.     private static string  GetTerrainTexture(Vector3 posToCheck, bool nameOrID, Terrain terrainToCheck)
    5.     {
    6.         string texture;
    7.  
    8.         //Saving the Terrain data where we are.  
    9.         TerrainData mTerrainData = terrainToCheck.terrainData;
    10.         //Debug.Log ("The Terrain name is... " + Terrain.activeTerrain);
    11.  
    12.         //Now we get the width and Height of the terrain.
    13.         //Look like if "control texture resoluion" in Terrain settings is changed, the values here change with it.
    14.         int alphamapWidth = mTerrainData.alphamapWidth;
    15.         int alphamapHeight = mTerrainData.alphamapHeight;
    16.         //Debug.Log ("The Value of alphamapWidth is " + alphamapWidth + " and the value of alphamapHeight is " + alphamapHeight);
    17.  
    18.         //Now we create an array with all possibles textures.
    19.         float[,,] mSplatmapData = mTerrainData.GetAlphamaps(0, 0, alphamapWidth, alphamapHeight);
    20.  
    21.         //And we save the lenght of the arrain in a int for the for later
    22.         int mNumTextures = mSplatmapData.Length / (alphamapWidth * alphamapHeight);
    23.         //Debug.Log ("The terrain have ... " + mNumTextures + " textures");
    24.  
    25.         //Creating a new vector
    26.         Vector3 terrainCoords = new Vector3();
    27.         terrainCoords.x = ((posToCheck.x - terrainToCheck.transform.position.x) / terrainToCheck.terrainData.size.x) * terrainToCheck.terrainData.alphamapWidth;
    28.         terrainCoords.z = ((posToCheck.z - terrainToCheck.transform.position.z) / terrainToCheck.terrainData.size.z) * terrainToCheck.terrainData.alphamapHeight;
    29.  
    30.         //So lets check, finally, the index and the name for the texture
    31.         for (int i = 0; i < mNumTextures; i++)
    32.         {
    33.             if (0 < mSplatmapData [(int)terrainCoords.z, (int)terrainCoords.x, i]) {
    34.                 if (nameOrID == true)
    35.                     texture = i.ToString();
    36.                 else
    37.                     texture = mTerrainData.splatPrototypes [i].texture.ToString ();
    38.             }
    39.         }
    40.  
    41.         return texture;
    42.     }
    43.  
    44.     //True
    45.     public static string GetTerrainID(Vector3 posToCheck, Terrain terrainToCheck)
    46.     {
    47.         return GetTerrainTexture (posToCheck, true, terrainToCheck);
    48.     }
    49.  
    50.     //False
    51.      public static string GetTerrainName(Vector3 posToCheck, Terrain terrainToCheck)
    52.     {
    53.         return GetTerrainTexture (posToCheck, false, terrainToCheck);
    54.     }
    55.      
    56.     /*void Update () {
    57.         Debug.Log("The ID and name of my texture is... " + GetTerrainID(transform.position, terrainToCheck) + "<<>>" + GetTerrainName(transform.position, terrainToCheck));
    58.     }*/
    59. }

    Now the Script where I check what Sound I should use:

    Code (CSharp):
    1. public class ImprovedStepSounds : MonoBehaviour {
    2.  
    3.     [Header("Terrain that I Want check")]
    4.     public Terrain terrainToCheck;
    5.  
    6.     [Space(10)]
    7.     [Header("Sin Sonido")]
    8.     public List<AudioClip> noSoundList;
    9.     public AudioClip noSoundJump;
    10.     public AudioClip noSoundLand;
    11.  
    12.     [Space(10)]
    13.     [Header("Texture Default (when not found a texture)")]
    14.     public List<AudioClip> idDStepsList;
    15.     public AudioClip idDJumps;
    16.     public AudioClip idDLand;
    17.  
    18.     [Space(10)]
    19.     [Header("Texture ID 0 / Cliff")]
    20.     public List<AudioClip> id0StepsList;
    21.     public AudioClip id0Jumps;
    22.     public AudioClip id0Land;
    23.  
    24.     [Space(10)]
    25.     [Header("Texture ID 1 / Arena ")]
    26.     public List<AudioClip> id1StepsList;
    27.     public AudioClip id1Jumps;
    28.     public AudioClip id1Land;
    29.  
    30.     [Space(10)]
    31.     [Header("Texture ID 2 / Césped ")]
    32.     public List<AudioClip> id2StepsList;
    33.     public AudioClip id2Jumps;
    34.     public AudioClip id2Land;
    35.  
    36.     [Space(10)]
    37.     [Header("Texture ID 3 / Grava")]
    38.     public List<AudioClip> id3StepsList;
    39.     public AudioClip id3Jumps;
    40.     public AudioClip id3Land;
    41.  
    42.     [Space(10)]
    43.     [Header("Texture ID 4 / Tierra")]
    44.     public List<AudioClip> id4StepsList;
    45.     public AudioClip id4Jumps;
    46.     public AudioClip id4Land;
    47.  
    48.  
    49.     [Space(10)]
    50.     [Header("Water")]
    51.     public List<AudioClip> waterList;
    52.     public AudioClip waterJump;
    53.     public AudioClip waterLand;
    54.  
    55.  
    56.     [Space(10)]
    57.     [Header("Wood")]
    58.     public List<AudioClip> woodFenceList;
    59.     public AudioClip woodFenceJump;
    60.     public AudioClip woodFenceLand;
    61.  
    62.  
    63.     private bool manualSound = false;
    64.     private float distToGround = 5f;
    65.     private float distToTop = 50f;
    66.     private RaycastHit hitObject = new RaycastHit();
    67.     private RaycastHit hitObjectTop = new RaycastHit();
    68.     private RaycastHit hitObjectSphere = new RaycastHit();
    69.  
    70.     private int lastStepsSelected = -1;
    71.     private int newStepsSelected = -1;
    72.  
    73.     void Start()
    74.     {
    75.         NewStepsSounds(idDStepsList, idDJumps, idDLand);
    76.     }
    77.  
    78.  
    79.  
    80.  
    81.     //The ID of textures go between -1 (default sounds) to 999 (for example)
    82. //The ID for manual sounds will start in 1000
    83. //99999 is for when I don't want sounds at all
    84.  
    85.     void Update()    {
    86.              
    87.         CheckingRaycastOrTexture ();
    88.  
    89.  
    90. //I tryed the sphere too.
    91.         /*if (Physics.SphereCast (transform.position, 25f, transform.position, out hitObjectSphere, 5f)) {
    92.             if (hitObjectSphere.transform.tag == "MANUAL_STEPS") {
    93.                 SettingSoundsByName (hitObjectSphere);
    94.             } else {
    95.                 CheckingRayCastOnTop ();
    96.             }
    97.         } else {
    98.             CheckingRayCastOnTop ();
    99.  
    100.         }*/
    101.     }
    102.  
    103.  
    104.  
    105.  
    106. //==========================
    107.  
    108.     void CheckingRaycastOrTexture()
    109.     {
    110.         if (Physics.Raycast (transform.position, Vector3.down, out hitObject, distToGround)) {
    111.             Debug.Log(hitObject.transform.name);
    112.             if (hitObject.transform.tag == "MANUAL_STEPS") {
    113.                 SettingSoundsByName(hitObject);
    114.             } else {
    115.                 //Calling to check the Texture
    116.                 newStepsSelected = int.Parse (CheckingTexture.GetTerrainID (transform.position, terrainToCheck));
    117.                 SettingSoundsByTexture();
    118.  
    119.             }
    120.         }
    121.     }
    122.  
    123.     /*
    124. //Not using ATM
    125.     void CheckingRayCastOnTop()
    126.     {
    127.         //Check to Up
    128.         if (Physics.Raycast (transform.position, Vector3.up, out hitObjectTop, distToTop)) {
    129.             if (hitObjectTop.transform.tag == "MANUAL_STEPS") {
    130.                 SettingSoundsByName (hitObjectTop);
    131.             }
    132.         } else {
    133.             CheckingRaycastOrTexture ();
    134.         }
    135.     }
    136. */
    137.  
    138.     void SettingSoundsByTexture(){
    139.      
    140.  
    141.         //Default, just in case
    142.         if (newStepsSelected == -1 || newStepsSelected>= 5 && newStepsSelected<=999) {
    143.             NewStepsSounds(idDStepsList, idDJumps, idDLand);
    144.         }
    145.  
    146.         //ID 0 stone
    147.         if (newStepsSelected == 0) {
    148.             NewStepsSounds (id0StepsList, id0Jumps, id0Land);
    149.         }
    150.  
    151.         //ID 1 sand
    152.         if (newStepsSelected == 1) {
    153.             NewStepsSounds (id1StepsList, id1Jumps, id1Land);
    154.         }
    155.  
    156.         //ID 2 grass
    157.         if (newStepsSelected == 2) {
    158.             NewStepsSounds (id2StepsList, id2Jumps, id2Land);
    159.         }
    160.  
    161.         //ID 3 gravel
    162.         if (newStepsSelected == 3) {
    163.             NewStepsSounds (id3StepsList, id3Jumps, id3Land);
    164.         }
    165.  
    166.         //ID 4 Earth
    167.         if (newStepsSelected == 4) {
    168.             NewStepsSounds (id4StepsList, id4Jumps, id4Land);
    169.         }
    170.  
    171.  
    172. }
    173.  
    174.     void SettingSoundsByName(RaycastHit hit)
    175.     {
    176.  
    177.         if (hit.transform.name == "House_No_Sound") {
    178.             NewStepsSounds (noSoundList, noSoundJump, noSoundLand);
    179.             newStepsSelected = 99999;
    180.         }
    181.  
    182.         if (hit.transform.name == "water") {
    183.             NewStepsSounds (waterList, waterJump, waterLand);
    184.             newStepsSelected = 1000;
    185.         }
    186.  
    187.         if (   hit.transform.name == "Wood Fence"
    188.             || hit.transform.name == "Medieval_House"
    189.             || hit.transform.name == "Wood Fence Top"
    190.             || hit.transform.name == "House_Wood"
    191.         )
    192.         {
    193.             NewStepsSounds (woodFenceList, woodFenceJump, woodFenceLand);
    194.             newStepsSelected = 1001;
    195.         }
    196.  
    197.         if (hit.transform.name == "Stairs_color_StairCollider") {
    198.             NewStepsSounds (id0StepsList, id0Jumps, id0Land);
    199.             newStepsSelected = 1002;
    200.         }
    201.  
    202.  
    203.     }
    204.  
    205.  
    206.     void NewStepsSounds(List<AudioClip> newSounds, AudioClip newJumpSound, AudioClip newLandSound)
    207.     {
    208.  //This is a very simple method that I did in the FirstPersonController
    209.         GetComponent<FirstPersonController> ().ChangeStepsSounds (newSounds, newJumpSound, newLandSound);
    210.     }
    211. }

    Btw, the "newStepsSelect" is a variable that is "work in progress" that I will use later to check if is the same id than before, so in that case the call to change the steps isn't needed. But still not implemented. And "Manual_Steps" can be removed completly with some tweaks, so I'll do it too.


    Well, with terrain and decorations game objects the code works pretty well. The problem starts when I want use a water steps. If my water have a Collision, it works perfectly, but I want the player can go at half height or totally underwater. It will depend of terrain height.

    In this case the RayCast to Down improved it a bit, but still in some places isn't taking the water correctly and it go to use texture sounds.

    Then I tryed the Sphere, and it worked pretty well! Too pretty well... It was taking the elements around, even if I was too far away (I tryed differents radius values, but it needed to be that big to work fine).

    Of course before all of this I tryed a box collider with a trigger and it worked but it wasn't very accurate to the water area. In essence all geometric gameobjects aren't enought for an non geometric area. Oh, well, they could if I spend alot hours placing alot of them in order to fill all the area and to do a perfect borders.

    I thought too check the player Y coordenate, but maybe in some points could be not correct because player could go to that Y coordenate but in an area without water.

    Well, that's is. I really ill appreciate any help and suggestion. Thanks so much for your time and help and sorry my bad English.
     
  2. vegetamaker

    vegetamaker

    Joined:
    Feb 28, 2017
    Posts:
    37
    Well, like usual with a deserved and comforting rest, and more work later, I find a way to solve it, and I guess it is the correct one.

    Possibly I have sinned of very novice.

    I just used a Trigger that disable the raycast when enter in the area and reactivate it when exit. Then the area is a simple Cube at the water's height. It worked pretty well.

    Atleast, all of this helped me alot to practice the triggers and the raycast ^^.

    When finish, i'll post the code.

    Thanks!