软件编程
位置:首页>> 软件编程>> C#编程>> Unity3D UGUI实现缩放循环拖动卡牌展示效果

Unity3D UGUI实现缩放循环拖动卡牌展示效果

作者:诗远  发布时间:2022-02-19 10:37:24 

标签:Unity3D,拖动卡牌,缩放卡牌

本文实例为大家分享了Unity3D UGUI实现缩放循环拖动卡牌展示的具体代码,供大家参考,具体内容如下

需求:游戏中展示卡牌这种效果也是蛮酷炫并且使用的一种常见效果,下面我们就来实现以下这个效果是如何实现。 

Unity3D UGUI实现缩放循环拖动卡牌展示效果

思考:第一看看到这个效果,我们首先会想到UGUI里面的ScrollRect,当然也可以用ScrollRect来实现缩短ContentSize的width来自动实现重叠效果,然后中间左右的卡牌通过计算来显示缩放,这里我并没有用这种思路来实现,我提供另外一种思路,就是自己去计算当前每个卡牌的位置和缩放值,不用UGUI的内置组件。

CODE:

1.卡牌拖动组件:


using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public enum DragPosition
{
Left,
Right,
Up,
Down,
}

[RequireComponent(typeof(Image))]
public class CDragOnCard : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
public bool dragOnSurfaces = true;
public ScrollRect m_ScrollRect = null;
public CFixGridRect m_FixGridRect = null;
private RectTransform m_DraggingPlane;

public bool isVertical = false;
private bool isSelf = false;
private DragPosition m_dragPosition = DragPosition.Left;

public System.Action<DragPosition> DragCallBack = null;

public void OnBeginDrag(PointerEventData eventData)
{
 Vector2 touchDeltaPosition = Vector2.zero;
#if UNITY_EDITOR
 float delta_x = Input.GetAxis("Mouse X");
 float delta_y = Input.GetAxis("Mouse Y");
 touchDeltaPosition = new Vector2(delta_x, delta_y);

#elif UNITY_ANDROID || UNITY_IPHONE
touchDeltaPosition = Input.GetTouch(0).deltaPosition;
#endif
 if (isVertical)
 {
  if(touchDeltaPosition.y > 0)
  {
   UnityEngine.Debug.Log("上拖");
   m_dragPosition = DragPosition.Up;
  }
  else
  {
   UnityEngine.Debug.Log("下拖");
   m_dragPosition = DragPosition.Down;
  }

if (Mathf.Abs(touchDeltaPosition.x) > Mathf.Abs(touchDeltaPosition.y))
  {
   isSelf = true;
   var canvas = FindInParents<Canvas>(gameObject);
   if (canvas == null)
    return;

if (dragOnSurfaces)
    m_DraggingPlane = transform as RectTransform;
   else
    m_DraggingPlane = canvas.transform as RectTransform;

}
  else
  {
   isSelf = false;
   if (m_ScrollRect != null)
    m_ScrollRect.OnBeginDrag(eventData);
  }
 }
 else //水平
 {
  if (touchDeltaPosition.x > 0)
  {
   UnityEngine.Debug.Log("右移");
   m_dragPosition = DragPosition.Right;
  }
  else
  {
   UnityEngine.Debug.Log("左移");
   m_dragPosition = DragPosition.Left;
  }

if (Mathf.Abs(touchDeltaPosition.x) < Mathf.Abs(touchDeltaPosition.y))
  {
   isSelf = true;
   var canvas = FindInParents<Canvas>(gameObject);
   if (canvas == null)
    return;

if (dragOnSurfaces)
    m_DraggingPlane = transform as RectTransform;
   else
    m_DraggingPlane = canvas.transform as RectTransform;
  }
  else
  {
   isSelf = false;
   if (m_ScrollRect != null)
    m_ScrollRect.OnBeginDrag(eventData);
  }
 }
}

public void OnDrag(PointerEventData data)
{
 if (isSelf)
 {

}
 else
 {
  if (m_ScrollRect != null)
   m_ScrollRect.OnDrag(data);
 }
}

public void OnEndDrag(PointerEventData eventData)
{
 if (isSelf)
 {

}
 else
 {
  if (m_ScrollRect != null)
   m_ScrollRect.OnEndDrag(eventData);
  if (m_FixGridRect != null)
   m_FixGridRect.OnEndDrag(eventData);
 }

if (DragCallBack != null)
  DragCallBack(m_dragPosition);
}

static public T FindInParents<T>(GameObject go) where T : Component
{
 if (go == null) return null;
 var comp = go.GetComponent<T>();

if (comp != null)
  return comp;

Transform t = go.transform.parent;
 while (t != null && comp == null)
 {
  comp = t.gameObject.GetComponent<T>();
  t = t.parent;
 }
 return comp;
}
}

2.卡牌组件


using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class EnhanceItem : MonoBehaviour
{
// 在ScrollViewitem中的索引
// 定位当前的位置和缩放
public int scrollViewItemIndex = 0;
public bool inRightArea = false;

private Vector3 targetPos = Vector3.one;
private Vector3 targetScale = Vector3.one;

private Transform mTrs;
private Image mImage;

private int index = 1;
public void Init(int cardIndex = 1)
{
 index = cardIndex;
 mTrs = this.transform;
 mImage = this.GetComponent<Image>();
 mImage.sprite = Resources.Load<Sprite>(string.Format("Texture/card_bg_big_{0}", cardIndex % 6 + 1));
 this.gameObject.GetComponent<Button>().onClick.AddListener(delegate () { OnClickScrollViewItem(); });
}

// 当点击Item,将该item移动到中间位置
private void OnClickScrollViewItem()
{
 Debug.LogError("点击" + index);
 EnhancelScrollView.GetInstance().SetHorizontalTargetItemIndex(scrollViewItemIndex);
}

/// <summary>
/// 更新该Item的缩放和位移
/// </summary>
public void UpdateScrollViewItems(float xValue, float yValue, float scaleValue)
{
 targetPos.x = xValue;
 targetPos.y = yValue;
 targetScale.x = targetScale.y = scaleValue;

mTrs.localPosition = targetPos;
 mTrs.localScale = targetScale;
}

public void SetSelectColor(bool isCenter)
{
 if (mImage == null)
  mImage = this.GetComponent<Image>();

if (isCenter)
  mImage.color = Color.white;
 else
  mImage.color = Color.gray;
}
}

3.自定义的ScrollView组件


using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;

public class EnhancelScrollView : MonoBehaviour
{
public AnimationCurve scaleCurve;
public AnimationCurve positionCurve;
public float posCurveFactor = 500.0f;
public float yPositionValue = 46.0f;

public List<EnhanceItem> scrollViewItems = new List<EnhanceItem>();
private List<Image> imageTargets = new List<Image>();

private EnhanceItem centerItem;
private EnhanceItem preCenterItem;

private bool canChangeItem = true;

public float dFactor = 0.2f;

private float[] moveHorizontalValues;
private float[] dHorizontalValues;

public float horizontalValue = 0.0f;
public float horizontalTargetValue = 0.1f;

private float originHorizontalValue = 0.1f;
public float duration = 0.2f;
private float currentDuration = 0.0f;

private static EnhancelScrollView instance;

private bool isInit = false;
public static EnhancelScrollView GetInstance()
{
 return instance;
}

void Awake()
{
 instance = this;
}

public void Init()
{
 if ((scrollViewItems.Count % 2) == 0)
 {
  Debug.LogError("item count is invaild,please set odd count! just support odd count.");
 }

if (moveHorizontalValues == null)
  moveHorizontalValues = new float[scrollViewItems.Count];

if (dHorizontalValues == null)
  dHorizontalValues = new float[scrollViewItems.Count];

if (imageTargets == null)
  imageTargets = new List<Image>();

int centerIndex = scrollViewItems.Count / 2;
 for (int i = 0; i < scrollViewItems.Count; i++)
 {
  scrollViewItems[i].scrollViewItemIndex = i;
  Image tempImage = scrollViewItems[i].gameObject.GetComponent<Image>();
  imageTargets.Add(tempImage);

dHorizontalValues[i] = dFactor * (centerIndex - i);

dHorizontalValues[centerIndex] = 0.0f;
  moveHorizontalValues[i] = 0.5f - dHorizontalValues[i];
  scrollViewItems[i].SetSelectColor(false);
 }

//centerItem = scrollViewItems[centerIndex];
 canChangeItem = true;
 isInit = true;
}

public void UpdateEnhanceScrollView(float fValue)
{
 for (int i = 0; i < scrollViewItems.Count; i++)
 {
  EnhanceItem itemScript = scrollViewItems[i];
  float xValue = GetXPosValue(fValue, dHorizontalValues[itemScript.scrollViewItemIndex]);
  float scaleValue = GetScaleValue(fValue, dHorizontalValues[itemScript.scrollViewItemIndex]);
  itemScript.UpdateScrollViewItems(xValue, yPositionValue, scaleValue);
 }
}

void Update()
{
 if (!isInit)
  return;
 currentDuration += Time.deltaTime;
 SortDepth();
 if (currentDuration > duration)
 {
  currentDuration = duration;

//if (centerItem != null)
  //{
  // centerItem.SetSelectColor(true);
  //}

if (centerItem == null)
  {
   var obj = transform.GetChild(transform.childCount - 1);
   if (obj != null)
    centerItem = obj.GetComponent<EnhanceItem>();
   if (centerItem != null)
    centerItem.SetSelectColor(true);
  }
  else
   centerItem.SetSelectColor(true);
  if (preCenterItem != null)
   preCenterItem.SetSelectColor(false);
  canChangeItem = true;
 }

float percent = currentDuration / duration;
 horizontalValue = Mathf.Lerp(originHorizontalValue, horizontalTargetValue, percent);
 UpdateEnhanceScrollView(horizontalValue);
}

private float GetScaleValue(float sliderValue, float added)
{
 float scaleValue = scaleCurve.Evaluate(sliderValue + added);
 return scaleValue;
}

private float GetXPosValue(float sliderValue, float added)
{
 float evaluateValue = positionCurve.Evaluate(sliderValue + added) * posCurveFactor;
 return evaluateValue;
}

public void SortDepth()
{
 imageTargets.Sort(new CompareDepthMethod());
 for (int i = 0; i < imageTargets.Count; i++)
  imageTargets[i].transform.SetSiblingIndex(i);
}

public class CompareDepthMethod : IComparer<Image>
{
 public int Compare(Image left, Image right)
 {
  if (left.transform.localScale.x > right.transform.localScale.x)
   return 1;
  else if (left.transform.localScale.x < right.transform.localScale.x)
   return -1;
  else
   return 0;
 }
}

private int GetMoveCurveFactorCount(float targetXPos)
{
 int centerIndex = scrollViewItems.Count / 2;
 for (int i = 0; i < scrollViewItems.Count; i++)
 {
  float factor = (0.5f - dFactor * (centerIndex - i));

float tempPosX = positionCurve.Evaluate(factor) * posCurveFactor;
  if (Mathf.Abs(targetXPos - tempPosX) < 0.01f)
   return Mathf.Abs(i - centerIndex);
 }
 return -1;
}

public void SetHorizontalTargetItemIndex(int itemIndex)
{
 if (!canChangeItem)
  return;

EnhanceItem item = scrollViewItems[itemIndex];
 if (centerItem == item)
  return;

canChangeItem = false;
 preCenterItem = centerItem;
 centerItem = item;

float centerXValue = positionCurve.Evaluate(0.5f) * posCurveFactor;
 bool isRight = false;
 if (item.transform.localPosition.x > centerXValue)
  isRight = true;

int moveIndexCount = GetMoveCurveFactorCount(item.transform.localPosition.x);
 if (moveIndexCount == -1)
 {
  moveIndexCount = 1;
 }

float dvalue = 0.0f;
 if (isRight)
  dvalue = -dFactor * moveIndexCount;
 else
  dvalue = dFactor * moveIndexCount;

horizontalTargetValue += dvalue;
 currentDuration = 0.0f;
 originHorizontalValue = horizontalValue;
}

public void OnBtnRightClick()
{
 if (!canChangeItem)
  return;
 int targetIndex = centerItem.scrollViewItemIndex + 1;
 if (targetIndex > scrollViewItems.Count - 1)
  targetIndex = 0;
 SetHorizontalTargetItemIndex(targetIndex);
}

public void OnBtnLeftClick()
{
 if (!canChangeItem)
  return;
 int targetIndex = centerItem.scrollViewItemIndex - 1;
 if (targetIndex < 0)
  targetIndex = scrollViewItems.Count - 1;
 SetHorizontalTargetItemIndex(targetIndex);
}
}

上面的代码好像不能用 我自己写了两种方法

1  使用 Scroll View 实现效果如下

Unity3D UGUI实现缩放循环拖动卡牌展示效果

Unity3D UGUI实现缩放循环拖动卡牌展示效果

代码如下


public int totalItemNum;//共有几个单元格

public int currentIndex;//当前单元格的索引

private float bilv ;

public float currentBilv = 0;

private void Awake()
{
 scrollRect = GetComponent<ScrollRect>();

scrollRect.horizontalNormalizedPosition =0;
}
// Use this for initialization
void Start () {
Button[] button = scrollRect.content.GetComponentsInChildren<Button>();
totalItemNum= button.Length;
bilv = 1 / (totalItemNum - 1.00f);

}
public void OnBeginDrag(PointerEventData eventData)
{

beginMousePositionX = Input.mousePosition.x;
}

public void OnEndDrag(PointerEventData eventData)
{

float offSetX = 0;
endMousePositionX = Input.mousePosition.x;

offSetX = beginMousePositionX - endMousePositionX;

if (Mathf.Abs(offSetX)>firstItemLength)
{
 if (offSetX>0)
 {
 //当前的单元格大于等于单元格的总个数
 if (currentIndex >= totalItemNum-1 )
 {
  Debug.Log("左滑动-------");
  return;
 }
 currentIndex += 1;
 scrollRect.DOHorizontalNormalizedPos(currentBilv += bilv, 0.2f);

Debug.Log("左滑动");
 }
 else
 {
 Debug.Log("右滑动");
 //当前的单元格大于等于单元格的总个数
 if ( currentIndex < 1)
 {
  return;
 }
 currentIndex -= 1;
 scrollRect.DOHorizontalNormalizedPos(currentBilv -= bilv, 0.2f);

}
}

}

Unity3D UGUI实现缩放循环拖动卡牌展示效果


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using UnityEngine.UI;

public class ThreePage1 : MonoBehaviour {
public GameObject[] images;
int currentIndex;
public float DistancesNum = 250;
public float min = 0.8f;
public float max = 1.4f;

public float speed = 0.2f;
public float Alpha = 0.8f;

void Start () {
InitRectTranform();
}
public void InitRectTranform()
{
currentIndex = images.Length / 2;
for (int i = currentIndex + 1; i < images.Length; i++)
{
 images[i].GetComponent<RectTransform>().anchoredPosition = new Vector3((i - currentIndex) * DistancesNum, 0, 0);
}
int num = 0;
for (int i = currentIndex; i >= 0; i--)
{
 images[i].GetComponent<RectTransform>().anchoredPosition = new Vector3(-num * DistancesNum, 0, 0);
 num++;
}
foreach (var item in images)
{
 if (item != images[currentIndex])
 {
 item.GetComponent<RectTransform>().localScale = new Vector3(min, min);
 item.GetComponent<Image>().color = new Color(1, 1, 1, Alpha);
 }
 else
 {
 item.GetComponent<RectTransform>().localScale = new Vector3(max, max);
 }
}
}
public void Left()
{

ButtonManager._Instances.PlayInput();

OnLeftButtonClick();
}

public void OnLeftButtonClick()
{

if (currentIndex < images.Length-1)
{
 foreach (GameObject item in images)
 {
 (item.GetComponent<RectTransform>()).DOAnchorPosX(item.GetComponent<RectTransform>().anchoredPosition.x- DistancesNum, speed);
 }
 images[currentIndex].GetComponent<Image>().color = new Color(1, 1, 1, Alpha);
 images[currentIndex].GetComponent<RectTransform>().DOScale(min, speed);
 currentIndex += 1;
 images[currentIndex].GetComponent<RectTransform>().DOScale(max, speed);
 images[currentIndex].GetComponent<Image>().color = new Color(1, 1, 1, 1f);
}
}

public void Right()
{

ButtonManager._Instances.PlayInput();

OnRightButtonClick();
}

public void OnRightButtonClick()
{

if (currentIndex > 0)
{
 foreach (GameObject item in images)
 {
 (item.GetComponent<RectTransform>()).DOAnchorPosX(item.GetComponent<RectTransform>().anchoredPosition.x + DistancesNum, speed);
 }
 images[currentIndex].GetComponent<RectTransform>().DOScale(min, speed);
 images[currentIndex].GetComponent<Image>().color = new Color(1, 1, 1, Alpha);
 currentIndex -= 1;
 images[currentIndex].GetComponent<RectTransform>().DOScale(max, speed);
 images[currentIndex].GetComponent<Image>().color = new Color(1, 1, 1, 1f);
}
}

private void OnEnable()
{
isOn = true;
timess = 0;
//jarodInputController.IsShiYong = true;
}

private void OnDisable()
{
InitRectTranform();
jarodInputController.IsShiYong = false;
}
}

来源:https://blog.csdn.net/qq_36848370/article/details/82800849

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com