首页 > 解决方案 > 带有语音输入(transform.Translate)的玩家移动没有按预期工作

问题描述

我已经成功地在 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#unity3d

解决方案


不同之处在于,例如在Gotransform.Translate(2, 0, 0);远程传输”中,对象向右固定大约2个单位,而controller.Move(horizontalMove * Time.deltaTime, crouch, jump);随着时间的推移以horizontalMove单位/秒平滑移动对象。

另请注意,您不应该通过Transformwith Rigidbody(/ Rigidbody2D) .. 混合运动。这会破坏物理学。

你可以简单地使用

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

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

但是,我会使用一个协程,它在语音命令后模拟按钮按下一段时间,并将运动留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.


推荐阅读