/*
********************************************************************************
*Copyright(C),coolae.net
*Author: chenbin
*Version: 2.0
*Date: 2017-01-09
*Description: 通过ui的drag来处理对3d场景中处理
* 使用说明:
1.在ui层绑定该脚本
2.在3d场景中有主摄像机要绑定CLSmoothFollow脚本和MyMainCamera脚本
3.CLSmoothFollow要有一个target
4.再把2,3赋值给本脚本中的target变量及mainCamera变量等
5.特别注意groundMask,这个可以处理能够看到的地表的大小,因此需要地表有boxCollider
*Others:
*History:
*********************************************************************************
*/
using UnityEngine;
using System.Collections;
namespace Coolape
{
[ExecuteInEditMode]
public class CLUIDrag4World : MonoBehaviour
{
public enum DragEffect
{
None,
Momentum,
MomentumAndSpring,
}
public static CLUIDrag4World self;
public CLUIDrag4World()
{
self = this;
}
public object onDragMoveDelegate = null; // 当移动时的代理
public object onEndDragMoveDelegate = null; // 当移动结束时的代理
public object onDragScaleDelegate = null; // 缩放代理
public object onDragAngleViewCallback = null; //旋转回调
public MyMainCamera main3DCamera;
///
/// Target object that will be dragged.
///
public Transform target;
public CLSmoothFollow scaleTarget;
public bool canMove = true;
public bool canRotation = true;
public bool canRotationOneTouch = true;
public bool canScale = true;
[HideInInspector]
public bool canDoInertance = true;
//是否严格检测可视范围
public bool isLimitCheckStrict = true;
int _dragProcType = -1;
//0:拖动 1:旋转 2:缩放
int dragProcType
{
get
{
return _dragProcType;
}
set
{
if (_dragProcType != value)
{
oldTowFingersDis = -1;
}
_dragProcType = value;
}
}
///
/// Scale value applied to the drag delta. Set X or Y to 0 to disallow dragging in that direction.
///
public Vector3 dragMovement { get { return scale; } set { scale = value; } }
///
/// Momentum added from the mouse scroll wheel.
///
public Vector3 scrollMomentum = Vector3.zero;
///
/// Effect to apply when dragging.
///
public DragEffect dragEffect = DragEffect.MomentumAndSpring;
///
/// How much momentum gets applied when the press is released after dragging.
///
public float momentumAmount = 35f;
// Obsolete property. Use 'dragMovement' instead.
[SerializeField]
protected Vector3
scale = new Vector3(1f, 1f, 0f);
//====limit setting
public LayerMask groundMask;
public Vector3 viewCenter = Vector3.zero;
public float viewRadius = 10;
public float rotationMini = 0;
public float rotationMax = 0;
public float scaleMini = 0;
public float scaleMax = 0;
public float scaleHeightMini = 0;
public float scaleHeightMax = 0;
public float rotateSpeed = 1;
public float scaleSpeed = 1;
public float inertanceSpeed = 1;
//惯性speed
// Obsolete property. Use 'scrollMomentum' instead.
[SerializeField]
[HideInInspector]
float
scrollWheelFactor = 0f;
Vector2 inputPos;
Vector3 mLastPos;
Vector3 mMomentum = Vector3.zero;
Vector3 mScroll = Vector3.zero;
int mTouchID = 0;
bool mStarted = false;
bool mPressed = false;
Vector2 limitOffset = Vector2.zero;
public float _scaleValue
{
get
{
return scaleTarget.height / 10f;
}
}
float scaleValue = 1;
///
/// Auto-upgrade the legacy data.
///
float _scaleOffsetVal_ = 200;
void Start()
{
float size = Screen.width < Screen.height ? Screen.height : Screen.width;
_scaleOffsetVal_ = size / 5;
}
void OnEnable()
{
if (scrollWheelFactor != 0f)
{
scrollMomentum = scale * scrollWheelFactor;
scrollWheelFactor = 0f;
}
dragProcType = -1;
}
void OnDisable()
{
dragProcType = -1;
mStarted = false;
}
static Hashtable canProcClickPanels = new Hashtable();
public static void setCanClickPanel(string pName)
{
canProcClickPanels[pName] = true;
}
public static void removeCanClickPanel(string pName)
{
canProcClickPanels[pName] = null;
}
///
/// Create a plane on which we will be performing the dragging.
///
void OnPress(bool pressed)
{
// Unity's physics seems to break when timescale is not quite zero. Raycasts start to fail completely.
float ts = Time.timeScale;
if (ts < 0.01f && ts != 0f)
return;
if (Input.touchCount > 1 && !main3DCamera.allowMultiTouch)
{
if (main3DCamera.enabled)
{
main3DCamera.ProcessRelease();
main3DCamera.enabled = false;
}
}
else
{
if (CLPanelManager.topPanel != null &&
canProcClickPanels[CLPanelManager.topPanel.name] != null)
{
if (pressed && main3DCamera != null)
{//add by chenbin
main3DCamera.enabled = true;
main3DCamera.Update();
main3DCamera.LateUpdate();
}
}
}
if (enabled && NGUITools.GetActive(gameObject) && target != null)
{
if (pressed)
{
unDoInertance();
if (!mPressed)
{
scaleValue = _scaleValue;
inputPos = UICamera.currentTouch.pos;
// Remove all momentum on press
mTouchID = UICamera.currentTouchID;
mPressed = true;
mStarted = false;
CancelMovement();
// Disable the spring movement
CancelSpring();
}
}
else if (mPressed && mTouchID == UICamera.currentTouchID)
{
mPressed = false;
if (dragEffect != DragEffect.MomentumAndSpring)
{
CancelMovement();
unDoInertance();
}
if (dragProcType == 0)
{
if (limitDisplayView())
{
if (canMove)
{
doInertance();
}
else
{
unDoInertance();
}
}
else
{
unDoInertance();
}
}
else
{
unDoInertance();
}
}
}
//===========================
dragProcType = -1;
}
Vector2 dragDelta = Vector2.zero;
///
/// Drag the object along the plane.
///
public void OnDrag(Vector2 delta)
{
dragDelta = delta;
switch (dragProcType)
{
case 0:
if (canMove)
{
doOnDragMove(delta);
}
break;
case 1:
if (canRotation)
{
procAngleView(delta);
}
break;
case 2:
if (canScale)
{
procScalerSoft(delta);
}
break;
case 3:
proc2TouchsDrag(delta);
break;
default:
break;
}
}
void doOnDragMove(Vector2 delta)
{
if (mPressed && mTouchID == UICamera.currentTouchID &&
enabled && NGUITools.GetActive(gameObject) && target != null && main3DCamera != null)
{
Vector3 offset = getMoveOffset(delta);
if (dragEffect != DragEffect.None)
mMomentum = Vector3.Lerp(mMomentum, mMomentum + offset * (0.01f * momentumAmount), 0.67f);
// Adjust the position and bounds
Move(offset, false);
// Constrain the UI to the bounds, and if done so, immediately eliminate the momentum
if (dragEffect != DragEffect.MomentumAndSpring)
{
CancelMovement();
}
}
}
Vector3 getMoveOffset(Vector2 delta)
{
Vector2 offset = delta;
offset.Scale(scale);
Vector3 off = Vector3.zero;
float angle = target.rotation.eulerAngles.y * Mathf.PI / 180;
off.x = -((offset.x) * Mathf.Cos(angle) + (offset.y) * Mathf.Sin(angle));
off.z = -((offset.y) * Mathf.Cos(angle) - (offset.x) * Mathf.Sin(angle));
off = off * scaleValue * 0.015f;
return off;
}
///
/// Move the dragged object by the specified amount.
///
void Move(Vector3 worldDelta, bool isDoLimitView = false)
{
Vector3 before = target.position;
Vector3 orgDelta = worldDelta;
target.position = before + worldDelta;
scaleTarget.LateUpdate(); //执行一次跟随
bool inGround = true;
if (isDoLimitView)
{
inGround = limitDisplayView(ref worldDelta);
}
else
{
inGround = isInviewBounds(ref worldDelta);
}
if (!inGround)
{
if (!isDoLimitView)
{
//target.position = before + worldDelta;
target.position = before + orgDelta;
CancelMovement();
}
}
else
{
Utl.doCallback(onDragMoveDelegate, worldDelta);
}
}
RaycastHit hitOut;
Ray veiwRay;
bool getViewPoint2World(Vector3 pos, ref Vector3 outPos)
{
veiwRay = main3DCamera.cachedCamera.ScreenPointToRay(pos);
outPos = Vector3.zero;
if (Physics.Raycast(veiwRay, out hitOut, 2000, groundMask))
{
outPos = hitOut.point;
return true;
}
return false;
}
Vector3 viewLeft = Vector3.zero;
Vector3 viewRight = Vector3.zero;
Vector3 viewTop = Vector3.zero;
Vector3 viewBottom = Vector3.zero;
bool inGroundLeft = false;
bool inGroundRight = false;
bool inGroundTop = false;
bool inGroundBottom = false;
bool isInviewBounds()
{
Vector3 offset = Vector3.zero;
return isInviewBounds(ref offset);
}
bool isInviewBounds(ref Vector3 offset)
{
if (offset == null)
{
offset = Vector3.zero;
}
inGroundLeft = getViewPoint2World(new Vector3(0, Screen.height / 2, 0), ref viewLeft);
inGroundRight = getViewPoint2World(new Vector3(Screen.width, Screen.height / 2, 0), ref viewRight);
inGroundTop = getViewPoint2World(new Vector3(Screen.width / 2, Screen.height, 0), ref viewTop);
inGroundBottom = getViewPoint2World(new Vector3(Screen.width / 2, 0, 0), ref viewBottom);
if (isLimitCheckStrict)
{
if (!inGroundLeft || !inGroundRight || !inGroundTop || !inGroundBottom)
{
if (!inGroundLeft || !inGroundRight)
{
offset.x = 0;
}
if (!inGroundTop || !inGroundBottom)
{
offset.z = 0;
}
return false;
}
}
else
{
if (!inGroundLeft && !inGroundRight && !inGroundTop && !inGroundBottom)
{
float dis1 = Vector3.Distance(target.position, viewCenter);
float dis2 = Vector3.Distance(target.position + offset, viewCenter);
if (dis1 < dis2)
{
offset = Vector3.zero;
}
return false;
}
else if (!inGroundLeft && !inGroundRight && !inGroundTop)
{
offset = Vector3.zero;
return false;
}
else if (!inGroundLeft && !inGroundRight && !inGroundBottom)
{
offset = Vector3.zero;
return false;
}
else if (!inGroundLeft && !inGroundTop && !inGroundBottom)
{
offset = Vector3.zero;
return false;
}
else if (!inGroundRight && !inGroundTop && !inGroundBottom)
{
offset = Vector3.zero;
return false;
}
}
float disLeft = Vector3.Distance(viewCenter, viewLeft);
float disRight = Vector3.Distance(viewCenter, viewRight);
float disTop = Vector3.Distance(viewCenter, viewTop);
float disBottom = Vector3.Distance(viewCenter, viewBottom);
if ((disLeft > viewRadius || disRight > viewRadius)
&& (disTop > viewRadius || disBottom > viewRadius))
{
offset.x = 0;
offset.y = 0;
offset.z = 0;
return false;
}
if (disLeft > viewRadius || disRight > viewRadius)
{
offset.x = 0;
return false;
}
if (disTop > viewRadius || disBottom > viewRadius)
{
offset.z = 0;
return false;
}
return true;
}
void Update()
{
//处理旋转或缩放
screenTouch();
if (isLimitDisplayView)
{
canDoInertance = false;
Move(getMoveOffset(limitOffset * 50), true);
}
else
{
if (canDoInertance)
{
inertanceCount = inertanceCount + Time.unscaledDeltaTime;
if (inertanceCount > 1)
{
canDoInertance = false;
}
else
{
if (isInviewBounds())
{
Move(getMoveOffset(dragDelta * (1 - inertanceCount) * inertanceSpeed), false);
}
else
{
// limitDisplayView ();
canDoInertance = false;
}
}
}
}
}
float inertanceCount = 0;
public void doInertance()
{
inertanceCount = 0;
canDoInertance = true;
}
public void unDoInertance()
{
dragDelta = Vector2.zero;
inertanceCount = 0;
canDoInertance = false;
}
bool isTouchMoved = false;
bool isCameraRotation = false;
bool isFirstInOneTouch = false;
float touchClickThreshold = 5;
long StationaryTime = 0;
Touch touch1;
Touch touch2;
Vector2 totalDelta1 = Vector2.zero;
Vector2 totalDelta2 = Vector2.zero;
///
/// Screens the touch.处理旋转或缩放
///
void screenTouch()
{
if (CLPanelManager.topPanel != null &&
canProcClickPanels[CLPanelManager.topPanel.name] == null)
{
return;
}
if (Application.platform == RuntimePlatform.Android ||
Application.platform == RuntimePlatform.IPhonePlayer)
{
//两个手指滑动
if (Input.touchCount == 2)
{
touch1 = Input.touches[0];
touch2 = Input.touches[1];
isFirstInOneTouch = true;
if (Input.touches[0].phase == TouchPhase.Moved)
{
totalDelta1 += Input.touches[0].deltaPosition;
}
if (Input.touches[1].phase == TouchPhase.Moved)
{
totalDelta2 += Input.touches[1].deltaPosition;
}
if (Input.touches[0].phase == TouchPhase.Stationary)
{
totalDelta1 = Vector2.zero;
}
if (Input.touches[1].phase == TouchPhase.Stationary)
{
totalDelta2 = Vector2.zero;
}
//===============
if (touch1.phase == TouchPhase.Began ||
touch2.phase == TouchPhase.Began)
{
totalDelta1 = Vector2.zero;
totalDelta2 = Vector2.zero;
dragProcType = -1;
oldTowFingersDis = -1;
tempOldDis = -1;
}
else if (isTouchMoving(totalDelta1) ||
isTouchMoving(totalDelta2))
{
proc2TouchsDrag(dragDelta);
// dragProcType = 3;
}
else if (touch1.phase == TouchPhase.Ended ||
touch2.phase == TouchPhase.Ended)
{
dragProcType = -1;
isCameraRotation = false;
StationaryTime = System.DateTime.Now.AddSeconds(0.5f).ToFileTime();
isFirstInOneTouch = true;
}
}
else if (Input.touchCount == 1)
{ //一个手指
if (isFirstInOneTouch)
{
totalDelta1 = Vector2.zero;
//初始化视角转动参Number
StationaryTime = System.DateTime.Now.AddSeconds(0.5f).ToFileTime();
isCameraRotation = false;
isFirstInOneTouch = false;
isTouchMoved = false;
}
if (Input.touches[0].phase == TouchPhase.Stationary)
{
totalDelta1 = Vector2.zero;
if (canRotationOneTouch)
{
if (!isTouchMoved && !isCameraRotation && System.DateTime.Now.ToFileTime() - StationaryTime > 0)
{
isCameraRotation = true;
// dragProcType = 1;
//TODO:显示一个图标,表示已经选中了点
}
}
else
{
isCameraRotation = false;
dragProcType = -1;
}
}
else if (Input.touches[0].phase == TouchPhase.Began)
{
totalDelta1 = Vector2.zero;
isTouchMoved = false;
//初始化视角转动参Number
StationaryTime = System.DateTime.Now.AddSeconds(0.5f).ToFileTime();
isCameraRotation = false;
}
else if (Input.touches[0].phase == TouchPhase.Ended)
{
isTouchMoved = false;
isCameraRotation = false;
totalDelta1 = Vector2.zero;
dragProcType = -1;
}
else if (Input.touches[0].phase == TouchPhase.Moved)
{ //滑动
totalDelta1 += Input.touches[0].deltaPosition;
if (isTouchMoving(totalDelta1))
{
if (isCameraRotation)
{
dragProcType = 1;
}
else
{
isTouchMoved = true;
dragProcType = 0;
}
}
}
}
}
else
{
float v = Input.GetAxis("Mouse ScrollWheel");
if (Mathf.Abs(v) > 0.01f)
{
dragProcType = 2;
OnDrag(new Vector2(v * Screen.width, 0));
}
else
{
//视角转动处理
if (Input.GetMouseButtonDown(1))
{
dragProcType = 1;
}
else if (Input.GetMouseButtonDown(0))
{
dragProcType = 0;
}
}
}
}
bool isTouchMoving(Vector2 totalDelta)
{
float threshold = Mathf.Max(touchClickThreshold, Screen.height * 0.005f);
if (totalDelta.magnitude > threshold)
{
return true;
}
return false;
}
float tempOldDis = 0;
void proc2TouchsDrag(Vector2 iDelta)
{
if (Input.touchCount != 2)
{
dragProcType = -1;
return;
}
Vector2 pos1 = Input.touches[0].position;
Vector2 pos2 = Input.touches[1].position;
Vector2 cachDelta1 = Input.touches[0].deltaPosition;
Vector2 cachDelta2 = Input.touches[1].deltaPosition;
Vector2 dragDelta = iDelta;
if (touch2.position.x < touch1.position.x)
{
dragDelta = iDelta * -1;
pos1 = touch2.position;
pos2 = touch1.position;
cachDelta1 = touch2.deltaPosition;
cachDelta2 = touch1.deltaPosition;
}
Vector2 delta1 = cachDelta1;
Vector2 delta2 = cachDelta2;
delta1 = Mathf.Abs(delta1.x) > Mathf.Abs(delta1.y) ? new Vector2(delta1.x, 0) : new Vector2(0, delta1.y);
delta2 = Mathf.Abs(delta2.x) > Mathf.Abs(delta2.y) ? new Vector2(delta2.x, 0) : new Vector2(0, delta2.y);
if (
(delta1.x < 0 && delta2.x < 0) ||
(delta1.x > 0 && delta2.x > 0) ||
(delta1.y < 0 && delta2.y < 0) ||
(delta1.y > 0 && delta2.y > 0))
{ //两个手指向同一方向移动
dragProcType = -1;
}
else if ((
(Mathf.Abs(pos1.y - pos2.y) < _scaleOffsetVal_ &&
((delta1.x <= 0 && delta2.x > 0) ||
(delta1.x < 0 && delta2.x >= 0) ||
(delta1.x >= 0 && delta2.x < 0) ||
(delta1.x > 0 && delta2.x <= 0)
)
)) || (
(Mathf.Abs(pos1.x - pos2.x) < _scaleOffsetVal_ &&
((delta1.y <= 0 && delta2.y > 0) ||
(delta1.y < 0 && delta2.y >= 0) ||
(delta1.y >= 0 && delta2.y < 0) ||
(delta1.y > 0 && delta2.y <= 0))
)))
{ //缩放
// dragProcType = 2;
procScalerSoft(Vector2.zero);
}
else
{
float angle1 = getAngle(new Vector3(cachDelta1.x, 0, cachDelta1.y));
float angle2 = getAngle(new Vector3(-cachDelta2.x, 0, -cachDelta2.y));
Vector2 dir = Vector2.zero;
float dis = Vector2.Distance(pos1, pos2);
if (tempOldDis == -1)
{
tempOldDis = dis;
return;
}
if (tempOldDis > dis)
{
dir = pos2 - pos1;
}
else
{
dir = pos1 - pos2;
}
tempOldDis = dis;
float angle3 = getAngle(new Vector3(dir.x, 0, dir.y));
if (Mathf.Abs(angle3 - angle1) < 50f &&
Mathf.Abs(angle3 - angle2) < 50f)
{
//缩放
// dragProcType = 2;
procScalerSoft(Vector2.zero);
}
else
{
if (
(delta1.y <= 0 && delta2.y > 0) ||
(delta1.y < 0 && delta2.y >= 0))
{
procAngleView(dragDelta);
dragProcType = -1;
}
else if (
(delta1.y >= 0 && delta2.y < 0) ||
(delta1.y > 0 && delta2.y <= 0))
{
procAngleView(dragDelta);
dragProcType = -1;
}
if (
(delta1.x <= 0 && delta2.x > 0) ||
(delta1.x < 0 && delta2.x >= 0))
{
procAngleView(dragDelta);
dragProcType = -1;
}
else if (
(delta1.x >= 0 && delta2.x < 0) ||
(delta1.x > 0 && delta2.x <= 0))
{
procAngleView(dragDelta);
dragProcType = -1;
}
}
}
}
public float getAngle(Vector3 dir)
{
if (dir.magnitude < 0.001f)
{
return 0;
}
Quaternion toTarget = Quaternion.LookRotation(dir);
float angle = 0;
Vector3 axis = Vector3.zero;
toTarget.ToAngleAxis(out angle, out axis);
return angle;
}
//视角处理
void procAngleView(Vector2 delta)
{
if (!canRotation)
{
return;
}
// float angle = getAngle (new Vector3(delta.x, 0, delta.y));
float offset = 0;
#if UNITY_EDITOR
if (UIRoot.list.Count > 0 && Input.mousePosition.y > UIRoot.list[0].manualHeight/2) {
offset = -delta.x;
} else {
offset = delta.x;
}
#else
offset = Mathf.Abs(delta.x) > Mathf.Abs(delta.y) ? delta.x : delta.y;
#endif
target.Rotate (Vector3.up, rotateSpeed * Time.deltaTime * offset * 10);
Vector3 ea = target.localEulerAngles;
if (Mathf.Abs(rotationMax) > 0.0001f && Mathf.Abs(rotationMini) > 0.0001f) {
if (ea.y >= rotationMax) {
ea.y = rotationMax;
target.localEulerAngles = ea;
}
if (ea.y <= rotationMini) {
ea.y = rotationMini;
target.localEulerAngles = ea;
}
}
if (onDragAngleViewCallback != null)
{
Utl.doCallback(onDragAngleViewCallback, target.localEulerAngles);
}
limitDisplayView ();
}
float oldTowFingersDis = -1;
void procScalerSoft (Vector2 delta)
{
if (!canScale) {
return;
}
float offset = 0;
if (Input.touchCount == 2) {
float dis = Vector2.Distance (Input.touches [0].position, Input.touches [1].position);
if (oldTowFingersDis == -1) {
oldTowFingersDis = dis;
return;
}
offset = (dis - oldTowFingersDis);
oldTowFingersDis = dis;
} else {
offset = Mathf.Abs (delta.y) > Mathf.Abs (delta.x) ? delta.y : delta.x;
}
if (onDragScaleDelegate != null) {
Utl.doCallback (onDragScaleDelegate, delta, offset);
} else {
procScaler (offset);
}
}
public void procScaler (float delta)
{
CancelMovement();
unDoInertance();
if (!canScale) {
return;
}
if (scaleTarget == null) {
return;
}
float offset = Time.deltaTime * delta * scaleSpeed;
scaleTarget.distance -= offset;
scaleTarget.height -= offset;
if (scaleMax != 0 && scaleMini != 0) {
if (scaleTarget.distance >= scaleMax) {
scaleTarget.distance = scaleMax;
} else if (scaleTarget.distance <= scaleMini) {
scaleTarget.distance = scaleMini;
}
}
if (scaleHeightMax != 0 && scaleHeightMini != 0) {
if (scaleTarget.height >= scaleHeightMax) {
scaleTarget.height = scaleHeightMax;
} else if (scaleTarget.height <= scaleHeightMini) {
scaleTarget.height = scaleHeightMini;
}
}
limitDisplayView ();
}
bool isLimitDisplayView = false;
///
/// Limits the display view.
///
/// true, if display view was limited, false otherwise.
/*
* left->Rrigh:(-1,0)
* Rrigh->left:(1,0)
* bottom->up:(0, -1);
* up->bottom:(0, 1);
*/
public bool limitDisplayView ()
{
Vector3 offset = Vector3.zero;
return limitDisplayView (ref offset);
}
public bool limitDisplayView (ref Vector3 offset)
{
if (offset == null) {
offset = Vector3.zero;
}
bool ret = true;
isLimitDisplayView = false;
Vector3 pos = target.position;
Vector3 newPos = pos;
limitOffset = Vector2.zero;
inGroundLeft = getViewPoint2World (new Vector3 (0, Screen.height / 2, 0), ref viewLeft);
inGroundRight = getViewPoint2World (new Vector3 (Screen.width, Screen.height / 2, 0), ref viewRight);
inGroundTop = getViewPoint2World (new Vector3 (Screen.width / 2, Screen.height, 0), ref viewTop);
inGroundBottom = getViewPoint2World (new Vector3 (Screen.width / 2, 0, 0), ref viewBottom);
if (!inGroundLeft && !inGroundRight && !inGroundTop && !inGroundBottom) {
offset = Vector3.zero;
// target.position = viewCenter;
return false;
}
if (isLimitCheckStrict) {
if (!inGroundLeft && !inGroundRight) {
offset.x = 0;
newPos.x = viewCenter.x;
target.position = newPos;
} else {
if (!inGroundLeft) {
offset.x = 0;
limitOffset.x = -1;
isLimitDisplayView = true;
ret = false;
} else if (!inGroundRight) {
offset.x = 0;
limitOffset.x = 1;
isLimitDisplayView = true;
ret = false;
}
}
if (!inGroundTop && !inGroundBottom) {
offset.z = 0;
newPos.z = viewCenter.z;
target.position = newPos;
} else {
if (!inGroundTop) {
offset.z = 0;
limitOffset.y = 1;
isLimitDisplayView = true;
ret = false;
} else if (!inGroundBottom) {
offset.z = 0;
limitOffset.y = -1;
isLimitDisplayView = true;
ret = false;
}
}
} else {
if (!inGroundLeft && !inGroundRight && !inGroundTop && inGroundBottom) {
offset = Vector3.zero;
limitOffset.y = 1;
isLimitDisplayView = true;
ret = false;
} else if (!inGroundLeft && !inGroundRight && inGroundTop && !inGroundBottom) {
offset = Vector3.zero;
limitOffset.y = -1;
isLimitDisplayView = true;
ret = false;
} else if (!inGroundLeft && inGroundRight && !inGroundTop && !inGroundBottom) {
offset = Vector3.zero;
limitOffset.x = -1;
isLimitDisplayView = true;
ret = false;
} else if (inGroundLeft && !inGroundRight && !inGroundTop && !inGroundBottom) {
offset = Vector3.zero;
limitOffset.x = 1;
isLimitDisplayView = true;
ret = false;
}
}
//=======================================
float disLeft = Vector3.Distance (viewCenter, viewLeft);
float disRight = Vector3.Distance (viewCenter, viewRight);
float disTop = Vector3.Distance (viewCenter, viewTop);
float disBottom = Vector3.Distance (viewCenter, viewBottom);
float screenWidth = Vector3.Distance(viewLeft, viewRight);
float screenHeigh = Vector3.Distance(viewBottom, viewTop);
if (disLeft > viewRadius && disRight > viewRadius
&& (disLeft + disRight) < screenWidth + viewRadius/2)
{
//说明中心点还在屏内,那说是表示x轴已经不在在拖动
offset.x = 0;
newPos.x = viewCenter.x;
target.position = newPos;
limitOffset.x = 0;
}
else
{
if (disLeft > viewRadius && disRight > viewRadius
&& (disLeft + disRight) > screenWidth + viewRadius
&& disLeft > disRight)
{
offset.x = 0;
limitOffset.x = -1;
isLimitDisplayView = true;
ret = false;
} else if (disLeft > viewRadius && disRight > viewRadius
&& (disLeft + disRight) > screenWidth + viewRadius
&& disLeft <= disRight)
{
offset.x = 0;
limitOffset.x = 1;
isLimitDisplayView = true;
ret = false;
} else if(disLeft > viewRadius)
{
offset.x = 0;
limitOffset.x = -1;
isLimitDisplayView = true;
ret = false;
} else if (disRight > viewRadius)
{
offset.x = 0;
limitOffset.x = 1;
isLimitDisplayView = true;
ret = false;
}
}
if (disTop > viewRadius && disBottom > viewRadius
&& (disTop + disBottom) < screenHeigh+ viewRadius / 2)
{
//说明中心点还在屏内,那说是表示x轴已经不在在拖动
offset.z = 0;
newPos.z = viewCenter.z;
target.position = newPos;
limitOffset.y = 0;
}
else
{
if (disTop > viewRadius && disBottom > viewRadius
&& (disTop + disBottom) > screenHeigh + viewRadius
&& disTop > disBottom)
{
offset.z = 0;
limitOffset.y = 1;
isLimitDisplayView = true;
ret = false;
}
else if (disTop > viewRadius && disBottom > viewRadius
&& (disTop + disBottom) > screenHeigh + viewRadius
&& disTop <= disBottom)
{
offset.z = 0;
limitOffset.y = -1;
isLimitDisplayView = true;
ret = false;
}
else if (disTop > viewRadius)
{
offset.z = 0;
limitOffset.y = 1;
isLimitDisplayView = true;
ret = false;
}
else if (disBottom > viewRadius)
{
offset.z = 0;
limitOffset.y = -1;
isLimitDisplayView = true;
ret = false;
}
}
if (!isLimitDisplayView) {
LateUpdate ();
}
return ret;
}
///
/// Apply the dragging momentum.
///
void LateUpdate ()
{
#if UNITY_EDITOR
if (!Application.isPlaying)
return;
#endif
if (target == null)
return;
float delta = RealTime.deltaTime;
mMomentum -= mScroll;
mScroll = NGUIMath.SpringLerp (mScroll, Vector3.zero, 20f, delta);
// No momentum? Exit.
if (mMomentum.magnitude > 0.0001f) {
if (!mPressed) {
// Apply the momentum
Move (NGUIMath.SpringDampen (ref mMomentum, 9f, delta));
if (dragEffect == DragEffect.None) {
CancelMovement ();
} else {
CancelSpring ();
}
// Dampen the momentum
NGUIMath.SpringDampen (ref mMomentum, 9f, delta);
// Cancel all movement (and snap to pixels) at the end
if (mMomentum.magnitude < 0.0001f) {
CancelMovement ();
Utl.doCallback (onEndDragMoveDelegate);
}
} else {
NGUIMath.SpringDampen (ref mMomentum, 9f, delta);
}
}
}
///
/// Cancel all movement.
///
public void CancelMovement ()
{
mMomentum = Vector3.zero;
mScroll = Vector3.zero;
}
///
/// Cancel the spring movement.
///
public void CancelSpring ()
{
SpringPosition sp = target.GetComponent ();
if (sp != null)
sp.enabled = false;
}
///
/// If the object should support the scroll wheel, do it.
///
void OnScroll (float delta)
{
if (enabled && NGUITools.GetActive (gameObject))
mScroll -= scrollMomentum * (delta * 0.05f);
}
}
}