0
\$\begingroup\$

I'm working on an FPS for my first time.

I'm creating a simple terrain and instatiating 15 cubes on my terrain. (This works fine). Each cube is named "cube" and has a static trigger collider.

Here's what my scene looks like:

Unity editor screenshot

When my first person controller collides with my cube (instantiated object) then I want the cube to deactivate and add 1 to my score, but nothing happens.

Code: I added this code in FirstPersonController.cs

void OnTriggerEnter(Collider other)
{
    if (other.gameObject.name == "cube")
    {

        other.gameObject.SetActive(false); 
        // when the player touches my spawned object then I want to 
        // deactivate my cube, but nothing happens

        Debug.Log("collidedwith:" + other.gameObject.name); 

        score += 1;
        scoreText.text = score.ToString();     

    }
}
\$\endgroup\$
0
\$\begingroup\$

Advice I give to Unity developers is please never look up or compare GameObjects by name. It's a very brittle way to work and we have better options available to us.

In this case, your cube objects are not named "cube" or "Cube". They're named "Cube(Clone)" as we can see in your screenshot, so comparing the name to "cube" returns false and you always skip the inner code.

You can find this yourself by putting at the top of your method, before the if:

Debug.LogFormat("Collided with {0}", other.gameObject.name);

This will let you see how the name of what you're colliding with actually shows up in game.

So, better things we can do:

  1. Make a ScorePickup physics layer that only collides with itself. Put all your score pickups on this layer, and give your player object a collider on this layer to detect them, with a ScoreCollector script on it to receive and act on the trigger messages.

    Now you don't need an if check at all: only collisions with score pickups will fire the OnTriggerEnter message on this script, no filtering required.

    Or...

  2. Give the cubes a tag "ScorePickup" (name your stuff based on what it does, not what shape it is - shapes often change as you update your game's look) then change your if check to if(other.gameObject.CompareTag("ScorePickup")) to match the tag instead of the name. This is much more robust to scene changes than names, which are easy to change accidentally.

    Or...

  3. Create a ScorePickup MonoBehaviour script and put it on your score pickup prefab. You can then check if the object you've collided with is a score pickup like so:

    var pickup = other.gameObject.GetComponent();
    if(pickup != null) {...

    The advantage of doing it this way is you can give the ScorePickup additional properties and behaviour. Like a variable to control how much score it's worth, so you can have little pickups and big pickups both using the same script. You could also include collection sounds & particle effects here.

\$\endgroup\$
  • \$\begingroup\$ Thanks for suggestion, It a big help for me. \$\endgroup\$ – jishan nuran Aug 1 at 16:40
  • \$\begingroup\$ can u give referance for this ,i want player should be able to feel the low gravity?? how can i do this?? \$\endgroup\$ – jishan nuran Aug 1 at 16:52
  • \$\begingroup\$ That sounds like a different question. Post it separately, and ensure you include lots of detail so a reader can clearly understand what you mean by "feel the low gravity" \$\endgroup\$ – DMGregory Aug 1 at 17:03
0
\$\begingroup\$

When you instantiate an object then the name of the object will be "Object Name+(Clone)" for example in your case the object name you want to instantiate is "cube" but after the instantiation the name will be "cube(Clone)" so you have to compare with "cube(Clone)" instead of "cube".

void OnTriggerEnter(Collider other)
{
      if (other.gameObject.name == "cube(Clone)")
      {
            other.gameObject.SetActive(false);
            Debug.Log("collidedwith:" + other.gameObject.name); 

            score += 1;
            scoreText.text = score.ToString();     

       }
}

By the way the way you use to detect an object is not a perfect way so my suggestion is to use Tags and the check for specific tag instead of the name. Eg your code will become like this:

private void OnTriggerEnter(Collider other)
{
    if (other.gameObject.CompareTag("cube"))
    {
        other.gameObject.SetActive(false);
        Debug.Log("collidedwith:" + other.gameObject.name);

        score += 1;
        scoreText.text = score.ToString();
    }
}

So Now the object name does't matter any more And also i used "CompareTag("Tag")" instead of "Tag == Tag", its because this will provide better performance and also if the tag is not define unity will notify you So you will be having better control over you code.

I hop it helps...

\$\endgroup\$
  • \$\begingroup\$ ,its work for me thanks for your suggestion \$\endgroup\$ – jishan nuran Aug 1 at 16:41
  • \$\begingroup\$ I am glad it helped... plz up vote the answer if it helped This might help others too. cheers!. \$\endgroup\$ – Swati Aug 2 at 4:37
  • \$\begingroup\$ @ user3733160 can u give referance for this ,i want player should be able to feel the low gravity?? how can i do this?? \$\endgroup\$ – jishan nuran Aug 2 at 5:33
  • \$\begingroup\$ you can make gravity low or high by this: Physics.gravity = new Vector3(0, custom_Gravity, 0); "custom_Gravity" is a float value. default gravity is 9.8f. By the way you ask this question separately, So that if other people can see it. \$\endgroup\$ – Swati Aug 2 at 6:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.