输入.GetMouseButtonUp在Unity中没有按预期工作

本文关键字:工作 GetMouseButtonUp Unity 输入 | 更新日期: 2023-09-27 18:14:58

我有一个2D Unity游戏,其中有许多代理,当点击它们时可以选择。当这种情况发生时,他们就变成了玩家(玩家的代理变量被他们所取代,代理就变成了玩家的父母)。我正试图实现一个系统,你拖动他们的目的地在另一个代理"目标"他们。

为了做到这一点,我实际上是从目标的My类(一个包含所有玩家组件和变量的引用的类)中瞄准,所以我将代理放入由玩家当前代理操作的函数中。这似乎在理论上是可行的,但在Unity中,它只允许我瞄准层级中的第一个代理,而不是其他代理。但是所有的代理都是在游戏开始时生成的代理预制的相同实例。

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Agent : Grammar {
    public Physical physical;
    public Agent agent;
    void Update() {
        float distanceFromMouse = the.Distance(this.transform.position, Camera.main.ScreenToWorldPoint(Input.mousePosition));
        if (Input.GetMouseButtonDown(0)) {
            if (distanceFromMouse < 1f) {
                the.player.agent = this;
                the.player.transform.parent = this.transform;
            }
        }
        if (Input.GetMouseButtonUp (0)) {
            if (distanceFromMouse < 1f) {
                if (the.player.agent != this && the.player.agent is Agent) {
                    the.player.agent.Target (agent);
                }
            }
            the.player.agent = null;
        }
        if (the.player.agent == agent)
            physical.goal = Camera.main.ScreenToWorldPoint (Input.mousePosition);
        else if (physical.hasTarget)
            physical.goal = physical.target.transform.position;
    }
}
public void Target (My target) {
    my.physical.target = target;
    my.physical.hasTarget = true;
    foreach (My other in the.agents.GetComponentsInChildren<My>()) {
        if (other.physical.targetters.Contains (my))
            other.physical.targetters.Remove (my);
    }
    target.physical.targetters.Add (my);
    target.physical.targetted = true;
}

这是我的语法类,所有东西都继承自它,所以它们可以访问全局的类。

using UnityEngine;
using System.Collections;
public class Grammar : MonoBehaviour {
    public A a;
    public The the;
} 

这是我的(全局实用程序)类

using UnityEngine;
using System.Collections;
public class The : MonoBehaviour {
    public Grid grid;
    public GameObject world;
    public Player player;
    public GameObject squareParent;
    public GameObject linkParent;
    public GameObject nodeParent;
    public GameObject agents;
    public Vector2 HeadingFrom(float angle) { return new Vector2(Mathf.Cos(angle * Mathf.Deg2Rad), Mathf.Sin(angle * Mathf.Deg2Rad)); }
    public float AngleFrom(Vector2 heading) { return Mathf.Atan2 (heading.y, heading.x) * Mathf.Rad2Deg; }
    public Vector2 RelativeHeadingFrom(Vector2 heading, float rotation) { return (Vector2)(HeadingFrom(AngleFrom(heading) - rotation)); }
    public float Distance(Vector2 from, Vector2 to) { return (Heading(from,to)).magnitude; }
    public Vector2 Heading (Vector2 from, Vector2 to) { return to - from; }
    public Vector2 MidPoint (GameObject my, GameObject their) { return (my.transform.position + their.transform.position) / 2; }
}

输入.GetMouseButtonUp在Unity中没有按预期工作

您在代理类中检测点击的方式有点不对劲。当属性Input.mousePosition返回一个Vector3时,Z分量总是零。Camera.ScreenToWorldPoint函数的文档指出,提供的矢量的Z分量是以世界为单位的距离,这意味着您在Agent类中的"点击"的世界位置将始终紧挨着相机。

通常的方法是定义方法OnMouseDown()和OnMouseUp()(在你的代理类)或使用Camera.ScreenPointToRay创建一个射线,然后用于做光线投射到场景中,然后使用光线命中结果作为鼠标指针的"实际世界"位置。请参阅Unity Answers上的答案了解更多信息。

我建议你使用新的事件系统(这是新的Unity GUI系统的一部分)来检测代理是否被点击,因为如果你想让你的游戏在移动设备上运行,这也可以处理触摸输入。

你需要做的是:

  • 在你的代理类中实现接口IPointerUpHandler和IPointerDownHandler,并在接口要求你定义的方法中处理点击。
  • 确保你的代理上有某种碰撞器(或触发器)。
  • 确保你在Camera对象上添加了一个PhysicsRaycaster组件。

您可能也对这些接口感兴趣:

  • IBeginDragHandler
  • IDragHandler
  • IEndDragHandler
  • IDropHandler