MarioLikeSwimTilemap

 avatar
unknown
plain_text
a year ago
4.7 kB
11
Indexable
using UnityEngine;
using UnityEngine.Tilemaps;

public class MarioLikeSwimTilemap : MonoBehaviour
{
    [Header("Swimming Settings")]
    public float swimHorizontalSpeed = 3f;
    public float swimVerticalBoost = 5f;
    public float waterGravity = 2f;

    private Rigidbody2D rb;
    public TilemapCollider2D waterTilemapCollider;
    private bool isInWater = false;
    private bool isAtSurface = false;
    public Tilemap waterTilemap;
    private PlayerMovement playerMovement;
    private SlopeMovement slopeMovement;
    public AudioClip swim;
    public AudioClip enterWater;
    public AudioClip exitWater;
    private AudioSource audio;

    private Animator animator;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        animator = GetComponent<Animator>();
        playerMovement = GetComponent<PlayerMovement>();
        audio = GetComponent<AudioSource>();
        slopeMovement = GetComponent<SlopeMovement>();
        // Trouver automatiquement le Tilemap Collider marquant l'eau
        //waterTilemapCollider = FindObjectOfType<TilemapCollider2D>();
        if (waterTilemapCollider == null)
        {
            Debug.LogError("A Tilemap Collider 2D for water is required in the scene!");
        }
        //waterTilemap = FindObjectOfType<Tilemap>();
        if (waterTilemap == null)
        {
            Debug.LogError("A Tilemap for water is required in the scene!");
        }
    }

    void Update()
    {
        if (isInWater)
        {
            
            playerMovement.grounded = false;
            playerMovement.jump = 0;
            slopeMovement.enabled = false;
            SwimControls();
            animator.SetBool("isSwimming", true);
            animator.SetBool("isSwimmingUp", Input.GetButton("Jump"));
            rb.gravityScale = waterGravity;
        }
        else
        {
            animator.SetBool("isSwimming", false);
            animator.SetBool("isSwimmingUp", false);
            playerMovement.jump = 5f;
        }
    }

    private void SwimControls()
    {
        // Déplacement horizontal
        float horizontalInput = Input.GetAxis("Horizontal");
        rb.velocity = new Vector2(horizontalInput * swimHorizontalSpeed, rb.velocity.y);

        // Boost vertical dans l'eau ou sortie de l'eau
        if (Input.GetButtonDown("Jump"))
        {
            if ((isAtSurface)&&(Input.GetAxis("Vertical")>0))
            {
                // Sauter hors de l'eau si à la surface
                rb.velocity = new Vector2(rb.velocity.x, swimVerticalBoost);
                isInWater = false;
                audio.PlayOneShot(exitWater);
                Debug.Log("Swim Up:" + rb.velocity.y);
            }
            else if (isAtSurface){
                rb.velocity = new Vector2(rb.velocity.x, 0);
                audio.PlayOneShot(swim);
            }
            else
            {
                // Booster vers le haut sous l'eau
                rb.velocity = new Vector2(rb.velocity.x, swimVerticalBoost);
                Debug.Log("Swim Up:" + rb.velocity.y);
                audio.PlayOneShot(swim);
            }
        }
    }

    private void FixedUpdate()
    {
        if (isInWater)
        {
            // Réduction de la gravité dans l'eau
            rb.gravityScale = waterGravity;

            // Détection si proche de la surface
            if (waterTilemapCollider != null)
            {
                Vector2 playerPosition = transform.position;

                // Vérifier si le personnage est près de la limite supérieure de la zone
                isAtSurface= IsAtSurface(playerPosition);
            }
        }
        else
        {
            // Retour à la gravité normale hors de l'eau
            rb.gravityScale = 1f;
        }
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision == waterTilemapCollider)
        {
            isInWater = true;
            audio.PlayOneShot(enterWater);
        }
    }

    private void OnTriggerExit2D(Collider2D collision)
    {
        if (collision == waterTilemapCollider)
        {
            isInWater = false;
            isAtSurface = false;
        }
    }
    private bool IsAtSurface(Vector2 position)
    {
        Vector3Int tilePosition = waterTilemap.WorldToCell(position);
        TileBase currentTile = waterTilemap.GetTile(tilePosition);

        // Vérifie si la tuile au-dessus est vide
        Vector3Int tileAbove = new Vector3Int(tilePosition.x, tilePosition.y + 1, tilePosition.z);
        Debug.Log(currentTile != null && waterTilemap.GetTile(tileAbove) == null);
        return currentTile != null && waterTilemap.GetTile(tileAbove) == null;
        
    }
}
Editor is loading...
Leave a Comment