EventSystem应用于3D GameObject,实现拖拽效果

EventSystem大家平时主要是用来处理UGUI的输入,但其实也可以使用在一般的3D对象上,Unity API对这个介绍的很少。

在网上找到了一篇介绍不错的文章。

https://www.cnblogs.com/weiqiangwaideshijie/p/6859867.html

以下是我的一些分享:

除了需要依赖UI相同的EventSystem之后,还需要使用Physics RayCaster组件绑定Camera上

Test脚本如下,只不过Drag事件还未处理,物体还不能拖动

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

public class TestSystemInputMono : MonoBehaviour, IPointerDownHandler, IBeginDragHandler, IDragHandler, IEndDragHandler {

	// Use this for initialization
	void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
		
	}

	public void OnPointerDown (PointerEventData eventData)
	{
		Debug.Log ("OnPointerDown");
	}


		
	public void OnBeginDrag(PointerEventData data)
	{
		Debug.Log ("OnBeginDrag");
	}

	public void OnDrag(PointerEventData data)
	{
		Debug.Log ("OnDrag");
	}

	public void OnEndDrag(PointerEventData eventData)
	{
		Debug.Log ("OnEndDrag");
	}

}

有关PointerEventData的参数,其中了些属性,很重要的

 

buttonThe InputButton for this event

对应Mouse的三个按键

 

pointerIdId of the pointer (touch id).

对应Touch,这里还没有试过多点触屏是否支持,即是否支持同时拖拽两个物体

对对3D物体,最重要应该是PointerCurrentRaycast,其API说明:

https://docs.unity3d.com/ScriptReference/EventSystems.PointerEventData-pointerCurrentRaycast.html

 

depthThe relative depth of the element.
distanceDistance to the hit.
gameObjectThe GameObject that was hit by the raycast.
indexHit index.
isValidIs there an associated module and a hit GameObject.
moduleBaseInputModule that raised the hit.
screenPositionThe screen position from which the raycast was generated.
sortingLayerThe SortingLayer of the hit object.
sortingOrderThe SortingOrder for the hit object.
worldNormalThe normal at the hit location of the raycast.
worldPositionThe world position of the where the raycast has hit.

其中worldPostion就是当前射线碰撞到的点的世界坐标。如果没有碰撞到,比如Drag时拖出物体区域,那isValid值为False

下面看如何进行Drag处理让其动起来

	Vector3 oldPos;
	public void OnDrag(PointerEventData data)
	{
		//Debug.Log ("OnDrag " + data.pointerCurrentRaycast.worldPosition + " valid " + data.pointerCurrentRaycast.isValid);
		Debug.Log ("OnDrag " + data.delta);

		//var newPos = Camera.main.ScreenToWorldPoint (new Vector3(data.position.x, data.position.y, Camera.main.nearClipPlane));
		var newPos = data.pointerCurrentRaycast.worldPosition;

		var offset = newPos - oldPos; 
		Debug.Log ("offset is " + offset);
		var projectOffset = Vector3.ProjectOnPlane(offset, data.pointerCurrentRaycast.worldNormal);
		transform.position += projectOffset;

		//var dir2 = Camera.main.worldToCameraMatrix.inverse.MultiplyPoint (data.delta) - Camera.main.transform.position;
		//

//		var projectDir = Vector3.ProjectOnPlane(dir2, data.pointerCurrentRaycast.worldNormal);
//		Debug.Log ("dir = " + dir2.ToString() + "  projectDir = " + projectDir.ToString());
		//TestAnchor.transform.position += projectDir;
		oldPos = newPos;
	}

大体思路是获取到在物体上的移动的相对偏移,再映射到拖拽的平面上,这里只是简单的取当前物体拖拽点平面。之前的思路有问题,想从Camera的屏幕相对位移出发,但不是想要的效果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值