gpt4 book ai didi

c# - 使用Unity3D的IPointerDownHandler方法,但使用 “the whole screen”

转载 作者:IT王子 更新时间:2023-10-29 04:50:16 27 4
gpt4 key购买 nike

在Unity中,您需要检测场景中某物的手指触摸(手指画图)。

在现代Unity中,这样做的唯一方法是非常简单的:

步骤1 。将对撞机放在该物体上。 (“地面”或其他可能的东西。)1

步骤2. 在相机的“检查器”面板上,单击添加Physics Raycaster(相关的2D或3D)。

步骤3。只需使用下面的示例A中的代码。

(提示-别忘了确保有一个EventSystem ...有时Unity会自动添加一个,有时不会!)

太棒了,再简单不过了。 Unity最终会通过UI层正确处理取消/传播。在台式机,设备,编辑器等上可以统一且完美地工作。Hooray Unity。

都好。但是,如果您只想在屏幕上绘制,该怎么办?

因此,您很想简单地从“屏幕上”用户滑动/触摸/绘图。 (例如,仅用于操作轨道摄像头。)就像在任何普通的3D游戏中,摄像头到处乱跑并移动一样。

您不希望手指在在世界空间中某个对象上的位置,而只希望抽象的“手指运动”(即玻璃上的位置)。

您会使用什么对撞机?你能没有对撞机吗?仅仅因为这个原因,添加一个对撞机似乎是很不幸的。

我们要做的是这个:

我只是制作了一个平面对撞机,然后将其附加在相机下。因此,它仅位于相机的视锥中,并完全覆盖屏幕。

enter image description here

(对于代码,则无需使用ScreenToWorldPoint,因此只需使用示例B中的代码-非常简单,就可以完美地工作。)

我的问题是,仅仅为了触摸玻璃杯而不得不使用我所描述的“相机下的调音台”似乎有点奇怪。

怎么了

(注意-请不要回答涉及Unity古老的“Touches”系统的问题,该系统今天在实际项目中无法使用,您不能使用传统方法忽略.UI。)

代码示例A-在场景对象上绘制。使用ScreenToWorldPoint。

 using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;

public class FingerMove:MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
{
public void OnPointerDown (PointerEventData data)
{
Debug.Log("FINGER DOWN");
prevPointWorldSpace =
theCam.ScreenToWorldPoint( data.position );
}

public void OnDrag (PointerEventData data)
{
thisPointWorldSpace =
theCam.ScreenToWorldPoint( data.position );
realWorldTravel =
thisPointWorldSpace - prevPointWorldSpace;
_processRealWorldtravel();
prevPointWorldSpace = thisPointWorldSpace;
}

public void OnPointerUp (PointerEventData data)
{
Debug.Log("clear finger...");
}

代码示例B ...您只关心用户在设备的玻璃屏幕上执行的操作。在这里更容易:
 using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;

public class FingerMove:MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
{
private Vector2 prevPoint;
private Vector2 newPoint;
private Vector2 screenTravel;

public void OnPointerDown (PointerEventData data)
{
Debug.Log("FINGER DOWN");
prevPoint = data.position;
}

public void OnDrag (PointerEventData data)
{
newPoint = data.position;
screenTravel = newPoint - prevPoint;
prevPoint = newPoint;
_processSwipe();
}

public void OnPointerUp (PointerEventData data)
{
Debug.Log("FINEGR UP...");
}

private void _processSwipe()
{
// your code here
Debug.Log("screenTravel left-right.. " + screenTravel.x.ToString("f2"));
}
}

1如果您是Unity的新手,则很可能在该步骤上将其称为“Draw”;在物理设置中,使“绘图”无任何交互;在第二步中,使用Raycaster只是将图层设置为“Draw”。

最佳答案

我要发布的问题和答案似乎很大程度上基于观点。不过,我将尽力回答。

如果您尝试检测屏幕上的指针事件,则用对象表示屏幕没有任何问题。在您的情况下,您可以使用3D对撞机来覆盖相机的整个视锥面。但是,在Unity中,有一种 native 方式可以使用覆盖整个屏幕的2D UI对象。屏幕最好用2D对象表示。对我来说,这似乎是一种自然的方法。

我为此使用通用代码:

public class Screen : MonoSingleton<Screen>, IPointerClickHandler, IDragHandler, IBeginDragHandler, IEndDragHandler, IPointerDownHandler, IPointerUpHandler, IScrollHandler {
private bool holding = false;
private PointerEventData lastPointerEventData;

#region Events
public delegate void PointerEventHandler(PointerEventData data);

static public event PointerEventHandler OnPointerClick = delegate { };

static public event PointerEventHandler OnPointerDown = delegate { };
/// <summary> Dont use delta data as it will be wrong. If you are going to use delta, use OnDrag instead. </summary>
static public event PointerEventHandler OnPointerHold = delegate { };
static public event PointerEventHandler OnPointerUp = delegate { };

static public event PointerEventHandler OnBeginDrag = delegate { };
static public event PointerEventHandler OnDrag = delegate { };
static public event PointerEventHandler OnEndDrag = delegate { };
static public event PointerEventHandler OnScroll = delegate { };
#endregion

#region Interface Implementations
void IPointerClickHandler.OnPointerClick(PointerEventData e) {
lastPointerEventData = e;
OnPointerClick(e);
}

// And other interface implementations, you get the point
#endregion

void Update() {
if (holding) {
OnPointerHold(lastPointerEventData);
}
}
}
Screen是单例,因为在游戏上下文中只有一个屏幕。对象(如相机)订阅其指针事件,并相应地安排其自身。这样也可以保持单一职责。

您可以将其附加到代表所谓的玻璃(屏幕表面)的对象上。如果您认为UI上的按钮从屏幕弹出,那么玻璃就在它们的下面。为此,玻璃杯必须是 Canvas的第一个 child 。当然,必须在屏幕空间中呈现 Canvas才有意义。

这里的一种技巧没有意义,那就是在玻璃杯中添加一个不可见的 Image组件,以便它可以接收事件。这就像玻璃的射线转换目标一样。

Hierarchy
Inspector

您还可以使用 Input( Input.touches等)来实现此玻璃对象。它可以用作检查每个 Update调用中输入是否更改。在我看来,这似乎是一种基于轮询的方法,而上述方法是一种基于事件的方法。

您的问题似乎是在寻找一种使用 Input类进行辩护的方法。恕我直言,不要让自己更难。使用有效的方法。并接受Unity不完美的事实。

关于c# - 使用Unity3D的IPointerDownHandler方法,但使用 “the whole screen”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40323677/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com