Skip to content

Instantly share code, notes, and snippets.

@SamatKadyrov
Last active November 23, 2023 07:37
Show Gist options
  • Save SamatKadyrov/86933e398f6c2ba808a81e0dd3ccd7f5 to your computer and use it in GitHub Desktop.
Save SamatKadyrov/86933e398f6c2ba808a81e0dd3ccd7f5 to your computer and use it in GitHub Desktop.
using UnityEngine;
[RequireComponent(typeof(CharacterController))]
public class AdvancedCharacterController : MonoBehaviour
{
[SerializeField] private float _speed = 5.0f; // Скорость передвижения персонажа
[SerializeField] private float _gravity = 9.8f; // Гравитация, влияющая на падение персонажа
[SerializeField] private float _jumpForce = 8.0f; // Сила прыжка персонажа
[SerializeField] private float _slopeForce = 5.0f; // Сила, добавляемая для движения по наклонным поверхностям
[SerializeField] private float _slopeRayLength = 1.5f; // Длина луча, используемая для определения наклонной поверхности
[SerializeField] private float _rotationSpeed = 300.0f; // Скорость вращения персонажа
private CharacterController controller; // Ссылка на компонент CharacterController
private Vector3 moveDirection = Vector3.zero; // Вектор направления движения
private void Awake()
{
controller = GetComponent<CharacterController>(); // Получаем компонент CharacterController
}
private void Update()
{
if (controller.isGrounded) // Проверяем, находится ли персонаж на земле
{
SetMoveDirection();
if (Input.GetButton("Jump")) // Проверка на нажатие клавиши прыжка
{
Jump();
}
}
Rotate();
moveDirection.y -= _gravity * Time.deltaTime; // Применяем гравитацию к перемещению по вертикали
controller.Move(moveDirection * Time.deltaTime); // Выполняем перемещение персонажа в соответствии с текущими изменениями
}
private void FixedUpdate()
{
Slope();
}
private void SetMoveDirection()
{
float horizontalInput = Input.GetAxis("Horizontal"); // Получаем ввод по горизонтали
float verticalInput = Input.GetAxis("Vertical"); // Получаем ввод по вертикали
Vector3 inputDirection = new Vector3(horizontalInput, 0.0f, verticalInput); // Создаем вектор ввода
inputDirection = transform.TransformDirection(inputDirection); // Преобразуем вектор ввода
moveDirection = inputDirection * _speed; // Устанавливаем направление и скорость движения
}
private void Jump()
{
moveDirection.y = _jumpForce; // Применяем силу прыжка
}
private void Rotate()
{
if (Input.GetKey(KeyCode.Q)) // Проверяем нажатие клавиши Q
{
transform.Rotate(Vector3.up, -_rotationSpeed * Time.deltaTime); // Вращаем персонажа влево
}
else if (Input.GetKey(KeyCode.E)) // Проверяем нажатие клавиши E
{
transform.Rotate(Vector3.up, _rotationSpeed * Time.deltaTime); // Вращаем персонажа вправо
}
}
private void Slope()
{
if (Physics.Raycast(transform.position, Vector3.down, out RaycastHit hit, _slopeRayLength) == false) // Выпускаем луч вниз для определения наклонной поверхности
{
return;
}
if (Vector3.Angle(hit.normal, Vector3.up) > controller.slopeLimit) // Если наклон больше допустимого предела
{
moveDirection.x += (1f - hit.normal.y) * hit.normal.x * _slopeForce; // Добавляем силу для движения по наклонной поверхности по X
moveDirection.z += (1f - hit.normal.y) * hit.normal.z * _slopeForce; // Добавляем силу для движения по наклонной поверхности по Z
moveDirection.y -= _slopeForce; // Добавляем силу для "скатывания" по наклонной поверхности
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment