Hit when i start , and i cant jump on other tilemaps

for details of my game ( i will provide photos and code ) my level is about fghting a boss where he will throw three fireballs that follow player three times then rest where the player can hit him.

Here are the two main Problems :

1 - Three Obstacles above the tilemap a( they are all are 1 tilemap but i defrentiate them using three gameobject box colliders) . Now the charcter moves in and jump when its in land but when the player lands on one of three obstacles , the jump not work

2- When i play the game the player get hit whenever i start without anything touches him .

Now here is the code of this unfinished game

Boss Controller :

using System.Collections;
using UnityEngine;

public class BossController : MonoBehaviour
{
    public Transform firepoint;
    public GameObject fireballPrefab;
    public Animator bossAnimator;
    public Transform player; // Add a reference to the player

    private bool isShooting = false;
    private bool isDefeated = false;

    void Start()
    {
        StartCoroutine(BossBehavior());
    }

    IEnumerator BossBehavior()
    {
        while (!isDefeated)
        {
            // Boss is not defeated
            if (!isDefeated)
            {
                // Set the isShooting parameter in the animator to trigger the shooting animation
                isShooting = true;
                bossAnimator.SetBool("IsShooting", isShooting);

                // Wait for the animation to complete
                yield return new WaitForSeconds(3);

                // Shoot three fireballs
                for (int i = 0; i < 3; i++)
                {
                    ShootFireball();
                    yield return new WaitForSeconds(1);
                }

                // Wait for all fireballs to be shot
                yield return new WaitForSeconds(1);

                // Reset isShooting parameter to false
                isShooting = false;
                bossAnimator.SetBool("IsShooting", isShooting);

                // Wait for a cooldown or any other condition before shooting again
                yield return new WaitForSeconds(3);
            }

            yield return null; // Allows the frame to update
        }
    }

    void ShootFireball()
    {
        // Instantiate the fireball
        GameObject fireball = Instantiate(fireballPrefab, firepoint.position, firepoint.rotation);

        // Calculate the direction towards the player
        Vector3 direction = (firepoint.position - player.position).normalized; // Reverse the direction

        // Set the velocity of the fireball to shoot left
        fireball.GetComponent<Rigidbody2D>().velocity = direction * fireball.GetComponent<FireballController>().speed;
    }

    public void PlayerHitBoss()
    {
        // Player hits the boss
        // Decrease boss health or handle defeat logic
        // For example, you can reduce health and check if the boss is defeated
        // If the boss is defeated, set isDefeated to true to exit the coroutine
        // If the boss is not defeated, you might want to play a hit animation

        // For simplicity, let's assume the boss is defeated after a certain number of hits
        isDefeated = true;
        bossAnimator.SetBool("IsDefeated", isDefeated);
    }
}

PlayerStats:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerStats_4 : MonoBehaviour
{
    public int health = 6;
    public int lives = 2;
    public float flickerDura1on = 0.1f;
    private float flickerTime = 0f;
    private SpriteRenderer spriteRenderer;
    public bool isImmune = false;
    public float immunityDura1on = 1.5f; //el w2t ely sonic 3mal ynor w ytfy
    private float immunityTime = 0f;
    public KeyCode Return;
    public Transform firepoint;
    public GameObject bullet;
    public bool IsShooting = false;
    public Animator anim;


    // public int coinsCollected = 0;
    void Start()
    {
        spriteRenderer = this.gameObject.GetComponent<SpriteRenderer>();
    }
    // Update is called once per framea
    void Update()
    {
        if (this.isImmune == true)
        {
            SpriteFlicker();
            immunityTime = immunityTime + Time.deltaTime;
            if (immunityTime >= immunityDura1on)
            {
                this.isImmune = false;
                this.spriteRenderer.enabled = true;
            }
        }

      
       if (Input.GetKeyDown(Return)) { Shoot();}

      
    }
    public void TakeDamage(int damage)
{
    if (this.isImmune == false)
    {
        this.health -= damage;

        if (this.health < 0f)
            this.health = 0;

        if (this.lives > 0f && this.health == 0f)
        {
            FindObjectOfType<LevelManager>().RespawnPlayer();
            this.health = 6;
            this.lives--;
        }
        else if (this.lives == 0 && this.health == 0)
        {
            FindObjectOfType<LevelManager>().Gameover();
            Debug.Log("Gameover"); //add game over splash screen
            StartCoroutine(DelayedDestroy());
        }

        Debug.Log("Player Health : " + this.health.ToString());
        Debug.Log("Player Lives : " + this.lives.ToString());
    }

    PlayHitReac1on();
}

IEnumerator DelayedDestroy()
{
    yield return new WaitForSeconds(1); // You can adjust the delay as needed
    Destroy(this.gameObject);
}

    public void Shoot()
{
    Instantiate(bullet, firepoint.position, firepoint.rotation);
    IsShooting = true;
    anim.SetBool("Shoot", IsShooting);
    StartCoroutine(ResetShootAnimation());
}

IEnumerator ResetShootAnimation()
{
    // Wait for the duration of the shooting animation
    yield return new WaitForSeconds(1);

    // Set the boolean parameter back to false to transition to the idle state
    IsShooting = false;
    anim.SetBool("Shoot", IsShooting);
}

 

   
   
    void PlayHitReac1on()
    {
        this.isImmune = true;
        this.immunityTime = 0f;
    }
    void SpriteFlicker()
    {
        if (this.flickerTime < this.flickerDura1on)
        {
            this.flickerTime = this.flickerTime + Time.deltaTime;
        }
        else if (this.flickerTime >= this.flickerDura1on)
        {
            spriteRenderer.enabled = !(spriteRenderer.enabled);
            this.flickerTime = 0;
        }
    }
  
} //Class

Fireball Controller:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FireballController : MonoBehaviour
{
    public float speed; // speed of the bullet
    private PlaterMovement_4 player;
    public int damage = 2;

    // Use this for initialization
    void Start()
    {
        SetSizeToParent();
        transform.localScale = new Vector3(17, 17, 17);

        // Initialize the player variable
        player = FindObjectOfType<PlaterMovement_4>();

        if (player == null)
        {
            Debug.LogError("Player not found!");
        }

        BossController boss = FindObjectOfType<BossController>();

        if (boss.transform.localScale.x > 0)
        {
            speed = -speed; // Make the bullet move left if the boss is facing right
        }
        else
        {
            speed = Mathf.Abs(speed); // Make the bullet move left if the boss is facing left
        }
    }

    void SetSizeToParent()
    {
        // Find the parent object (in this case, it might be the Player)
        PlayerStats_4 player = FindObjectOfType<PlayerStats_4>();

        // Set the local scale of the bullet to match the local scale of the parent
        transform.localScale = new Vector3(player.transform.localScale.x, player.transform.localScale.y, 1);

        // Adjust the size based on a scale factor
        float scaleFactor = 2.0f; // You can adjust this value based on your preference
        transform.localScale *= scaleFactor;
    }

    void Update()
    {
        if (player != null)
        {
            // Get the player's position
            Vector3 targetPosition = player.transform.position;

            // Set a fixed Y-coordinate for the enemy (adjust this value as needed)
            float fixedY = 0.0f;

            // Create a new position with the fixed Y-coordinate
            Vector3 newPosition = new Vector3(targetPosition.x, fixedY, targetPosition.z);

            // Move the enemy towards the new position
            transform.position = Vector3.MoveTowards(transform.position, newPosition, 2f * Time.deltaTime);
        }
    }

    void OnTriggerEnter2D(Collider2D other)
    {
        // The bullet affects any game object that is tagged "Player"
        if (other.tag == "Player")
        {
            FindObjectOfType<PlayerStats_4>().TakeDamage(damage);
            // Handle the collision with the Player (e.g., apply damage)
        }

        // Destroy the bullet when it collides with anything
       
    }
}

LevelManager:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;


public class LevelManager : MonoBehaviour
{
    private bool GameHasEnded = false;
    public float delay = 2f;

    public void Gameover()
    {
        if (GameHasEnded == false)
        {
            GameHasEnded = true;
            // Uncomment the line below if you want to restart the scene after delay seconds
            // Invoke("Restart", delay);
        }
    }

    private void Restart()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().name);
    }

    public GameObject CurrentCheckpoint;

    void Start()
    {
    }

    void Update()
    {
    }

    public void RespawnPlayer()
    {
        FindObjectOfType<PlaterMovement_4>().transform.position = CurrentCheckpoint.transform.position;
    }
}

PlaterMovement:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlaterMovement_4 : MonoBehaviour
{
   public float moveSpeed;
   public float jumpHeight;

   public KeyCode Spacebar;

   public KeyCode L;
   public KeyCode R;
   public Transform groundCheck;
   public float groundCheckRadius;
   public LayerMask WhatIsGround;
   private bool grounded;
   private Animator anim;


   void Start()
   {
       anim=GetComponent<Animator>();
   }

   void Update()
   {
    if(Input.GetKeyDown(Spacebar)&&grounded)
    {
        Jump();
    }

    if(Input.GetKey(L))
    {
        GetComponent<Rigidbody2D>().velocity = new Vector2(-moveSpeed,GetComponent<Rigidbody2D>().velocity.y);

        if(GetComponent<SpriteRenderer>()!=null)
        {
            GetComponent<SpriteRenderer>().flipX = false;
        }
    }

    if(Input.GetKey(R))
    {
        GetComponent<Rigidbody2D>().velocity = new Vector2(moveSpeed,GetComponent<Rigidbody2D>().velocity.y);

        if(GetComponent<SpriteRenderer>()!=null)
        {
            GetComponent<SpriteRenderer>().flipX = true;
        }
    }

    anim.SetFloat("speed",Mathf.Abs(GetComponent<Rigidbody2D>().velocity.x));
   }

   void Jump()
   {
    GetComponent<Rigidbody2D>().velocity = new Vector2(GetComponent<Rigidbody2D>().velocity.x, jumpHeight);
     anim.SetBool("grounded", grounded);
   }

 
   void FixedUpdate()
   {
    grounded = Physics2D.OverlapCircle(groundCheck.position,groundCheckRadius,WhatIsGround);
      
   }
}

EnemyFollow:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyFollow : EnemyController
{
    private Controller player;

    // Start is called before the first frame update
    void Start()
    {
        player = FindObjectOfType<Controller>();
    }

    // Update is called once per frame
    void Update()
    {
        // Get the player's position
        Vector3 targetPosition = player.transform.position;

        // Set a fixed Y-coordinate for the enemy (adjust this value as needed)
        float fixedY = 0.0f;

        // Create a new position with the fixed Y-coordinate
        Vector3 newPosition = new Vector3(targetPosition.x, fixedY, targetPosition.z);

        // Move the enemy towards the new position
        transform.position = Vector3.MoveTowards(transform.position, newPosition, 2f * Time.deltaTime);
    }
    void OnTriggerEnter2D(Collider2D other)
    {
        if (other.tag == "Player")
        {
            FindObjectOfType<PlayerStats>().TakeDamage(damage);
        }

    }
}

Bulletcontroller:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BulletController : MonoBehaviour
{
    public Transform firepoint;
    public GameObject Bullet;
    public float speed;

    // create a variable in which the player (and by extension his/her controller could be stored)
    // Use this for initialization
    void Start()
    {
        transform.localScale = new Vector3(3, 3, 3);

        PlaterMovement_4 player;
        player = FindObjectOfType<PlaterMovement_4>();

        if (player.transform.localScale.x < 0)
            speed = -speed;
            transform.localScale = new Vector3(-(transform.localScale.x),transform.localScale.y,transform.localScale.z);
    }

    void Update()
    {
        GetComponent<Rigidbody2D>().velocity = new Vector2(speed, GetComponent<Rigidbody2D>().velocity.y);
    }

    void OnTriggerEnter2D(Collider2D other) // the bullet only affects any game object that is tagged enemy!
    {
        if (other.tag == "Boss")
        {
        Destroy(other.gameObject);
        Destroy(this.gameObject);
        }
       
    }
}

Hope A Hero Helps




For your first issue, are your obstacles on the same Layer as the ground? Since you can only jump when the player is grounded, which only becomes true from this line:

grounded = Physics2D.OverlapCircle(groundCheck.position,groundCheckRadius,WhatIsGround);

Then you need to make sure your obstacles are on the same layer, otherwise the “grounded” bool will not return true.

For your second issue, put in some Debug.Logs everywhere your TakeDamage function is called. I see one of them on your OnTriggerEnter2D function on the EnemyFollow class. I see another on your FireballController in the TriggerEnter function as well.

One thing that stands out to me is on the FireballController, you have

FindObjectOfType<PlayerStats_4>().TakeDamage(damage);

But on the EnemyFollow, it is just PlayerStats, not PlayerStats_4 (a class you did not share if it does exist)

Then test your game once you have some Debug.Log functions stated and see where/when/how they are called.