Hello, I am new to Unity. There is a problem with the movement code of my FPS character that you can see below. What I want is for the character to jump only when it touches the ground, but the character can also jump when it is very close to the ground.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AvatarHareket : MonoBehaviour
{
[Header("Movement Settings")]
public float walkSpeed = 5f;
public float sprintSpeed = 8f;
public float crouchSpeed = 3f;
public float mouseSensitivity = 2f;
public float crouchHeight = 0.5f;
public float standingHeight = 2f;
public float crouchTransitionSpeed = 5f;
public float animationDampTime = 0.1f;
public float smoothTime = 0.2f;
[Header("Jump Settings")]
public float jumpForce = 5f;
public float groundCheckDistance = 0.4f;
public LayerMask groundMask;
public float coyoteTime = 0.2f;
public float jumpBufferTime = 0.1f;
public float extraGravity = 0.1f;
private Rigidbody rb;
private Camera playerCamera;
private float verticalRotation = 0f;
private bool isGrounded;
private CapsuleCollider capsuleCollider;
private float defaultSpeed;
private bool isCrouching = false;
private float coyoteTimeCounter;
private float jumpBufferCounter;
private float currentHeight;
private bool isJumping = false;
Animator yBotAnim;
float maxspeed;
float currentSpeed;
float speedVelocity;
void Start()
{
rb = GetComponent<Rigidbody>();
playerCamera = GetComponentInChildren<Camera>();
capsuleCollider = GetComponent<CapsuleCollider>();
Cursor.lockState = CursorLockMode.Locked;
defaultSpeed = walkSpeed;
currentHeight = standingHeight;
yBotAnim = GetComponent<Animator>();
}
void Update()
{
Move();
Rotate();
Jump();
HandleCrouch();
HandleSprint();
GroundCheck();
HandleAnimator();
}
void Move()
{
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
Vector3 movement = transform.forward * moveVertical + transform.right * moveHorizontal;
movement *= defaultSpeed;
RaycastHit hit;
if (Physics.Raycast(transform.position, movement.normalized, out hit, movement.magnitude * Time.deltaTime, groundMask))
{
if (Mathf.Abs(hit.normal.y) > 0.1f)
{
movement.y = 0f;
}
}
rb.velocity = new Vector3(movement.x, rb.velocity.y, movement.z);
}
void Rotate()
{
float horizontalRotation = Input.GetAxis("Mouse X") * mouseSensitivity;
verticalRotation -= Input.GetAxis("Mouse Y") * mouseSensitivity;
verticalRotation = Mathf.Clamp(verticalRotation, -90f, 90f);
transform.Rotate(0, horizontalRotation, 0);
playerCamera.transform.localRotation = Quaternion.Euler(verticalRotation, 0, 0);
}
void Jump()
{
// Zıplama işlemini yalnızca yere temas ediliyorsa yapar.
if (isGrounded)
{
coyoteTimeCounter = coyoteTime;
}
else
{
coyoteTimeCounter -= Time.deltaTime;
}
if (Input.GetButtonDown("Jump"))
{
jumpBufferCounter = jumpBufferTime;
}
else
{
jumpBufferCounter -= Time.deltaTime;
}
if (coyoteTimeCounter > 0f && jumpBufferCounter > 0f && isGrounded)
{
rb.velocity = new Vector3(rb.velocity.x, 0f, rb.velocity.z); // Yüksekliği sıfırla.
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse); // Zıplama kuvveti ekle.
jumpBufferCounter = 0f; // Zıplama tamponunu sıfırla.
coyoteTimeCounter = 0f; // Coyote zamanını sıfırla.
isJumping = true;
}
if (!isGrounded)
{
rb.AddForce(Vector3.down * extraGravity, ForceMode.Acceleration); // Ekstra yerçekimi ekle.
}
}
void GroundCheck()
{
bool wasGrounded = isGrounded;
isGrounded = Physics.Raycast(transform.position, Vector3.down, groundCheckDistance + capsuleCollider.bounds.extents.y, groundMask);
if (isGrounded && !wasGrounded)
{
isJumping = false;
}
}
void HandleCrouch()
{
if (Input.GetKey(KeyCode.LeftControl))
{
isCrouching = true;
}
else
{
isCrouching = false;
}
if (isCrouching)
{
currentHeight = Mathf.Lerp(currentHeight, crouchHeight, crouchTransitionSpeed * Time.deltaTime);
defaultSpeed = crouchSpeed;
}
else
{
currentHeight = Mathf.Lerp(currentHeight, standingHeight, crouchTransitionSpeed * Time.deltaTime);
defaultSpeed = walkSpeed;
}
capsuleCollider.height = currentHeight;
}
void HandleSprint()
{
if (Input.GetKey(KeyCode.LeftShift) && isGrounded && !isCrouching)
{
defaultSpeed = sprintSpeed;
}
else if (!isCrouching)
{
defaultSpeed = walkSpeed;
}
}
void HandleAnimator()
{
if (Input.GetKey(KeyCode.W))
{
if (Input.GetKey(KeyCode.LeftShift))
{
maxspeed = sprintSpeed; // Koşma hızı.
}
else
{
maxspeed = walkSpeed; // Yürüme hızı.
}
}
else
{
maxspeed = 0f; // Durma hızı.
}
// Hızın normalize edilmiş bir değerini animasyon blend tree'ye gönderiyoruz.
currentSpeed = Mathf.SmoothDamp(currentSpeed, maxspeed, ref speedVelocity, smoothTime);
float normalizedSpeed = currentSpeed / sprintSpeed;
yBotAnim.SetFloat("hiz", normalizedSpeed, animationDampTime, Time.deltaTime);
}
}