Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- private void StartClimbing(ParkourObstacle obstacle, ParkourObstacle.Wall wall, Vector3 startPoint)
- {
- //Взводим флаг
- _isClimbing = true;
- //Создаём плоскость стены дабы с помощью нормали её определить точку начала паркура
- Plane wallPlane = new Plane(wall.GetPoint(0), wall.GetPoint(1), wall.GetPoint(2));
- //Вычисляем две точки начала паркура, по обе сторон от стены
- Vector3 startPosition1 = startPoint + (wallPlane.normal * _playerController.CharacterRadius * -1);
- Vector3 startPosition2 = startPoint + (wallPlane.normal * _playerController.CharacterRadius);
- //та точка которая будет ближайшей к игроку, нас и интересует.
- //Очень важно правильно выбрать точку. Ибо игрок может оказаться внутри препятствия
- //или на противоположной стороне от него
- Vector3 climbStartPosition = Vector3.Distance(transform.position, startPosition1) < Vector3.Distance(transform.position, startPosition2) ? startPosition1 : startPosition2;
- //Вращение "Лицом к стене"
- Quaternion climbStartRtotation = Quaternion.LookRotation(startPoint - climbStartPosition, Vector3.up);
- //Запоминаем горизонтальную скорость которая была до начала залезания
- _velocityBeforeClimb = new Vector2(_rigidbody.velocity.x, _rigidbody.velocity.z).magnitude;
- //Сбрасываем скорость
- _rigidbody.velocity = Vector3.zero;
- //Отключаем управление персонажем
- _playerController.enabled = false;
- //Выключаем физику, дабы гравитация нам не мешала
- _rigidbody.isKinematic = true;
- //Запускаем корутину
- _parkourCoroutine = StartCoroutine(Climbing(obstacle, wall, climbStartPosition, climbStartRtotation));
- }
- private IEnumerator Climbing(ParkourObstacle obstacle, ParkourObstacle.Wall wall, Vector3 startPoint, Quaternion startRotation)
- {
- //Первый этап из позиции персонажа к позиции начала паркура
- Vector3 startPlayerPosition = transform.position;
- Quaternion startPlayerRotation = transform.rotation;
- float elapsed = 0f;
- //Вычисляем время на перемещение из скорости перемещения
- float translationTime = Vector3.Distance(startPlayerPosition, startPoint) / _translationVelocity;
- while (elapsed < translationTime)
- {
- //Плавно перемещаем персонажа
- transform.position = Vector3.Lerp(startPlayerPosition, startPoint, elapsed / translationTime);
- transform.rotation = Quaternion.Lerp(startPlayerRotation, startRotation, elapsed / translationTime);
- elapsed += Time.deltaTime;
- yield return null;
- }
- //Второй этап - подъём вверх
- //Вычисляем точку назначения из позиции персонажа
- //Добавив к ней высоту подъёма и половину "роста" персонажа
- startPlayerPosition = transform.position;
- Vector3 targetUpPosition = new Vector3(transform.position.x,
- wall.GetHighestPoint().y + _playerController.CharacterHeight / 2,
- transform.position.z);
- elapsed = 0f;
- float climbTime = Vector3.Distance(startPlayerPosition, targetUpPosition) / _climbVelocity;
- while (elapsed < climbTime)
- {
- transform.position = Vector3.Lerp(startPlayerPosition, targetUpPosition, elapsed / climbTime);
- elapsed += Time.deltaTime;
- yield return null;
- }
- //Последний этап
- //Выдвигаем персонажа вперед на два его радиуса
- //Дабы он комфортно остановился на верхушке препятствия, а не на его кромке
- Vector3 targetForwardPosition = targetUpPosition + transform.forward * _playerController.CharacterRadius * 2;
- float forwardTime = Vector3.Distance(startPlayerPosition, targetForwardPosition) / _forwardVelocity;
- elapsed = 0f;
- startPlayerPosition = transform.position;
- while (elapsed < forwardTime)
- {
- transform.position = Vector3.Lerp(startPlayerPosition, targetForwardPosition, elapsed / forwardTime);
- elapsed += Time.deltaTime;
- yield return null;
- }
- //Возвращаем управление персонажем игроку
- StopClimbing();
- }
- private void StopClimbing()
- {
- _isClimbing = false;
- _playerController.enabled = true;
- _rigidbody.isKinematic = false;
- _rigidbody.velocity = transform.forward * _velocityBeforeClimb;
- }
Add Comment
Please, Sign In to add comment