简体   繁体   English

如何将键盘转换为触控器

[英]How to Convert Keyboard to Touch controller

Good day i'm new to unity c#. 美好的一天,我是团结的新手#。 Does anyone know how to convert my 2d top down car controller script from keyboard to touch buttons. 有谁知道如何将我的2d自上而下汽车控制器脚本从键盘转换为触摸按钮。 I need to have a touch buttons that has break,back,accelerate and left right buttons for my 2d topdown car. 我需要一个触摸按钮,它有我的2d自上而下车的休息,后退,加速和左右按钮。

What my codes is based on an Arcade style car game. 我的代码是基于街机风格的汽车游戏。

    float speedForce = 15f;
    float torqueForce = -200f;
    float driftFactorSticky = 0.9f;
    float driftFactorSlippy = 1;
    float maxStickyVelocity = 2.5f;
    float minSlippyVelocity = 1.5f; // <--- Exercise for the viewer

    // Use this for initialization
    void Start () 
    {

    }

    void Update() 
    {
        // check for button up/down here, then set a bool that you will use in FixedUpdate
    }

    // Update is called once per frame
    void FixedUpdate () 
    {
        Rigidbody2D rb = GetComponent<Rigidbody2D>();

        Debug.Log(RightVelocity().magnitude);

        float driftFactor = driftFactorSticky;
        if(RightVelocity().magnitude > maxStickyVelocity) {
            driftFactor = driftFactorSlippy;
        }

        rb.velocity = ForwardVelocity() + RightVelocity()*driftFactor;

        if(Input.GetButton("Accelerate")) {
            rb.AddForce( transform.up * speedForce );

            // Consider using rb.AddForceAtPosition to apply force twice, at the position
            // of the rear tires/tyres
        }
        if(Input.GetButton("Brakes")) {
            rb.AddForce( transform.up * -speedForce/2f );

            // Consider using rb.AddForceAtPosition to apply force twice, at the position
            // of the rear tires/tyres
        }

        // If you are using positional wheels in your physics, then you probably
        // instead of adding angular momentum or torque, you'll instead want
        // to add left/right Force at the position of the two front tire/types
        // proportional to your current forward speed (you are converting some
        // forward speed into sideway force)
        float tf = Mathf.Lerp(0, torqueForce, rb.velocity.magnitude / 2);
        rb.angularVelocity = Input.GetAxis("Horizontal") * tf;
    }

    Vector2 ForwardVelocity() 
    {
        return transform.up * Vector2.Dot( GetComponent<Rigidbody2D>().velocity, transform.up );
    }

    Vector2 RightVelocity() 
    {
        return transform.right * Vector2.Dot( GetComponent<Rigidbody2D>().velocity, transform.right );
    }
}

instead of 代替

if(Input.GetButton("Accelerate")) 
{
    rb.AddForce( transform.up * speedForce );
}
if(Input.GetButton("Brakes")) 
{
    rb.AddForce( transform.up * -speedForce/2f );
}

and

rb.angularVelocity = Input.GetAxis("Horizontal") * tf;

simply check for some bools instead and have according setter methods for them (You need those to be able to call them by UnityEvents): 只需检查一些bool,并为它们设置相应的setter方法(你需要能够通过UnityEvents调用它们):

private bool acceleratePressed;
private bool brakePressed;
private bool leftPressed;
private bool rightPressed;

public void SetAccelerate(bool pressed)
{
    acceleratePressed = pressed;
}

public void SetBrake(bool pressed)
{
    brakePressed = pressed;
}

public void SetRightPressed(bool pressed)
{
    rightPressed = pressed;
}

public void SetLeftPressed(bool pressed)
{
    leftPressed = pressed;
}

private void FixedUpdate()
{
    if(acceleratePressed) 
    {
        rb.AddForce( transform.up * speedForce );
    }
    if(brakePressed)
    {
        rb.AddForce( transform.up * -speedForce/2f );
    }

    var leftRight = 0;
    if(leftPressed && !rightPressed)
    {
        leftRight = -1;
    }
    else if(!leftPressed && rightPressed)
    {
        leftRight = 1;
    }

    // If you are using positional wheels in your physics, then you probably
    // instead of adding angular momentum or torque, you'll instead want
    // to add left/right Force at the position of the two front tire/types
    // proportional to your current forward speed (you are converting some
    // forward speed into sideway force)
    float tf = Mathf.Lerp(0, torqueForce, rb.velocity.magnitude / 2);
    rb.angularVelocity = leftRight * tf;
}

Unfortunately the Unity UI.Button doesn't have a way for forwarding button down or up .. only the onClick . 不幸的是Unity UI.Button没有办法转发按钮向下或向上..只有onClick

But you can very easily implement additional events on your own! 您可以自己轻松实现其他活动! You can use the IPointerDownHandler and IPointerUpHandler & IPointerExitHandler interfaces and custom UnityEvents 您可以使用IPointerDownHandlerIPointerUpHandlerIPointerExitHandler接口以及自定义UnityEvents

I don't like do inherit from UI.Button (some poeple might prefer that) but instead rather add additional behaviour in a seperate component. 我不喜欢继承UI.Button(有些人可能更喜欢),而是在单独的组件中添加其他行为。

There are other ways how to implement it exactly but I like to keep things reusable so I would use it like 还有其他方法如何完全实现它,但我喜欢保持可重用的东西,所以我会像它一样使用它

[RequireComponent((typeof(Button)))]
public class DownUpButtonEnhancement : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerExitHandler
{
    private Button _button;

    public UnityEvent OnButtonDown;
    public UnityEvent OnButtonUp;

    private void Awake()
    {
        _button = GetComponent<Button>();
    }

    //Detect current clicks on the GameObject (the one with the script attached)
    public void OnPointerDown(PointerEventData pointerEventData)
    {
        if (!_button.interactable) return;

        OnButtonDown?.Invoke();
    }

    //Detect if clicks are no longer registering
    public void OnPointerUp(PointerEventData pointerEventData)
    {
        OnButtonUp?.Invoke();
    }

    // Detect if pointer leaves the object
    public void OnPointerExit(PointerEventData eventData)
    {
        // additionally reset if pointer leaves button while pressed
        OnButtonUp?.Invoke();
    }
}

Put this on your two UI Buttons and configure the according OnButtonDown and OnButtonUp callback just the same way you would with onClick of the Button : 把它放在你的两个UI Buttons并配置相应的OnButtonDownOnButtonUp回调,就像使用Button onClick

  1. Drag in the GameObject with your movement script in 使用您的移动脚本在GameObject中拖动
  2. Select the according method that should be called every frame the button is pressed. 选择按下按钮的每一帧应调用的相应方法。
  3. For OnButtonDown pass in true (check the box) for OnButtonUp pass in false. 对于OnButtonDown传入true (勾选方框) OnButtonUp传递为false。

在此输入图像描述

Then in the game you can see that now the according bool of the MoveController script is enabled while the button is pressed and additionally reset if the pinter leaves the button while pressed 然后在游戏中你可以看到现在按下按钮时启用了MoveController脚本的相应bool,如果pinter在按下时离开按钮,则另外重置

在此输入图像描述

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

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