Enemy that needs to jump with gravity but ignore colliders.

Hi, I’ve only been using Unity for a few weeks, and I’m trying to remake the first level of Sonic the Hedgehog to challenge myself. I’ve run into a roadblock that I can’t figure out.

The red fish that jump up repeatedly at the bridges in the Green Hill Zone are giving me trouble. I need it to be able to ignore the colliders on the bridge from both directions and I need it to be able to recognize Sonic when they collide, so I was thinking about using isTrigger, but when I use isTrigger, it just falls through everything. I was hoping to set another object and use it’s Transform position in an if statement to get the fish to jump each time it gets close to the empty object. This doesn’t seem to be working. Any ideas about how to deal with this problem? Here’s my code for the fish:

public class Chopper : MonoBehaviour
{
    //Creates a field in the inspector to link the sonic game object.
    public GameObject sonic;
    //Creates a variable to hold a SonicController_FSM script component.
    private SonicController_FSM sonicScript;

    //Creates a field in the inspector to link the associated jump point for chopper.
    public Transform jumpPoint;

    //Creates a field in the inspector to place chopper's animator.
    public Animator chopperAnimator;

    //Creates a field in the inspector to place chopper's rigidbody2D.
    public Rigidbody2D chopperRb2d;

    public CapsuleCollider2D capsuleCollider;

    //Set's the force at which the fish will keep jumping in the air.
    public float jumpForce = 5;

    void Start()
    {
        sonicScript = sonic.GetComponent<SonicController_FSM>();
        chopperAnimator = GetComponent<Animator>();
        chopperRb2d = GetComponent<Rigidbody2D>();
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.tag == "SonicPlayer")
        {
            if (sonicScript.isDeadly)
            {
                chopperRb2d.isKinematic = true;
                chopperAnimator.Play("Enemy_Explosion");
                Invoke("Destroyed", 0.3f);
            }
        }
    }

    void Update()
    {
        Jump();
    }

    private void Jump()
    {
        //Checks if the choppers's position is less than .2 from the current waypoint's position.
        if (Vector2.Distance(jumpPoint.transform.position, transform.position) < 0.2f)
        {
            chopperRb2d.AddForce(transform.up * jumpForce);
        }
    }

        //Destroys the game object.
        private void Destroyed()
    {
        Destroy(gameObject);
    }
}

That is kinda how I would do it.

I would make a GameObject with trigger area such that when Sonic enters it, the fish wakes up and leaps, if he’s not already leaping.

The key would be each trigger area would wake up a specific fish, so the trigger area handling script would have a reference to the fish it was waking up.

Such a thing is trivial enough to set up quickly to test, just one trigger linked to one fish, a simple script to make it work… if you have difficulties, here is my go-to debugging steps:

You must find a way to get the information you need in order to reason about what the problem is.

What is often happening in these cases is one of the following:

  • the code you think is executing is not actually executing at all
  • the code is executing far EARLIER or LATER than you think
  • the code is executing far LESS OFTEN than you think
  • the code is executing far MORE OFTEN than you think
  • the code is executing on another GameObject than you think it is

To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

Doing this should help you answer these types of questions:

  • is this code even running? which parts are running? how often does it run? what order does it run in?
  • what are the values of the variables involved? Are they initialized? Are the values reasonable?
  • are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

Knowing this information will help you reason about the behavior you are seeing.

You can also put in Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene

You could also just display various important quantities in UI Text elements to watch them change as you play the game.

If you are running a mobile device you can also view the console output. Google for how on your particular mobile target.

Here’s an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

https://discussions.unity.com/t/839300/3