Движение игрока с голосовым вводом (transform.Translate) работает не так, как задумано - PullRequest
0 голосов
/ 14 июля 2020

Я успешно создал свою первую игру в Unity, которая позволяет пользователю перемещаться по поверхности. Работало нормально. Однако теперь я также хочу иметь возможность перемещать игрока с помощью голосового ввода. Игрок прыгает, когда слышит слово jump, но, например, чтобы переместить игрока вперед, когда он слышит go, я просто использовал transform.Translate(2, 0, 0). Это перемещает игрока вперед, но его не волнует, какова поверхность, например, он движется сквозь объекты или движется прямо, даже если впереди есть уклон. Движение с помощью клавиатуры не имеет этой проблемы.

Это мой код:

public class PlayerMovement : MonoBehaviour {

        
        public CharacterController2D controller;
        public Animator animator;

        public float runSpeed = 40f;

        float horizontalMove = 0f;

        bool jump = false;

        bool crouch = false;

        private KeywordRecognizer keywordRecognizer;

        private Dictionary<string, Action> actions = new Dictionary<string, Action>();


        void Start()
        {
            actions.Add("Go", Go);
            actions.Add("up", Up);
            actions.Add("back", Back);

            keywordRecognizer = new KeywordRecognizer(actions.Keys.ToArray());
            keywordRecognizer.OnPhraseRecognized += RecognizedSpeech;
            keywordRecognizer.Start();

        }


        private void RecognizedSpeech(PhraseRecognizedEventArgs speech)
        {
            Debug.Log(speech.text);
            actions[speech.text].Invoke();

        }



    // Update is called once per frame

    void Update () {

            horizontalMove =  Input.GetAxisRaw("Horizontal") * runSpeed;

            animator.SetFloat("Speed", Mathf.Abs(horizontalMove));

            if (Input.GetButtonDown("Jump")) {
                jump = true;
                animator.SetBool("IsJumping",true);
            }


            if (Input.GetButtonDown("Crouch")){
                crouch = true;
            } else if (Input.GetButtonUp("Crouch")){
            crouch = false;
            }

                }
          



        public void OnLanding (){
            animator.SetBool("IsJumping", false);
        }


        void FixedUpdate()
        {
            // Move our character
            controller.Move(horizontalMove * Time.deltaTime, crouch, jump);
            jump = false;

    }


    void Go()
    {
        transform.Translate(2, 0, 0);
    }

    void Back()
    {
        transform.Translate(-2, 0, 0);
    }

    void Up()
    {
        jump = true;
        animator.SetBool("IsJumping", true);
    }

}

Что мне нужно изменить, чтобы игрок действительно двигался, как задумано, с помощью голосового ввода.

Большое спасибо и извините, если это основной c вопрос!

Ответы [ 2 ]

1 голос
/ 14 июля 2020

Разница в том, что, например, в Go transform.Translate(2, 0, 0); "телетранспортирует" объект примерно на 2 фиксирует единицы вправо, в то время как controller.Move(horizontalMove * Time.deltaTime, crouch, jump); перемещает объект плавно во времени с помощью horizontalMove единиц / второй.

Также обратите внимание, что вы не должны смешивать движения через Transform с Rigidbody (/ Rigidbody2D) .. это нарушает физику.

Вы можете просто использовать

public void Go
{
    controller.Move(runSpeed * 2, crouch, jump);
}

public void Back
{
    controller.Move(runSpeed * -2, crouch, jump);
}

Я бы, однако, использовал Coroutine , который имитирует нажатие кнопки в течение определенного времени после голосовой команды и оставит движение в FixUpdate на месте, например,

// How long shall the character move into the direction after voice command?
[SerializeField] private float voicePressDuration = 1f;

private bool isVoiceCommand;
private Coroutine voiceRoutine;

void Update () 
{
    if(!isVoiceCommand) horizontalMove =  Input.GetAxisRaw("Horizontal") * runSpeed;

    animator.SetFloat("Speed", Mathf.Abs(horizontalMove));

    if (Input.GetButtonDown("Jump")) 
    {
        jump = true;
        animator.SetBool("IsJumping",true);
    }

    if (Input.GetButtonDown("Crouch"))
    {
        crouch = true;
    } 
    else if (Input.GetButtonUp("Crouch"))
    {
        crouch = false;
    }
}

void Go()
{
    if(voiceRoutine != null)
    {
        // evtl interrupt an already running routine
        StopCoroutine(voiceRoutine);
    } 

    voiceRoutine = StartCoroutine(ProcessVoiceMove(runSpeed));
}

void Back()
{
    if(voiceRoutine != null)
    {
        // evtl interrupt an already running routine
        StopCoroutine(voiceRoutine);
    } 

    voiceRoutine = StartCoroutine(ProcessVoiceMove(-runSpeed));
}

private IEnuermator ProcessVoiceMove(float value)
{
    isVoiceCommand = true;
    horizontalMove = value;

    yield return new WaitForSeconds(voicePressDuration);

    isVoiceCommand = false;
}

Таким образом, после того, как вы скажете, например, Go, объект будет двигаться вперед в течение одной секунды или того, что вы настроили в voicePressDuration.

1 голос
/ 14 июля 2020

Перемещайте игрока через CharacterController2D, а не Translate, потому что это не позволяет физике обнаруживать столкновения.

Примерно так:

void Go()
{
   controller.Move(2, crouch, jump);
}

void Back()
{
   controller.Move(-2, crouch, jump);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...