I need help in a player script, I'm implementing his swimming, when it collides with the 2d box Collider from the water, it stays as true, so I can swim (lowered his gravity and stuff). My question is the following, I followed a tutorial on the web, but when my player starts to swim, it's ok, I do a "jump" to give impulse to swim, like super mario, but then he leaves the water when he enters again he falls very quickly . And also when it collides with the ground which is the ground (at the bottom of the water) it gets stuck and nothing happens. What can I do to solve this problem?
Video showing both problems: Falling down very quickly when entering the water and getting stuck at the bottom (Ground). Link video
public class PlayerMovement2D : MonoBehaviour{
//Movement
private float move;
public float moveSpeed;
//GroundCheck
[SerializeField] LayerMask groundLayer;
//Jump
Vector2 vecGravity;
[Header("Jump System")]
public float jumpPower;
public float jumpTime;
public float fallMultiplier;
public float jumpMultiplier;
public bool isJumping;
float jumpCounter;
//Swimming
private float swimmingTime;
public float forceSwimming;
private bool Swimming;
private CapsuleCollider2D bc2d;
Rigidbody2D rb;
SpriteRenderer sprite;
Animator animationPlayer;
void Start()
{
vecGravity = new Vector2(0, -Physics.gravity.y);
rb = GetComponent<Rigidbody2D>();
sprite = GetComponent<SpriteRenderer>();
animationPlayer = GetComponent<Animator>();
bc2d = GetComponent<CapsuleCollider2D>();
}
void Update()
{
if(Input.GetButtonDown("Jump") && isGrounded())
{
rb.velocity = new Vector2(rb.velocity.x, jumpPower);
isJumping = true;
jumpCounter = 0;
}
if(rb.velocity.y>0 && isJumping)
{
jumpCounter += Time.deltaTime;
if (jumpCounter > jumpTime) isJumping = false;
float t = jumpCounter / jumpTime;
float currentJumpM = jumpMultiplier;
if (t > 0.5f)
{
currentJumpM = jumpMultiplier * (1 - t);
}
rb.velocity += vecGravity * jumpMultiplier * Time.deltaTime;
}
if (Input.GetButtonUp("Jump"))
{
isJumping = false;
jumpCounter = 0;
if (rb.velocity.y > 0)
{
rb.velocity = new Vector2(rb.velocity.x, rb.velocity.y * 0.6f);
}
}
if (rb.velocity.y < 0)
{
rb.velocity -= vecGravity * fallMultiplier * Time.deltaTime;
}
//Input de movimentação do personagem
move = Input.GetAxis("Horizontal");
if (move != 0)
{
moveSpeed += 20f * Time.deltaTime;
if (moveSpeed >= 8.0f)
{
moveSpeed = 8.0f;
}
}
else
{
moveSpeed = 0;
}
//Inverter a posição do personagem
if (move < 0)
{
sprite.flipX = true;
}
else if (move > 0)
{
sprite.flipX = false;
}
if (isGrounded())
{
animationPlayer.SetBool("JumpingV", false);
animationPlayer.SetBool("FallingV", false);
animationPlayer.SetBool("JumpingH", false);
animationPlayer.SetBool("FallingH", false);
if (rb.velocity.x != 0 && move != 0)
{
animationPlayer.SetBool("IsWalking", true);
}
else
{
animationPlayer.SetBool("IsWalking", false);
}
}
else
{
if (rb.velocity.x == 0)
{
animationPlayer.SetBool("IsWalking", false);
if (rb.velocity.y > 0)
{
animationPlayer.SetBool("JumpingV", true);
animationPlayer.SetBool("FallingV", false);
animationPlayer.SetBool("JumpingH", false);
animationPlayer.SetBool("FallingH", false);
}
if (rb.velocity.y < 0)
{
animationPlayer.SetBool("JumpingV", false);
animationPlayer.SetBool("FallingV", true);
animationPlayer.SetBool("JumpingH", false);
animationPlayer.SetBool("FallingH", false);
}
}
else
{
if (rb.velocity.y > 0)
{
animationPlayer.SetBool("JumpingV", false);
animationPlayer.SetBool("FallingV", false);
animationPlayer.SetBool("JumpingH", true);
animationPlayer.SetBool("FallingH", false);
}
if (rb.velocity.y < 0)
{
animationPlayer.SetBool("JumpingV", false);
animationPlayer.SetBool("FallingV", false);
animationPlayer.SetBool("JumpingH", false);
animationPlayer.SetBool("FallingH", true);
}
}
if (Swimming)
{
do
{
animationPlayer.SetBool("Swimming", false);
swimmingTime -= Time.deltaTime;
}
while (swimmingTime > 0);
if (swimmingTime <= 0)
{
swimmingTime = 0;
animationPlayer.SetBool("Swimming", true);
}
fallMultiplier = 0f;
jumpPower = 0f;
jumpTime = 0f;
rb.gravityScale = 0f;
animationPlayer.SetBool("JumpingV", false);
animationPlayer.SetBool("FallingV", false);
animationPlayer.SetBool("JumpingH", false);
animationPlayer.SetBool("FallingH", false);
if (Input.GetButtonDown("Jump") && swimmingTime <= 0)
{
Debug.Log("abraçada");
animationPlayer.SetTrigger("SwimmingMoving");
ForceSwimming();
}
}
else
{
//Nadando
rb.gravityScale = 1f;
animationPlayer.SetBool("Swimming", false);
}
}
}
void FixedUpdate()
{
rb.velocity = new Vector2(move * moveSpeed, rb.velocity.y);
}
public void ForceSwimming()
{
animationPlayer.SetBool("Swimming", false);
rb.AddForce(new Vector2(rb.velocity.x, forceSwimming), ForceMode2D.Impulse);
swimmingTime = 0.1f;
}
private void OnTriggerEnter2D(Collider2D col)
{
if (col.gameObject.CompareTag("water") == true)
{
Swimming = true;
}
}
private void OnTriggerExit2D(Collider2D col)
{
Debug.Log("Out Trigger");
if (col.gameObject.CompareTag("water") == true)
{
Swimming = false;
rb.gravityScale = 1f;
fallMultiplier = 6f;
jumpPower = 9f;
jumpTime = 0.1f;
}
}
private bool isGrounded()
{
float extraHeightText = 1f;
RaycastHit2D raycastHit = Physics2D.BoxCast(bc2d.bounds.center, bc2d.bounds.size, 0f, Vector2.down, extraHeightText, groundLayer);
Color rayColor;
if(raycastHit.collider != null)
{
rayColor = Color.green;
}
else
{
rayColor = Color.red;
}
//Debug.DrawRay(bc2d.bounds.center + new Vector3(bc2d.bounds.extents.x, 0), Vector2.down * (bc2d.bounds.extents.y + extraHeightText), rayColor);
//Debug.DrawRay(bc2d.bounds.center - new Vector3(bc2d.bounds.extents.x, 0), Vector2.down * (bc2d.bounds.extents.y + extraHeightText), rayColor);
//Debug.DrawRay(bc2d.bounds.center - new Vector3(bc2d.bounds.extents.x, bc2d.bounds.extents.y + extraHeightText), Vector2.right * (bc2d.bounds.extents.x), rayColor);
//Debug.Log(raycastHit.collider);
return raycastHit.collider != null;
//return Physics2D.BoxCast(bc2d.bounds.center, bc2d.bounds.size, 0f, Vector2.down, 1f, groundLayer);
}
}