Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Character smelling objects in game

Discussion in 'Scripting' started by KrisM, Feb 24, 2015.

  1. KrisM

    KrisM

    Joined:
    Oct 18, 2014
    Posts:
    28
    I'm trying to create a system that allows players (and eventually NPCs) to track items/people via smell.

    Trouble is, I'm fairly new to C# and Unity, so I'm not sure of the best way to handle this. I'd greatly appreciate some detail in responses because of this.

    Based on my current knowledge, I'm thinking that the best way to handle this is to create an empty object to act as a 'smell field'. This will be separate from the originating object, and flow across the map according to wind direction. These will instantiate at set intervals and destruct after a set time. I have a script attached to this empty object that will increase the size of the collider over time, dictate the smell type, and how strong it is (degrades over time).

    My current hurdle is passing details from the empty object to the player(s) that collides with or triggers it. I'm not sure how to get this working.

    But I'm also keen to hear feedback on whether I'm going about this in the wrong way; in terms of game performance and ease of implementation.
     
  2. KrisM

    KrisM

    Joined:
    Oct 18, 2014
    Posts:
    28
    To add some details:

    This is the script I'm using to gather details from the collider:
    Code (CSharp):
    1.     void OnTriggerEnter(Collider col)
    2.     {
    3.         smellHUDText.text = col.gameObject.name;
    4.     }
    There's a script attached to the object containing the collider, with a public string called "smellType". How do I go about collecting this string within another script?
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,749
    Interesting problem. I will have to think more about it, but at first glance what you say seems like a way to get it going.

    As for finding that string, you can do it in these these steps:

    - from the Collider reference passed in, you can get at the gameObject (which is the thing you are triggering in)
    - from the gameObject you can get at the component (script) that contains the .smellType (use .GetComponent<>())

    You might need to "leave behind" some more information inside the smell cloud, like a direction of travel from the guy who left the smell. This may seem like cheating, but a vector direction like would simply be a mathematical proxy for what you do when you smell a scent: you move your nose around looking for where it is stronger, ie., you try to sense the spatial gradient.
     
    KrisM likes this.
  4. KrisM

    KrisM

    Joined:
    Oct 18, 2014
    Posts:
    28
    Thanks for the advice Kurt. I've managed to get it working like this:
    Code (CSharp):
    1. smellName = col.GetComponent<SmellScript> ().smellName;
    Works well. I did have a bit of trouble working through your advice.. me being a beginner with C# leaves me wondering what goes in <> and before .GetComponent. But some googling based on your direction sorted me out.

    I'm thinking I won't need to worry about direction details. I'll likely add a HUD component for wind direction, and allow players to try and figure it out themselves. If / once they get close enough, they'll be able to track by footprints (which is another project).

    I've yet to do some messing about with lists (or array lists) to combine smell and strength types, and compile them into a HUD display. I did have a look at this, but it was a bit beyond me at the time.

    Anyhow, thanks again for your help!
     
  5. KrisM

    KrisM

    Joined:
    Oct 18, 2014
    Posts:
    28
    My next issue seems to be with having multiple colliders functioning at once. I've got two Smells on the field. I can step into each one, and have my HUD update with the right details. But if these two colliders overlap, and I step into that justaposition, only one set of details is passed over (in no particular order, it seems).

    Code (CSharp):
    1.     void OnTriggerStay(Collider col)
    2.    
    3.             smellOriginString = col.gameObject.name;
    4.  
    5.                         if (smellOriginString == "SmellGrass") {
    6.                                 grassSmellName = col.GetComponent<Grass> ().SmellType;
    7.                                 grassSmellPower = col.GetComponent<Grass> ().SmellPower;
    8.  
    9.                         }
    10.  
    11.             smellOriginString = col.gameObject.name;
    12.  
    13.                         if (smellOriginString == "SmellFlowers") {
    14.                                 flowerSmellName = col.GetComponent<Flowers> ().SmellType;
    15.                                 flowerSmellPower = col.GetComponent<Flowers> ().SmellPower;
    16.  
    17.                         }
    18. }
    It also seems like I can't make a secondary 'void OnTriggerStay(Collider col)' because it's already been named.
     
  6. KrisM

    KrisM

    Joined:
    Oct 18, 2014
    Posts:
    28
    Sorry for the repeated posts. Sometimes writing my problems down helps with solving them. And I'm updating in case other people are having similar issues and need a solution.

    I've fixed this problem by changing the 'OnTriggerStay' to an 'OnTriggerEnter' and 'OnTriggerExit'. This way, the colliders aren't being triggered constantly (saving on performance) and each one is a separate instance.