Как сделать плавную останову персонажа на Unity2D
только недавно начал работать с unity. Начал создание 2D платформера с написания и разборов скриптов других людей для перемещения персонажа.
Проблема в том, что персонаж не останавливает после двежения за walkCooldown, а делает это хаотично. Насколько понимаю проблема в методе update. Подскажите в чём проблема, зарание спасибо за помошь!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
[Header("Speeds")]
public float WalkSpeed = 60;
public float JumpForce = 200;
public BoxCollider2D boxColliderNormal;
public BoxCollider2D boxColliderCrutch;
private MoveState _moveState = MoveState.Idle;
private DirectionState _directionState = DirectionState.Right;
private Transform _transform;
private Rigidbody2D _rigidbody;
private Animator _animatorController;
private float _walkTime = 0, _walkCooldown = 0.2f;
private void BoxOnNormal()
{
boxColliderNormal.enabled = true;
boxColliderCrutch.enabled = false;
}
private void BoxOffNormal()
{
boxColliderNormal.enabled = false;
boxColliderCrutch.enabled = true;
}
public void MoveRight()
{
if (_moveState != MoveState.Jump &(Input.GetKey(KeyCode.S)==false) )
{
BoxOnNormal();
_moveState = MoveState.Walk;
if (_directionState == DirectionState.Left)
{
_transform.localScale = new Vector3(-_transform.localScale.x, _transform.localScale.y, _transform.localScale.z);
_directionState = DirectionState.Right;
}
_walkTime = _walkCooldown;
_animatorController.Play("Walk");
}
}
public void MoveLeft()
{
if (_moveState != MoveState.Jump & (Input.GetKey(KeyCode.S) == false))
{
BoxOnNormal();
_moveState = MoveState.Walk;
if (_directionState == DirectionState.Right)
{
_transform.localScale = new Vector3(-_transform.localScale.x, _transform.localScale.y, _transform.localScale.z);
_directionState = DirectionState.Left;
}
_walkTime = _walkCooldown;
_animatorController.Play("Walk");
}
}
public void Crutch()
{
if (_moveState != MoveState.Jump)
{
BoxOffNormal();
_moveState = MoveState.Crutch;
_animatorController.Play("Crutch");
_walkTime = 0.07f;
}
}
public void Jump()
{
if (_moveState != MoveState.Jump)
{
BoxOnNormal();
_rigidbody.velocity += (Vector2.up * JumpForce * Time.deltaTime);
_moveState = MoveState.Jump;
_animatorController.Play("Jump");
}
}
private void Idle()
{
_moveState = MoveState.Idle;
_animatorController.Play("Idle");
}
private void Start()
{
_transform = GetComponent<Transform>();
_rigidbody = GetComponent<Rigidbody2D>();
_animatorController = GetComponent<Animator>();
_directionState = transform.localScale.x > 0 ? DirectionState.Right : DirectionState.Left;
}
private void Update()
{
if (_moveState == MoveState.Jump)
{
if (_rigidbody.velocity == Vector2.zero)
{
Idle();
}
}
else if (_moveState == MoveState.Walk)
{
_rigidbody.velocity = (_directionState == DirectionState.Right ? Vector2.right : -Vector2.right)
* WalkSpeed * Time.deltaTime;
_walkTime -= Time.deltaTime;
if (_walkTime <= 0)
{
Idle();
}
}
else if (_moveState == MoveState.Crutch)
{
_walkTime -= Time.deltaTime;
if (_walkTime <= 0)
{
Idle();
}
}
}
enum DirectionState
{
Right,
Left
}
enum MoveState
{
Idle,
Walk,
Jump,
Crutch
}
}
Ответы (1 шт):
Автор решения: Yaroslav
→ Ссылка
Пример
enum kMove { None, Right, Left, }
private kMove _moveStatus;
private float _moveSpeed = 10f;
private float _decreaseFactor = 2f; // множитель погашения скорости
private float _increaseFactor = 3f; // множитель набора скорости
private Rigidbody2D _body;
void Update () {
UpdateMove();
}
void UpdateMove () {
switch (_moveStatus) {
case: kMove.None { UpdateMoveNone (); } break;
case: kMove.Right { UpdateMoveRight (); } break;
case: kMove.Left { UpdateMoveLeft (); } break;
}
}
void UpdateMoveNone () {
if (_body.velocity.x != 0) {
float Decrease = _moveSpeed*Time.deltaTime*_decreaseFactor*-Mathf.Sign(_body.velocity.x);
if (Mathf.Abs(Decrease) < Mathf.Abs(_body.velocity.x))
_body.velocity += new Vector2(Decrease , 0); // Погашение скорости
else
_body.velocity = new Vector2(0, _body.velocity.y); // Скорость погашена
}
}
void UpdateMoveRight () {
if (_body.velocity.x < _moveSpeed) {
_body.velocity += new Vector2(_moveSpeed, 0)*Time.deltaTime*_increaseFactor; // набор скорости
if (_body.velocity.x > _moveSpeed) // проверка на перебор скорости
_body.velocity = new Vector2(_moveSpeed), _body.velocity.y); // ограничение скорости
}
}
void UpdateMoveLeft () {
if (_body.velocity.x > -_moveSpeed) {
_body.velocity += new Vector2(-_moveSpeed, 0)*Time.deltaTime*_increaseFactor; // набор скорости
if (_body.velocity.x < -_moveSpeed) // проверка на перебор скорости
_body.velocity = new Vector2(-_moveSpeed, _body.velocity.y); // ограничение скорости
}
}