概述
第一种
使用条件:
1.场景中要有EventSystem
2.脚本引用命名空间using UnityEngine.EventSystems;
3.脚本继承自MonoBehaviour
4.脚本要实现接口IBeginDragHandler,IDragHandler,IEndDragHandler(第三个接口不是必须的)
5.仅对UGUI有效,ui的image组件的RaycastTarget必须勾选上
using UnityEngine;
using UnityEngine.EventSystems;
public class Test : MonoBehaviour,IBeginDragHandler, IDragHandler,IEndDragHandler
{
private Vector3 offset;
public void OnBeginDrag(PointerEventData eventData)
{
//开始拖拽的时候记录偏移量
Vector3 v3;
RectTransformUtility.ScreenPointToWorldPointInRectangle(GetComponent<RectTransform>(),
eventData.position, eventData.enterEventCamera, out v3);
offset = transform.position-v3;
}
public void OnDrag(PointerEventData eventData)
{
transform.position = Input.mousePosition+offset;
}
public void OnEndDrag(PointerEventData eventData)
{
throw new System.NotImplementedException();
}
}
第二种
使用条件:
1.可用于3d物体和worldspace模式的画布
2.被拖拽的物体必须挂上碰撞器,ui的碰撞器要尽量包裹住UI同时,碰撞器的size.z不要太“厚”
using UnityEngine;
public class Test1 : MonoBehaviour
{
//偏移量
private Vector3 offset = Vector3.zero;
private float z;
private void OnMouseDown()
{
z = Vector3.Dot(transform.position - Camera.main.transform.position, Camera.main.transform.forward);
//也可以是z= Camera.main.WorldToScreenPoint(transform.position).z;
//debug一下就知道这两个z是一样的
//保持鼠标的屏幕坐标的z值与被拖拽物体的屏幕坐标的z保持一致
Vector3 v3 = new Vector3(Input.mousePosition.x, Input.mousePosition.y, z);
//得到鼠标点击位置与物体中心位置的差值
offset = transform.position - Camera.main.ScreenToWorldPoint(v3);
}
private void OnMouseDrag()
{
//时刻保持鼠标的屏幕坐标的z值与被拖拽物体的屏幕坐标保持一致
Vector3 v3 = new Vector3(Input.mousePosition.x, Input.mousePosition.y, z);
//鼠标的屏幕坐标转换为世界坐标+偏移量=物体的位置
transform.position = Camera.main.ScreenToWorldPoint(v3) + offset;
}
}
第三种
使用条件
1.3d物体和worldspace模式的画布UI
2.必须有碰撞器
using UnityEngine;
public class Test2 : MonoBehaviour
{
//1.3d物体和worldspace模式的画布UI
//2.必须有碰撞器
Vector3 offset;
Vector3 hitpoint;
RaycastHit hit;
Ray ray;
float z;
private bool mIsDrag = false;
private void Update()
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Input.GetMouseButtonDown(0))
{
if (Physics.Raycast(ray,out hit))
{
mIsDrag = true;
z = Vector3.Dot(hit.transform.position - Camera.main.transform.position,
Camera.main.transform.forward);
//也可写z = Camera.main.WorldToScreenPoint(hit.transform.position).z,两者是一样的
offset = hit.transform.position - Camera.main.ScreenToWorldPoint(new Vector3
(Input.mousePosition.x, Input.mousePosition.y,z));
}
}
if (Input.GetMouseButton(0))
{
if (mIsDrag)
{
hit.transform.position = Camera.main.ScreenToWorldPoint(new Vector3(
Input.mousePosition.x,Input.mousePosition.y, z))+offset;
}
}
if (Input.GetMouseButtonUp(0))
{
mIsDrag = false;
}
}
}
2021.5.28补充一种拖拽方式,其原理还是射线,不过我觉得他更适合VR手柄,而且比较简单,没有太多的转换,使用条件和第三种一样
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
float mDistance;
Ray mRay;
RaycastHit mHit;
GameObject mCurrentDragGo;
Vector3 offset = Vector3.zero;
public GameObject mHand;
// Update is called once per frame
void Update()
{
}
//鼠标模拟
void MouseInput()
{
mRay = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Input.GetMouseButtonDown(0))
{
if (Physics.Raycast(mRay, out mHit))
{
mDistance = Vector3.Distance(mRay.origin, mHit.point);
mCurrentDragGo = mHit.transform.gameObject;
offset = mCurrentDragGo.transform.position - mHit.point;
}
}
if (Input.GetMouseButton(0))
{
if (mCurrentDragGo)
{
Vector3 vector3 = mRay.GetPoint(mDistance);
Debug.Log(vector3);
mCurrentDragGo.transform.position = vector3 + offset;
}
}
if (Input.GetMouseButtonUp(0))
{
mCurrentDragGo = null;
mDistance = 0;
}
}
//手柄输入
void HandInput()
{
mRay = new Ray(mHand.transform.position, mHand.transform.forward);
if (Input.GetKeyDown(KeyCode.Q))
{
if (Physics.Raycast(mRay, out mHit))
{
mDistance = Vector3.Distance(mRay.origin, mHit.point);
mCurrentDragGo = mHit.transform.gameObject;
offset = mCurrentDragGo.transform.position - mHit.point;
}
}
if (Input.GetKey(KeyCode.Q))
{
if (mCurrentDragGo)
{
Vector3 vector3 = mRay.GetPoint(mDistance);
mCurrentDragGo.transform.position = vector3 + offset;
}
}
if (Input.GetKeyUp(KeyCode.Q))
{
mCurrentDragGo = null;
mDistance = 0;
}
if(Input.GetKey(KeyCode.LeftArrow))
{
mHand.transform.position+=Time.deltaTime*10*Vector3.left;
}
if(Input.GetKey(KeyCode.RightArrow))
{
mHand.transform.position+=Time.deltaTime*10*Vector3.right;
}
}
}
最后
以上就是小巧咖啡为你收集整理的unity拖拽的三种实现方式的全部内容,希望文章能够帮你解决unity拖拽的三种实现方式所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复