Unity中ScrollRect与OnDrag事件的冲突解决方法
2019-10-22 本文已影响0人
沉麟
项目需要:一个ScrollView里面的物体既可以点击,也可以整体滑动ScrollView,按住物体两秒还能实现拖拽。
using Constants;
using System.Collections;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using DG.Tweening;
public class DragPlant : BasePlant, IPointerUpHandler, IPointerExitHandler, IDragHandler, IBeginDragHandler, IEndDragHandler, IPointerDownHandler
{
//IDragHandler, IBeginDragHandler, IEndDragHandler,
public int selfId =1;
public bool useing =false;//使用中 未使用1
public int selfLv =1;//自身等级 三种形态 幼儿期/成长期/成熟期
public long selfProfit = 0;//自身平均收益
public string selfName = "";//自身平均收益
public Sprite selfIcon = null;//自身图标
//自身父物体
private Transform myParent;
//Panel,使拖拽是显示在最上方.
private Transform tempParent;
private CanvasGroup cg;
private RectTransform rt;
private GameObject targetObj = null;
//记录鼠标位置.
private Vector3 newPosition;
DragPlant go;
private bool isPutDown = false;//是否按下
private float dis = 0.1f;//按下与抬起之间的距离
private float putDownTime = 2f;//总的按下时间
private float curDownTime = 0;//当前时间
private Vector3 curPos;//当前位置
private Vector3 endPos;//上次位置
//使用中的标志
[Header("使用中的标志")]
public GameObject plantUse;
//点击下降位置
Vector3 downPos;
//是否暂停动画
// bool isStop = false;
Animator plantAnim;
//实例化的收益物体
public UnitPool unit;
//产生收益的位置
private Transform startTran;
private Vector3 startPos;
//植物图片
public Image plantImage;
private void Awake()
{
//添加CanvasGroup组件用于在拖拽时忽略自己,从而检测到被交换的图片.
if (gameObject.GetComponent<CanvasGroup>() == null)
{
cg = this.gameObject.AddComponent<CanvasGroup>();
}
else
{
cg = gameObject.GetComponent<CanvasGroup>();
}
rt = transform.GetComponent<RectTransform>();
tempParent = GameObject.Find("UIMgr").transform;
EventManager.Instance.AddEvent<Vector3>(EventKey.EventFarmPointDown, this.OnFarmPointDown);
}
void Start()
{
myParent = transform.parent;
startTran = transform.Find("StartPos");
startPos = startTran.position;
plantImage = transform.Find("plantImage").GetComponent<Image>();
plantAnim = plantImage.transform.GetComponent<Animator>();
transform.GetComponent<Button>().onClick.AddListener(OnPlantClick);
OnRefreshImg();
}
void Update()
{
if (isPutDown)
{
curDownTime += Time.deltaTime * 1;
if (curDownTime > 0.5f && Vector3.Distance(endPos, curPos) <= dis)
{
//显示圆形读条
if (!DynamicData.Instance.isRing)
{
HomeLayer.Instance.ShowRing();
DynamicData.Instance.isRing = true;
}
}
if (curDownTime >= putDownTime)
{
if (Vector3.Distance(endPos, curPos) > dis)
{
curDownTime = 0f;
return;
}
curDownTime = 0f;
isPutDown = false;
DynamicData.Instance.isDragPlant = true;
HomeLayer.Instance.ShowRing();
HomeManager.Instance.ShowOpts();
}
}
}
public void OnFarmPointDown(Vector3 pointer) {
}
/// <summary>
/// 开始拖拽
/// </summary>
/// <param name="eventData"></param>
public void OnBeginDrag(PointerEventData eventData)
{
if (!DynamicData.Instance.isDragPlant)
{
HomeLayer.Instance.farmScroll.OnBeginDrag(eventData);
return;
}
//拖拽开始时记下自己的父物体.
myParent = transform.parent;
//拖拽开始时禁用检测.
cg.blocksRaycasts = false;
transform.SetParent(tempParent);
////创建半透明植物残影
//go = Instantiate(this, myParent);
//go.transform.localPosition = Vector3.zero;
//go.transform.GetComponent<Image>().color = new Color(1f, 1f, 1f, 0.3f);
//显示选框
//HomeManager.Instance.ShowIsEmptyOpt();
//HomeLayer._instance.tempParent.position = myParent.position;
//if (plantUse.activeInHierarchy)
//{
// plantUse.transform.SetParent(transform);
// plantUse.SetActive(false);
//}
//transform.SetParent(HomeLayer._instance.tempParent);
//LayoutFream._instance.ShowFreamAll(); //显示选框
//显示可回收标识
//Debug.LogError("开始拖拽植物");
}
/// <summary>
/// 拖拽中
/// </summary>
/// <param name="eventData"></param>
public void OnDrag(PointerEventData eventData)
{
curPos = eventData.position;
if (!DynamicData.Instance.isDragPlant)
{
HomeLayer.Instance.farmScroll.OnDrag(eventData);
return;
}
//if (HomeLayer.Instance.BGImage.raycastTarget)
//{
// return;
//}
GameObject target = eventData.pointerEnter;
//被选中的图片压暗
//if (target.transform.parent.tag == "Pergola"&& target.tag == "plant")
//{
// if (targetObj != null && targetObj != target)
// {
// targetObj.GetComponent<Image>().color = Color.white;
// }
// target.transform.GetComponent<Image>().color = new Color(0.8f, 0.8f, 0.8f, 1f);
// targetObj = target;
//}
//拖拽时图片跟随鼠标移动.
RectTransformUtility.ScreenPointToWorldPointInRectangle(rt, Input.mousePosition, eventData.enterEventCamera, out newPosition);
transform.position = newPosition;
SetDrag(eventData);
//Debug.LogError("拖拽中");
//if (target.transform.tag == "plant")
//{
// //如果有物体
// if (target.GetComponent<DragPlant>())
// {
// //Debug.LogError("交换位置:" + target.name);
// Transform t = target.transform.parent;
// target.transform.SetParent(myParent);
// target.GetComponent<Image>().raycastTarget = false;
// target.transform.DOLocalMove(Vector3.zero, 0.35f).OnComplete(() => {
// target.GetComponent<Image>().raycastTarget = true;
// });
// myParent = t;
// //transform.SetParent(myParent);
// }
//}
}
/// <summary>
/// 结束拖拽 判断鼠标下的物体
/// </summary>
/// <param name="eventData"></param>
public void OnEndDrag(PointerEventData eventData)
{
if (!DynamicData.Instance.isDragPlant)
{
HomeLayer.Instance.farmScroll.OnEndDrag(eventData);
return;
}
//隐藏标识
HomeManager.Instance.HideOpts();
//获取鼠标下面的物体.
GameObject target = eventData.pointerEnter;
if (target == null)
{
//Debug.LogError("拖拽位置有误:" + target.name);
transform.SetParent(myParent);
transform.localPosition = Vector3.zero;
//拖拽结束时启用检测.
cg.blocksRaycasts = true;
return;
}
//如果能检测到物体.
if (target && target.tag == "Pergola" || target.transform.parent.tag == "Pergola")
{
//如果是花架
if (target.tag == "Pergola")
{
//如果花架里没东西
if (target.transform.GetComponentInChildren<DragPlant>() == null && target.tag == "Pergola")
{
//Debug.LogError("空花架:" + target.name);
myParent = target.transform;
transform.SetParent(myParent);
transform.DOLocalMove(Vector3.zero, 0.5f);
}
else
{
//Debug.LogError("有物体:" + target.transform.GetChild(0).name);
transform.SetParent(myParent);
transform.DOLocalMove(Vector3.zero, 0.5f);
}
}
else if (target.transform.tag == "plant")
{
//如果有物体
if (target.GetComponent<DragPlant>())
{
//Debug.LogError("交换位置:" + target.name);
Transform t = target.transform.parent;
target.transform.SetParent(myParent);
target.transform.DOLocalMove(Vector3.zero, 0.35f);
myParent = t;
transform.SetParent(myParent);
transform.DOLocalMove(Vector3.zero, 0.5f);
}
}
else
{
//Debug.LogError("有物体:" + target.transform.GetChild(0).name);
transform.SetParent(myParent);
transform.DOLocalMove(Vector3.zero, 0.5f);
}
}
else if (target.tag == "ShowPlantArea")
{
//Debug.LogError("展示当前盆栽:" + target.name);
transform.SetParent(myParent);
transform.DOLocalMove(Vector3.zero, 0.5f);
if (selfLv >= 60)
{
AppData.Instance.curPlant = selfId;
target.transform.GetComponentInChildren<ShowCurPlant>().Show(AppData.Instance.curPlant);
}
}
else
{
//Debug.LogError("拖拽位置有误:" + target.name);
transform.SetParent(myParent);
transform.DOLocalMove(Vector3.zero, 0.5f);
}
//保存信息
//拖拽结束时启用检测.
cg.blocksRaycasts = true;
//HomeLayer.Instance.BGImage.raycastTarget = true;
DynamicData.Instance.isDragPlant = false;
DynamicData.Instance.isRing = false;
//刷新
//DynamicData.Instance.onEndDragCount++;
//HomeLayer._instance.text.text = "end:" + target.name + DynamicData.Instance.onEndDragCount.ToString();
//Debug.LogError("OnEndDrag:" + DynamicData.Instance.onEndDragCount);
}
public void OnPointerExit(PointerEventData eventData)
{
//GameObject target = eventData.pointerEnter;
//if (target.transform.parent.tag == "Pergola")
//{
// target.transform.GetComponent<Image>().color = new Color(1f, 1f, 1f, 1f);
//}
}
///// <summary>
///// 植物升级 切换精灵
///// </summary>
//public void UpLv(int lv)
//{
// //Debug.Log(AppData.Instance.plantShopDic[AppData.Instance.curPlant].selfId+"升级植物的等级");
// if (AppData.Instance.isUp && selfId == AppData.Instance.curPlant && selfLv < 60)
// {
// selfLv += lv;
// //Growth(selfLv);
// if (selfLv >= 60)
// {
// selfLv = 60;
// AppData.Instance.isPlantAgain = true;
// return;
// }
// AppData.Instance.isUp = false;
// }
//}
/// <summary>
/// 各个成长期精灵切换
/// </summary>
/// <param name="lv"></param>
public void Growth()
{
if (selfLv >= 60)
{
selfLv = 60;
}
if (selfLv <= 20)
{
StartCoroutine(LoadSprite("younian" + selfId, 1));
}
else if (selfLv <= 40)
{
StartCoroutine(LoadSprite("chengzhangqi_" + selfId, 2));
}
else if(selfLv >= 60)
{
StartCoroutine(LoadSprite("zhiwu" + selfId, 3));
}
transform.Find("GrowthFx").gameObject.SetActive(true);
transform.Find("GrowthFx").GetComponent<ParticleSystem>().Play();
}
/// <summary>
/// 根据植物成长期更换精灵图片
/// </summary>
/// <param name="pathName"></param>
/// <param name="lv"></param>
IEnumerator LoadSprite(string pathName, int lv)
{
yield return null;
SoundManager.Instance.Play(Enums.SoundId.lv);
string spritePath = pathName;
Image image = plantImage;
Sprite sp = Resources.Load<Sprite>(string.Format("UI/Plant/{0}/{1}", lv, spritePath));
image.sprite = sp;
yield return new WaitForSeconds(2f);
transform.Find("GrowthFx").gameObject.SetActive(false);
}
public void OnRefreshImg()
{
if (selfLv <= 20)
{
string str = "younian" + selfId.ToString();
plantImage.sprite = Resources.Load<Sprite>(string.Format("UI/Plant/{0}/{1}", 1, str));
}
else if (selfLv <= 40)
{
string str = "chengzhangqi_" + selfId.ToString();
plantImage.sprite = Resources.Load<Sprite>(string.Format("UI/Plant/{0}/{1}", 2, str));
}
else if (selfLv >= 60)
{
string str = "zhiwu" + selfId.ToString();
plantImage.sprite = Resources.Load<Sprite>(string.Format("UI/Plant/{0}/{1}", 3, str));
}
}
/// <summary>
/// 连续点击产生收益------------???不回收
/// </summary>
public void OnPlantClick()
{
//Debug.Log("OnPlantClick:......");
curDownTime = 0;
if (Application.isMobilePlatform)
{
for (int i = 0; i < Input.touchCount; ++i)
{
Touch touch = Input.GetTouch(i);
transform.GetComponent<UIEffect>().PlayFX(touch.position);
}
}
else
{
transform.GetComponent<UIEffect>().PlayFX(Input.mousePosition);
}
int dex = Random.Range(20, 29);//随机音效
SoundManager.Instance.Play((Enums.SoundId)dex);
plantAnim.speed = 0;
ContinuousProduce();
UpDown();
}
/// <summary>
/// 植物下降升起动画
/// </summary>
public void UpDown()
{
downPos = transform.GetComponent<RectTransform>().anchoredPosition;
downPos.y += 10;
transform.GetComponent<RectTransform>().anchoredPosition = downPos;
StartCoroutine(PlantDown());
}
IEnumerator PlantDown()
{
yield return new WaitForSeconds(0.1f);
downPos.y -= 10;
transform.GetComponent<RectTransform>().anchoredPosition = downPos;
plantAnim.speed = 1;
}
/// <summary>
/// 连续产生收益
/// </summary>
public void ContinuousProduce()
{
//Debug.Log("------连续产生收益------");
UnitPool unit1 = PoolManager.Instance.GetUnit(PoolManager.PoolType.PoolEarning, (UnitPool unit) =>
{ return ((EarningPool)unit).Id == 1; });
unit1.transform.SetParent(startTran);
//Debug.Log(unit1.transform.parent);
unit1.transform.position = startPos;
unit1.transform.localScale = Vector3.one;
StartCoroutine(WaitClose(unit1));
}
//播放动画后连续收益关闭
IEnumerator WaitClose(UnitPool unit)
{
yield return new WaitForSeconds(2f);
CloseEarning(unit);
}
/// <summary>
/// 正常产生收益
/// </summary>
public void ProduceEarning()
{
// Debug.Log("------正常产生收益------");
unit = PoolManager.Instance.GetUnit(PoolManager.PoolType.PoolEarning, (UnitPool unit) =>
{ return ((EarningPool)unit).Id == 1; });
unit.transform.SetParent(startTran);
// Debug.Log(unit.transform.parent);
unit.transform.position = startPos;
unit.transform.localScale = Vector3.one;
}
/// <summary>
/// 正常收益关闭
/// </summary>
/// <param name="unit"></param>
public void CloseEarning(UnitPool unit)
{
PoolManager.Instance.SetUnit(unit);
unit.transform.SetParent(startTran);
}
/// <summary>
/// 拖拽时的位置
/// </summary>
/// <param name="eventData"></param>
void SetDrag(PointerEventData eventData)
{
Vector3 pos;
if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rt, eventData.position, eventData.enterEventCamera, out pos))
{
pos.y += 1f;
transform.position = pos;
}
}
/// <summary>
/// 点击抬起
/// </summary>
/// <param name="eventData"></param>
public void OnPointerUp(PointerEventData eventData)
{
curPos = Vector3.zero;
endPos = Vector3.zero;
isPutDown = false;
}
/// <summary>
/// 在回收栏实例化 转换信息
/// </summary>
void CollectMessage()
{
GameObject gb = Instantiate(Resources.Load("Prefab/RecoverItem/PlantRecover"), UIMgr.Instance.recoverParent) as GameObject;
RescoverItem rt = gb.GetComponent<RescoverItem>();
// AppData.Instance.returnPlants.Add(selfId, this);
AppData.Instance.reList.Add(this);
AppData.Instance.isSignRecover = true;
rt.reID = selfId;
rt.reLv = selfLv;
rt.plantName = selfName;
rt.earning = selfProfit;
rt.reIcon = Resources.Load<Sprite>(string.Format("UI/PlantIcon/icon{0}", selfId));
AppData.Instance.list_reItem.Add(rt);
}
/// <summary>
/// 展示台刷新
/// </summary>
private void OnFreash()
{
if (transform.parent.tag == "showPlank")
{
AppData.Instance.curPlayID = selfId;//把在使用中的植物赋到游戏场景中
}
}
//是否触碰到回收标志
bool istrigger = false;
//private void OnTriggerEnter2D(Collider2D collision)
//{
// //触碰选框 播放动画
// if (collision.gameObject.tag == "chooseFream"&& collision.transform.parent!=transform.parent)
// {
// Debug.Log(collision.gameObject.tag);
// LayoutFream._instance.ShowFreamOne(collision.transform);//显示选框
// }
// //触碰回收标志
// if (collision.gameObject.tag=="recover")
// {
// collision.transform.localScale = Vector3.one * 2f;
// istrigger = true;
// }
//}
//private void OnTriggerExit2D(Collider2D collision)
//{
// if (collision.gameObject.tag == "chooseFream"&& collision.transform.parent != transform.parent)
// {
// Debug.Log(collision.gameObject.tag);
// LayoutFream._instance.CloseFreamOne(collision.transform);//关闭选框
// }
// if (collision.gameObject.tag == "recover")
// {
// collision.transform.localScale = Vector3.one;
// }
//}
/// <summary>
/// 植物的数据 记录数据使用
/// </summary>
/// <returns></returns>
public PlantData GetPlantData() {
return new PlantData()
{
selfId = selfId,
useing = useing,
selfLv = selfLv,
selfProfit = selfProfit
};
}
public void OnPointerDown(PointerEventData eventData)
{
//DynamicData.Instance.isDragPlant = false;
//throw new System.NotImplementedException();
//StartCoroutine(Timer());
endPos = Input.mousePosition;
curPos = Input.mousePosition;
isPutDown = true;
}
IEnumerator Timer()
{
yield return new WaitForSeconds(2f);
DynamicData.Instance.isDragPlant = true;
//endPos = Input.mousePosition;
//if (Vector3.Distance(endPos, startPos) < 0.1f)
//{
// DynamicData.Instance.isDragPlant = true;
// GetComponent<Image>().raycastTarget = false;
// HomeManager.Instance.ShowOpts();
//}
//Debug.LogError("Vector3.Distance(endPos,startPos)" + Vector3.Distance(endPos, startPos));
}
}
将脚本挂到物体上做成预制物,既可以拖拽,滑动,也能点击。