所谓拖拽锁就是在用户上下滑动后,把左右滑动禁止掉,左右滑动时,把上下滑动禁止掉
最近最后做了一次调整,改掉了所有的问题,基本上可以用来,唯一的障碍是ngui的渲染效率问题,dragable panel这东西如果内部的组件过多,会十分消耗性能,找机会看一下ngui的drawcall的计算原理就可以了最终的代码
最后优化完成版:
适用于鼠标和单手指手势
public class DragPanelControl : MonoBehaviour
{
#region//定义变量
// 面板暂时可查看变量
public UIDraggablePanel DPanel;//可拖拽panel
public Transform CardPanel;//兵卡数据容器
//public SoldierModel model;//model负责ui逻辑和数据操作model = GameObject.Find("Model_UILogic").GetComponent<SoldierModel>();
public int currentId;//当前是第几个面板显示在正中间
public bool isDragging;//正在拖拽
public Dir dir;//可拖拽方向
//public AnimationCurve aniCurve;
//私有变量
private UIPanel mPanel; //手指拖动的距离
private Vector2 delta; //手指拖动的距离
private Vector2 startFingerPos; //手指的初始位置
private WindowSP windows;//窗口数据
private Transform LeftPos;
private Transform RightPos;
private Vector3 MiddlePos;
static private Transform RightPosStatic;
static private Transform MiddlePosStatic;
static private GameObject CardPanelStatic;
static private DragPanelControl dpc;
#endregion
void Start()
{
DPanel = this.GetComponent<UIDraggablePanel>();
mPanel= this.GetComponent<UIPanel>();
CardPanel = this.transform.FindChild("UiGrid02").transform;
LeftPos = this.transform.FindChild("UiGrid01").transform;
RightPos = this.transform.FindChild("UiGrid03").transform;
MiddlePos = CardPanel.position;
currentId = 1;
isDragging = false;
dir = Dir.none;
DragPanelControl.RightPosStatic = RightPos;
DragPanelControl.CardPanelStatic = CardPanel.gameObject;
DragPanelControl.dpc = GameObject.Find("Cards").GetComponent<DragPanelControl>();
}
bool isMoveMoreThanThesold = false;
// Update is called once per frame
void Update()
{
if (windows == null)
{
windows = UIData.Instance.soldierModel.WindowProperty;
}
//检测是否触摸了屏幕
if (windows.SoldierCardWindow && (Application.platform == RuntimePlatform.WindowsEditor || Input.touchCount == 1) && !isDragging)
{
#region//开始触摸
if (Input.GetMouseButtonDown(0))
{
delta = (Vector2)Input.mousePosition;
}
#endregion
#region //发生触摸位置移动
else if (Input.GetMouseButton(0))
{
if(!isMoveMoreThanThesold)
{
if(Vector2.Distance(delta,Input.mousePosition) > 10f)
{
isMoveMoreThanThesold = true;
}
return;
}
if (dir == Dir.none)
{
delta = (Vector2)Input.mousePosition - delta;
startFingerPos = Input.mousePosition;
if (Vector2.Angle(delta, Vector2.right) < 50 && dir != Dir.UpDown)
{
DPanel.scale.x = 0;
DPanel.scale.y = 0;
dir = Dir.right;
delta = (Vector2)Input.mousePosition;
}
else if (Vector2.Angle(delta, -Vector2.right) < 50 && dir != Dir.UpDown)
{
DPanel.scale.x = 0;
DPanel.scale.y = 0;
dir = Dir.lfet;
delta = (Vector2)Input.mousePosition;
}
else if (Vector2.Angle(delta, -Vector2.up) < 30 || Vector2.Angle(delta, Vector2.up) < 30)
{
DPanel.scale.x = 0;
DPanel.scale.y = 2;
dir = Dir.UpDown;
}
else
{
DPanel.scale.x = 0;
DPanel.scale.y = 2;
dir = Dir.none;
}
}
//移动数据面板
else if (dir == Dir.lfet || dir == Dir.right)
{
CardPanel.transform.localPosition = new Vector3(((Vector2)Input.mousePosition - delta).x*5, CardPanel.transform.localPosition.y,0);
mPanel.Refresh();
}
}
#endregion
//FIXME:左右翻页的判断条件有问题,应该在结束触摸时判断方向
//已经解决~!
#region//结束触摸
else if (Input.GetMouseButtonUp(0))
{
isMoveMoreThanThesold = false;
DPanel.scale.x = 0;
DPanel.scale.y = 0;
delta = Input.mousePosition;
currentId = windows.CurrentPage;
if (((delta.x - startFingerPos.x) > 0) && dir != Dir.none && dir != Dir.UpDown)
{
dir = Dir.right;
}
else if (((delta.x - startFingerPos.x) < 0) && dir != Dir.none && dir != Dir.UpDown)
{
dir = Dir.lfet;
}
else
{
dir = Dir.none;
}
switch (dir)
{
case Dir.lfet:
//注:方向左是向右翻页
dir = Dir.none;
if (currentId < windows.TotalPage)
{
isDragging = true;
currentId++;
FlipPage(Dir.lfet, currentId);//调用翻页,刷新数据
}
else
{
isDragging = true;
currentId = 1;//返回第一一页,因为右翻页已经翻到最后一页
FlipPage(Dir.lfet, currentId);//调用翻页,刷新数据
}
break;
case Dir.right:
//方向右是向左翻页
dir = Dir.none;
if (currentId > 1)
{
isDragging = true;
currentId--;
FlipPage(Dir.right, currentId);//调用翻页,刷新数据
}
else
{
isDragging = true;
currentId = windows.TotalPage;//返回最后一页,因为左翻页已经翻到最后一页
FlipPage(Dir.right, currentId);//调用翻页,刷新数据
}
break;
}
windows.CurrentPage = currentId;//TODO:页面的计数不应该放在这里,应该剥离开
}
#endregion
}
}
/// <summary>
/// 翻页
/// </summary>
/// <param name="dir"></param>
/// <param name="Id"></param>
private void FlipPage(Dir dir, int Id)
{
RightPos.position = new Vector3(RightPos.position.x, MiddlePos.y, RightPos.position.z);
LeftPos.position = new Vector3(LeftPos.position.x, MiddlePos.y, LeftPos.position.z);
Vector3 targetPos = Vector3.zero;//目标位置
switch (dir)
{
case Dir.lfet:
iTween.MoveTo(CardPanel.gameObject, iTween.Hash("position", RightPos, "time", 0.01f, "oncomplete", "AdjustPage", "oncompletetarget", this.gameObject));
//iTween.MoveTo(CardPanel.gameObject, iTween.Hash("position", MiddlePos, "delay", 0.1f, "time", 0.6f,"OnComplete","ResetPage"));
break;
case Dir.right:
iTween.MoveTo(CardPanel.gameObject, iTween.Hash("position", LeftPos, "time", 0.01f, "oncomplete", "AdjustPage", "oncompletetarget", this.gameObject));
//iTween.MoveTo(CardPanel.gameObject, iTween.Hash("position", MiddlePos, "delay", 0.1f, "time", 0.6f,"OnComplete", "ResetPage"));
break;
}
UIData.Instance.soldierModel.RefreshCards(Id);
}
/// <summary>
/// TODO:页面归位,即摄像头指向卡片页面最上方
/// </summary>
static public void ResetPage()
{
iTween.MoveTo(CardPanelStatic.gameObject, iTween.Hash("position", RightPosStatic, "time", 0.01f));
iTween.MoveTo(CardPanelStatic.gameObject, iTween.Hash("position", MiddlePosStatic, "delay", 0.05f, "time", 0.1f));
}
/// <summary>
/// 在页面移动到屏幕外之后,调整页面位置,回到屏幕中间
/// </summary>
public void AdjustPage()
{
iTween.MoveTo(CardPanel.gameObject, iTween.Hash("position", MiddlePos, "delay", 0.05f, "time", 0.2f, "oncomplete", "FinishAdjustPage", "oncompletetarget", this.gameObject));
}
//完成页面调整
public void FinishAdjustPage()
{
isDragging = false;
}
}