AmbushedRaccoon

Паркур и Unity - часть 1: Climbing

May 31st, 2020
210
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.93 KB | None | 0 0
  1. private void StartClimbing(ParkourObstacle obstacle, ParkourObstacle.Wall wall, Vector3 startPoint)
  2. {
  3.     //Взводим флаг
  4.     _isClimbing = true;
  5.     //Создаём плоскость стены дабы с помощью нормали её определить точку начала паркура
  6.     Plane wallPlane = new Plane(wall.GetPoint(0), wall.GetPoint(1), wall.GetPoint(2));
  7.     //Вычисляем две точки начала паркура, по обе сторон от стены
  8.     Vector3 startPosition1 = startPoint + (wallPlane.normal * _playerController.CharacterRadius * -1);
  9.     Vector3 startPosition2 = startPoint + (wallPlane.normal * _playerController.CharacterRadius);
  10.     //та точка которая будет ближайшей к игроку, нас и интересует.
  11.     //Очень важно правильно выбрать точку. Ибо игрок может оказаться внутри препятствия
  12.     //или на противоположной стороне от него
  13.     Vector3 climbStartPosition = Vector3.Distance(transform.position, startPosition1) < Vector3.Distance(transform.position, startPosition2) ? startPosition1 : startPosition2;
  14.     //Вращение "Лицом к стене"
  15.     Quaternion climbStartRtotation = Quaternion.LookRotation(startPoint - climbStartPosition, Vector3.up);
  16.  
  17.     //Запоминаем горизонтальную скорость которая была до начала залезания
  18.     _velocityBeforeClimb = new Vector2(_rigidbody.velocity.x, _rigidbody.velocity.z).magnitude;
  19.     //Сбрасываем скорость
  20.     _rigidbody.velocity = Vector3.zero;
  21.     //Отключаем управление персонажем
  22.     _playerController.enabled = false;
  23.     //Выключаем физику, дабы гравитация нам не мешала
  24.     _rigidbody.isKinematic = true;
  25.  
  26.     //Запускаем корутину
  27.     _parkourCoroutine = StartCoroutine(Climbing(obstacle, wall, climbStartPosition, climbStartRtotation));
  28. }
  29.  
  30.  
  31. private IEnumerator Climbing(ParkourObstacle obstacle, ParkourObstacle.Wall wall, Vector3 startPoint, Quaternion startRotation)
  32. {
  33.     //Первый этап из позиции персонажа к позиции начала паркура
  34.     Vector3 startPlayerPosition = transform.position;
  35.     Quaternion startPlayerRotation = transform.rotation;
  36.     float elapsed = 0f;
  37.     //Вычисляем время на перемещение из скорости перемещения
  38.     float translationTime = Vector3.Distance(startPlayerPosition, startPoint) / _translationVelocity;
  39.     while (elapsed < translationTime)
  40.     {
  41.         //Плавно перемещаем персонажа
  42.         transform.position = Vector3.Lerp(startPlayerPosition, startPoint, elapsed / translationTime);
  43.         transform.rotation = Quaternion.Lerp(startPlayerRotation, startRotation, elapsed / translationTime);
  44.         elapsed += Time.deltaTime;
  45.         yield return null;
  46.     }
  47.  
  48.     //Второй этап - подъём вверх
  49.     //Вычисляем точку назначения из позиции персонажа
  50.     //Добавив к ней высоту подъёма и половину "роста" персонажа
  51.     startPlayerPosition = transform.position;
  52.     Vector3 targetUpPosition = new Vector3(transform.position.x,
  53.         wall.GetHighestPoint().y + _playerController.CharacterHeight / 2,
  54.         transform.position.z);
  55.     elapsed = 0f;
  56.     float climbTime = Vector3.Distance(startPlayerPosition, targetUpPosition) / _climbVelocity;
  57.     while (elapsed < climbTime)
  58.     {
  59.         transform.position = Vector3.Lerp(startPlayerPosition, targetUpPosition, elapsed / climbTime);
  60.         elapsed += Time.deltaTime;
  61.         yield return null;
  62.     }
  63.    
  64.     //Последний этап
  65.     //Выдвигаем персонажа вперед на два его радиуса
  66.     //Дабы он комфортно остановился на верхушке препятствия, а не на его кромке
  67.     Vector3 targetForwardPosition = targetUpPosition + transform.forward * _playerController.CharacterRadius * 2;  
  68.     float forwardTime = Vector3.Distance(startPlayerPosition, targetForwardPosition) / _forwardVelocity;
  69.     elapsed = 0f;
  70.     startPlayerPosition = transform.position;
  71.     while (elapsed < forwardTime)
  72.     {
  73.         transform.position = Vector3.Lerp(startPlayerPosition, targetForwardPosition, elapsed / forwardTime);
  74.         elapsed += Time.deltaTime;
  75.         yield return null;
  76.     }
  77.    
  78.     //Возвращаем управление персонажем игроку
  79.     StopClimbing();
  80. }
  81.  
  82. private void StopClimbing()
  83. {
  84.     _isClimbing = false;
  85.     _playerController.enabled = true;
  86.     _rigidbody.isKinematic = false;
  87.     _rigidbody.velocity = transform.forward * _velocityBeforeClimb;
  88. }
Add Comment
Please, Sign In to add comment