【问题标题】:Moving Game Object with UI Buttons使用 UI 按钮移动游戏对象
【发布时间】:2019-11-04 06:41:42
【问题描述】:

我正在尝试通过 UI 按钮设置对 Player 游戏对象的控制。 2d 自上而下的视图场景。

当我释放左/右/上/下 ui 按钮时,我想在固定距离上平滑传输 Player 对象(Axix X 为 0.8 左右方向,2.4 上下方向)。

在这里我找到了平滑移动的代码,但是玩家在按下 ui 按钮时一直在移动。

你能帮我让它在鼠标向上移动(指针向上)并移动 public x= 0.8f 用于左/右,public y = 2.4f 用于上/下

同时我想使用不同的速度(peblic)在 x 和 y 轴上移动

如果它应该是使用 smth 的完全其他脚本,就像 transform.translate 请指导任何可能的解决方案。谢谢

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;

public class PlayerControl : MonoBehaviour
{

    float movX;
    float movY;
    Rigidbody2D rb;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        movX = CrossPlatformInputManager.GetAxisRaw("Horizontal");
        movY = CrossPlatformInputManager.GetAxisRaw("Vertical");

          rb.velocity = new Vector2(movX * 1, movY * 1);

    }
}

【问题讨论】:

  • 我觉得你可以从这里得到答案:stackoverflow.com/questions/50471129/…
  • 您可能没有施加足够的力量。将那些* 1 更改为* 100 并根据口味进行调整。如果您不在其他地方使用它们,您也不需要创建 movX/movY 实例变量。
  • 问题是对象正在移动,但是当按钮(带有碰撞器的图像精灵)向上时,我需要它以恒定值移动。实际上我不需要这里的 phisycs,这就是为什么要尝试通过 transform.translate。但是因为不熟练而无法处理

标签: c# unity3d


【解决方案1】:

这个脚本可以通过 WASD 键移动。 这应该在 x 时间(速度)内将您的游戏对象移动请求的数量。 目前它只能在到达目的地时移动,但您可以通过停止协程轻松修改它:)

using System.Collections;
using UnityEngine;

public class PlayerControl : MonoBehaviour
{
    // We gonna move by WASD keys

    [Header("Speed & Movement settings")]
    [SerializeField]
    float Speed = 2.0f;
    [SerializeField]
    float movSpeedX = 0.8f;
    [SerializeField]
    float movSpeedY = 2.4f;

    bool ReachedTarget = true;

    void Update()
    {
        if (ReachedTarget)
        {
            Vector2 dest = Vector2.zero;
            Vector2 currentPos = transform.position;
            if (Input.GetKeyUp(KeyCode.W))
            {
                dest = currentPos + (Vector2.up * movSpeedY);
                StartCoroutine(moveTo(dest, Speed));
            }
            else if (Input.GetKeyUp(KeyCode.S))
            {
                dest = currentPos + (Vector2.down * movSpeedY);
                StartCoroutine(moveTo(dest, Speed));
            }
            else if (Input.GetKeyUp(KeyCode.D))
            {
                dest = currentPos + (Vector2.right * movSpeedX);
                StartCoroutine(moveTo(dest, Speed));
            }
            else if (Input.GetKeyUp(KeyCode.A))
            {
                dest = currentPos + (Vector2.left * movSpeedX);
                StartCoroutine(moveTo(dest, Speed));
            }
        }
    }

    // Time to take is in seconds
    IEnumerator moveTo(Vector2 TargetPosition, float TimetoTake)
    {
        Vector2 originalPosition = transform.position;
        float Time_taken = 0f;
        ReachedTarget = false;
        while (Time_taken < 1)
        {
            Time_taken += Time.deltaTime / TimetoTake;
            // Interpolating between the original and target position this basically provides your "speed"
            transform.position = Vector2.Lerp(originalPosition, TargetPosition, Time_taken);
            yield return null;
        }
        Time_taken = 0;
        transform.position = TargetPosition;
        ReachedTarget = true;
    }
}

【讨论】:

【解决方案2】:

我找不到CrossPlatformInputManager 的任何文档,我对此一无所知。但是如果你需要获取“释放键”而不是“按下键”的事件,试试这个:Input.GetKeyUp。

说明

在用户释放由标识的键的帧期间返回 true 名字。

您需要从 Update 函数中调用此函数,因为 状态每帧都会重置。它不会返回真,直到用户 已按下该键并再次松开。

有关键标识符的列表,请参阅常规游戏输入。什么时候 处理输入建议使用 Input.GetAxis 和 Input.GetButton 代替,因为它允许最终用户配置 键。

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour
{
    void Update()
    {
        if (Input.GetKeyUp("space"))
        {
            print("Space key was released");
        }
    }
}

如果你想停止刚体,你需要将它的速度重置为 零。或者你可以使用 Rigidbody2D.MovePosition 将其移动一定距离。

参数

位置 刚体对象的新位置。

说明

将刚体移动到位置。

通过计算将刚体移动到指定位置 将刚体移动到该位置所需的适当线速度 在下一次物理更新期间的位置。搬家过程中,既不 重力或线性阻力会影响身体。这会导致对象 迅速从现有位置,通过世界,到 指定位置。

因为此功能允许刚体快速移动到 通过世界的指定位置,连接到的任何对撞机 刚体将按预期做出反应,即它们将产生碰撞 和/或触发器。这也意味着,如果对撞机产生 碰撞,那么它将影响刚体运动,并可能 在下一个物理过程中阻止它到达指定位置 更新。如果刚体是运动学的,那么任何碰撞都不会影响 刚体本身,只会影响任何其他动态对撞机。

2D 刚体对它们的移动速度有一个固定的限制,因此 试图在短时间内移动大距离可能会导致 在下一个刚体没有到达指定位置 物理更新。建议你相对使用这个 仅限小距离移动。

重要的是要了解实际的位置变化会 仅在下一次物理更新期间发生,因此称之为 方法重复而不等待下一次物理更新将 导致最后一个调用被使用。为此,建议 在 FixedUpdate 回调期间调用它。

注意:MovePosition 旨在用于运动学刚体。

// Move sprite bottom left to upper right.  It does not stop moving.
// The Rigidbody2D gives the position for the cube.

using UnityEngine;
using System.Collections;

public class Example : MonoBehaviour
{
    public Texture2D tex;

    private Vector2 velocity;
    private Rigidbody2D rb2D;
    private Sprite mySprite;
    private SpriteRenderer sr;

    void Awake()
    {
        sr = gameObject.AddComponent<SpriteRenderer>();
        rb2D = gameObject.AddComponent<Rigidbody2D>();
    }

    void Start()
    {
        mySprite = Sprite.Create(tex, new Rect(0.0f, 0.0f, tex.width, tex.height), new Vector2(0.5f, 0.5f), 100.0f);
        velocity = new Vector2(1.75f, 1.1f);
        sr.color = new Color(0.9f, 0.9f, 0.0f, 1.0f);

        transform.position = new Vector3(-2.0f, -2.0f, 0.0f);
        sr.sprite = mySprite;
    }

    void FixedUpdate()
    {
        rb2D.MovePosition(rb2D.position + velocity * Time.fixedDeltaTime);
    }
}

两个文件都有一个例子。 或者你不想使用键盘而是 UI 按钮,试试这个:IPointerDownHandler and IPointerUpHandler

说明 如果您希望接收 OnPointerDown 回调,则要实现的接口。

检测正在进行的鼠标点击,直到松开鼠标按钮。采用 IPointerUpHandler 来处理鼠标按键的释放。

//Attach this script to the GameObject you would like to have mouse clicks detected on
//This script outputs a message to the Console when a click is currently detected or when it is released on the GameObject with this script attached

using UnityEngine;
using UnityEngine.EventSystems;

public class Example : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
    //Detect current clicks on the GameObject (the one with the script attached)
    public void OnPointerDown(PointerEventData pointerEventData)
    {
        //Output the name of the GameObject that is being clicked
        Debug.Log(name + "Game Object Click in Progress");
    }

    //Detect if clicks are no longer registering
    public void OnPointerUp(PointerEventData pointerEventData)
    {
        Debug.Log(name + "No longer being clicked");
    }
}

【讨论】:

  • 欢迎来到 SO!这是一个非常好的答案,但它几乎基于实时链接。一旦它们消失,答案将毫无用处。请编辑您的评论并添加一些可以在链接上找到的信息。
  • @DavidGarcíaBodego 所有的链接都指向官方的 Unity 文档,所以没关系
  • 请注意,对于 IPointerXYHandler,您还需要:Ensure an Event System exists in the Scene(通常在添加 UI.Canvas 时自动添加)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-22
相关资源
最近更新 更多