简体   繁体   English

运动控制(2D场景)

[英]Movement controls (2D scene)

I am having an issue with my movement code I am writing for a top down RPG in 2D. 我在为二维自上而下的RPG编写运动代码时遇到问题。 Forgive my lack of knowledge but I have only recently had to learn how to code and this is my first attempt at movement controls. 原谅我缺乏知识,但是直到最近我才不得不学习如何编码,这是我第一次尝试运动控制。 The desired result is to have two input methods; 期望的结果是使用两种输入法; the controller and keyboard. 控制器和键盘。 I want to have them separate so when you are using the controller you cannot use the keyboard and vice-versa. 我想将它们分开,所以当您使用控制器时,不能使用键盘,反之亦然。 Here is the code. 这是代码。

using UnityEngine;
using System.Collections;

public class playerMovement : MonoBehaviour 
{   

    public float Speed = 1;
    private float deadZone = 0.25f;    

    // START - Use this for initialization
    void Start () {}

    // UPDATE is called once per frame - Using deadZone to compensate for faulty controllers etc.... Using options for controller true or false to switch between keyboard and controller input.
    void FixedUpdate () 
    {

        Vector2 stickInput = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));

        if ( Options.useController == true)
        {
            if( Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.A))
            {
                stickInput = Vector2.zero;
            }
            else if ( stickInput.magnitude < deadZone)
            {
                stickInput = Vector2.zero;
            }
            else
            {
                stickInput.Normalize();
                rigidbody2D.velocity = stickInput * Speed * Time.deltaTime;
            }

        }

        //Here is keyboard input - this is working great.
        else if ( Options.useController == false)
        {
            if ( Input.GetKey(KeyCode.A) && Input.GetKey (KeyCode.W))
            {
                stickInput = new Vector2(-1f,1f);
                stickInput.Normalize();
                rigidbody2D.velocity = stickInput * Speed * Time.deltaTime;  
            }
            else if ( Input.GetKey(KeyCode.W) && Input.GetKey (KeyCode.D))
            {
                stickInput = new Vector2(1f,1f);
                stickInput.Normalize();
                rigidbody2D.velocity = stickInput * Speed * Time.deltaTime; 
            }
            else if ( Input.GetKey(KeyCode.S) && Input.GetKey (KeyCode.D))
            {
                stickInput = new Vector2(1f,-1f);
                stickInput.Normalize();
                rigidbody2D.velocity = stickInput * Speed * Time.deltaTime; 
            }
            else if ( Input.GetKey(KeyCode.A) && Input.GetKey (KeyCode.S))
            {
                stickInput = new Vector2(-1f,-1f);
                stickInput.Normalize();
                rigidbody2D.velocity = stickInput * Speed * Time.deltaTime; 
            }
            else if ( Input.GetKey(KeyCode.W))
            {
                stickInput = new Vector2(0f,1f);
                stickInput.Normalize();
                rigidbody2D.velocity = stickInput * Speed * Time.deltaTime; 
            }
            else if ( Input.GetKey(KeyCode.D))
            {
                stickInput = new Vector2(1f,0f);
                stickInput.Normalize();
                rigidbody2D.velocity = stickInput * Speed * Time.deltaTime; 
            }
            else if ( Input.GetKey(KeyCode.S))
            {
                stickInput = new Vector2(0f,-1f);
                stickInput.Normalize();
                rigidbody2D.velocity = stickInput * Speed * Time.deltaTime; 
            }
            else if  ( Input.GetKey(KeyCode.A))
            {
                stickInput = new Vector2(-1f,0f);
                stickInput.Normalize();
                rigidbody2D.velocity = stickInput * Speed * Time.deltaTime; 
            }       
        }




    }
}

The issue arrives when the top loop is executing. 当顶层循环执行时,问题就到了。 I want movement from the keys to be null when useController is equal to true. useController等于true时,我希望键的移动为null。 It works great as long as the key is held down, but as soon as you release the key (A, D, S, W) it exits the if statement and the player is moved by the remaining GetAxis value. 只要按住键,它就可以很好地工作,但是一旦释放键(A,D,S,W),它将退出if语句,并且播放器将通过剩余的GetAxis值移动。

I have to use GetAxis for the controller input in this loop and unfortunately Unity automatically grabs values from the keys. 在此循环中,我必须使用GetAxis作为控制器的输入,不幸的是Unity会自动从键中获取值。 Is there a way I can not only limit the velocity to 0 but also make sure that when the key is released the GetAxis value also becomes 0. 有没有一种方法,我不仅可以将速度限制为0,还可以确保释放键时, GetAxis值也变为0。

You have to have a rigidbody2d attached to the object you want to move using rigidbody2d.velocity. 您必须使用刚性主体2d.velocity将刚性主体2d附加到要移动的对象上。 But, it's not a good idea to do that every frame. 但是,在每一帧都这样做不是一个好主意。 Instead, you could use transform.translate, or if you want to keep the physics simulation by using the rigidbodies, use rigidbody2d.addforce. 相反,您可以使用transform.translate,或者如果您想通过使用刚体来保持物理模拟,请使用僵尸2d.addforce。

Also, in Edit > Project Settings > Input make sure you remove the WSAD keys from the axes. 同样,在“编辑”>“项目设置”>“输入”中,确保从轴上删除了WSAD键。

Your code should look more something like this 您的代码应该看起来像这样

void FixedUpdate () 
{

    if (Options.useController)
    {
        // if the controller is enabled do this stuff
        Vector2 stickInput = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
    }
    else
    {
        // else if the controller is not enabled, do this stuff.
        stickinput = new Vector2(0, 0);
        if (Input.GetKey(KeyCode.W)
            stickinput += new Vector2(0, 1);
        if (Input.GetKey(KeyCode.S)
            stickinput += new Vector2(0, -1);
        if (Input.GetKey(KeyCode.A)
            stickinput += new Vector2(-1, 0);
        if (Input.GetKey(KeyCode.D)
            stickinput += new Vector2(1, 0);
        /* can have code like:
         * if (stickinput.x > 0)
         *     animator.crossfade("rightAnimation", 0f);
         * else if (stickinput.x < 0)
         *     animator.crossfade("leftanimation", 0f);
         * else
         *     animator.crossfade("standinganimation", 0f);
         */
    }

        transform.Translate(((stickinput.magnitude > 1) ? stickinput.normalized : stickinput) * speed * Time.fixedDeltaTime, Space.Self);

        // or use the one commented out below
        // rigidbody2D.AddForce(((stickinput.magnitude > 1) ? stickinput.normalized : stickinput) * speed * Time.fixedDeltaTime);


}

Notice I didn't use else if's. 注意,我没有使用else if。 If someone holds W and S, it adds to 0 for the y component. 如果有人持有W和S,则y分量加0。 I chose Space.Self for local translation, but you could use Space.World to move it in relation to the global axes. 我选择Space.Self进行本地翻译,但是您可以使用Space.World相对于全局轴进行移动。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM