public override void OnInspectorGUI() { EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_Layout); EditorGUILayout.PropertyField(m_PolygonSplitLength); EditorGUILayout.PropertyField(m_Radius); EditorGUI.EndChangeCheck(); serializedObject.ApplyModifiedProperties(); EditorGUILayout.Separator(); EditorGUILayout.HelpBox("Children's Graphic Component needs attachment of EffectComponent.\nWhen EffectComponent isn't attached, it doesn't curve.", MessageType.Info); if (GUILayout.Button("EffectComponent is added to all children's Graphic Component.")) { foreach (Object target in targets) { WheelEffect3D effect = target as WheelEffect3D; if (effect != null) { effect.SetEffectComponentToAllChildGraphics(); } } } }
protected void SetLayout(int axis) { if (scrollRect == null || scrollRect.layout != (RectTransform.Axis)axis || !Application.isPlaying) { return; } int itemCount = this.itemCount; if (itemCount <= 0 || scrollRect.itemSource == null) { foreach (MassivePickerItem item in m_Items.Values) { ReleaseItemObject(item); } m_Items.Clear(); return; } if (m_ChangedItemSource) { ClearAlreadyItems(); m_ChangedItemSource = false; } RectTransform rectTransform = this.rectTransform; Vector2 position = rectTransform.anchoredPosition; float itemSize = m_ItemSize[axis]; float spacing = this.spacing; Vector2 windowSize = scrollRect.windowSize; bool wheel = scrollRect.wheelEffect; float direction = (axis == (int)RectTransform.Axis.Horizontal ? 1f : -1f); WheelEffect3D wheelEffect3D = GetComponentInParent <WheelEffect3D>(); if (wheelEffect3D != null) { if (wheelEffect3D.IsActive() && (int)wheelEffect3D.layout == axis) { wheel = true; } else { wheelEffect3D = null; } } Vector2 areaSize = rectTransform.sizeDelta; areaSize[axis] = scrollRect.windowSize[axis] + (itemSize + spacing) * (itemCount - 1); if (rectTransform.sizeDelta != areaSize) { rectTransform.sizeDelta = areaSize; } int beginIndex = 0, endIndex = itemCount - 1; if (itemCount >= 3) { float range = !wheel ? windowSize[axis] * 0.5f : windowSize[axis] * 0.25f * Mathf.PI; int centerIndex = PositionToNearItemIndex(-position[axis]); int indexRange = Mathf.CeilToInt(range / (itemSize + spacing)); indexRange = Mathf.Min(indexRange, itemCount / 2); if (indexRange + indexRange + 1 >= itemCount) { beginIndex = 0; endIndex = itemCount - 1; } else { if (scrollRect.infiniteScroll) { beginIndex = (centerIndex - indexRange + itemCount) % itemCount; endIndex = (centerIndex + indexRange + itemCount) % itemCount; if (beginIndex == endIndex) { beginIndex = 0; endIndex = itemCount - 1; } } else { beginIndex = System.Math.Max(0, centerIndex - indexRange); endIndex = System.Math.Min(itemCount - 1, centerIndex + indexRange); } } } else { beginIndex = 0; endIndex = itemCount - 1; } ShrinkItem(beginIndex, endIndex); float scrollOffset = position[axis]; float pivot = m_ChildPivot - 0.5f; if (!wheel) { while (true) { MassivePickerItem item = GetItem(beginIndex); RectTransform itemRect = item.rectTransform; Vector3 itemPosition = itemRect.localPosition; itemPosition[axis] = -IndexToPosition(beginIndex); Vector2 center = itemRect.rect.center; float itemPivot = itemRect.pivot[1 - axis] - 0.5f; float itemAnchorMin = itemRect.anchorMin[1 - axis]; float itemAnchorMax = itemRect.anchorMax[1 - axis]; float revision = (itemPivot * (itemAnchorMax - itemAnchorMin) + (itemAnchorMax + itemAnchorMin - 1) * 0.5f) * windowSize[1 - axis]; itemPosition[1 - axis] = (windowSize[1 - axis] - itemRect.rect.size[1 - axis]) * pivot - center[1 - axis] - revision; itemPosition.z = 0; itemRect.localPosition = itemPosition; if (itemRect.localScale != Vector3.one) { itemRect.localScale = Vector3.one; } if (itemRect.localRotation != Quaternion.identity) { itemRect.localRotation = Quaternion.identity; } if (beginIndex == endIndex) { break; } beginIndex = (beginIndex + 1) % itemCount; } } else { float perspective = m_ScrollRect.wheelPerspective; float wheelRadius = windowSize[axis] * 0.5f; float circumference = (wheelRadius + wheelRadius) * Mathf.PI; float offsetToRad = (Mathf.PI + Mathf.PI) / circumference * -direction; while (true) { MassivePickerItem item = GetItem(beginIndex); RectTransform itemRect = item.rectTransform; float rad = (IndexToPosition(beginIndex) - scrollOffset) * offsetToRad; if (Mathf.Abs(rad) < Mathf.PI * 0.5f) { if (wheelEffect3D == null) { float scale = Mathf.Cos(rad); float scale2 = (1 - perspective) + scale * perspective; Vector3 localScale = itemRect.localScale; localScale[axis] = scale; localScale[1 - axis] = scale2; itemRect.localScale = localScale; Vector3 itemPosition = itemRect.anchoredPosition; Vector2 center = itemRect.rect.center; itemPosition[axis] = Mathf.Sin(-rad) * wheelRadius * -direction - scrollOffset - center[axis] * scale; float itemPivot = itemRect.pivot[1 - axis] - 0.5f; float itemAnchorMin = itemRect.anchorMin[1 - axis]; float itemAnchorMax = itemRect.anchorMax[1 - axis]; float revision = (itemPivot * (itemAnchorMax - itemAnchorMin) + (itemAnchorMax + itemAnchorMin - 1) * 0.5f) * windowSize[1 - axis]; itemPosition[1 - axis] = (windowSize[1 - axis] - itemRect.rect.size[1 - axis] * scale2) * pivot - center[1 - axis] * scale2 - revision; itemPosition.z = 0; itemRect.localPosition = itemPosition; if (itemRect.localRotation != Quaternion.identity) { itemRect.localRotation = Quaternion.identity; } } else { Vector3 itemPosition = itemRect.anchoredPosition; Vector2 center = itemRect.rect.center; itemPosition[axis] = Mathf.Sin(-rad) * wheelRadius * -direction - scrollOffset - center[axis]; Vector3 eulerAngles = itemRect.localRotation.eulerAngles; eulerAngles[1 - axis] = rad * -Mathf.Rad2Deg * direction; itemRect.localRotation = Quaternion.Euler(eulerAngles); float itemPivot = itemRect.pivot[1 - axis] - 0.5f; float itemAnchorMin = itemRect.anchorMin[1 - axis]; float itemAnchorMax = itemRect.anchorMax[1 - axis]; float revision = (itemPivot * (itemAnchorMax - itemAnchorMin) + (itemAnchorMax + itemAnchorMin - 1) * 0.5f) * windowSize[1 - axis]; itemPosition[1 - axis] = (windowSize[1 - axis] - itemRect.rect.size[1 - axis]) * pivot - center[1 - axis] - revision; itemPosition.z = wheelRadius - Mathf.Cos(rad) * wheelRadius; itemRect.localPosition = itemPosition; if (itemRect.localScale != Vector3.one) { itemRect.localScale = Vector3.one; } } } else { Vector3 scale = itemRect.localScale; if (scale.x != 0 || scale.y != 0) { scale.x = 0; scale.y = 0; itemRect.localScale = scale; } } if (beginIndex == endIndex) { break; } beginIndex = (beginIndex + 1) % itemCount; } } if (scrollRect != null && Application.isPlaying) { scrollRect.SetInitialPosition(); } }
protected virtual void SetLayout(int axis) { if (scrollRect == null) { return; } if (axis != GetAxisIndex()) { return; } if (m_LockSetLayout) { m_DirtyLayout = true; return; } Vector2 scrollAreaSize = GetScrollAreaSize(); m_Tracker.Clear(); rectChildren.Clear(); m_itemOffsetList.Clear(); m_pickerItemList.Clear(); m_childTransformList.Clear(); cacheRect.Clear(); bool infinite = m_ScrollRect.infiniteScroll; bool wheelEffect = m_ScrollRect.wheelEffect; WheelEffect3D wheelEffect3D = GetComponentInParent <WheelEffect3D>(); if (wheelEffect3D != null) { if (wheelEffect3D.IsActive() && (int)wheelEffect3D.layout == axis) { wheelEffect = true; } else { wheelEffect3D = null; } } DrivenTransformProperties childDriven = GetChildPropertyDriven(axis, wheelEffect); float position = (!infinite ? scrollAreaSize[axis] * 0.5f : 0); float scrollSize = position; for (int childIndex = 0; childIndex < rectTransform.childCount; childIndex++) { Transform childTransform = rectTransform.GetChild(childIndex); RectTransform childRectTransform; ItemComponent itemComponent; PickerItem item; if (!m_ChildItemTable.TryGetValue(childTransform, out itemComponent)) { childRectTransform = childTransform as RectTransform; item = childRectTransform.GetComponent <PickerItem>(); m_ChildItemTable[childTransform] = new ItemComponent() { item = item, rectTransform = childRectTransform }; } else { childRectTransform = itemComponent.rectTransform; item = itemComponent.item; } if (item == null || !item.enabled || !childRectTransform.gameObject.activeInHierarchy) { continue; } rectChildren.Add(childRectTransform); m_pickerItemList.Add(item); m_itemOffsetList.Add(0); m_childTransformList.Add(childRectTransform); m_Tracker.Add(this, childRectTransform, childDriven); { Vector2 anchorMin = childRectTransform.anchorMin; if (anchorMin[axis] != 0.5f) { anchorMin[axis] = 0.5f; childRectTransform.anchorMin = anchorMin; } Vector2 anchorMax = childRectTransform.anchorMax; if (anchorMax[axis] != 0.5f) { anchorMax[axis] = 0.5f; childRectTransform.anchorMax = anchorMax; } } Rect rect = childRectTransform.rect; cacheRect.Add(rect); float size = rect.size[axis]; scrollSize += spacing + size; } if (m_childTransformList.Count > 0 && !infinite) { float size = m_childTransformList[0].rect.size[axis]; position -= size * 0.5f; scrollSize -= size * 0.5f; size = m_childTransformList[m_childTransformList.Count - 1].rect.size[axis]; scrollSize -= size * 0.5f; scrollSize -= spacing; } if (!infinite) { float flex = Mathf.Min(scrollSize * 0.002f, 0.1f); scrollSize += scrollAreaSize[axis] * 0.5f + flex + flex; position += flex; } SetContentRectSize(axis, scrollSize); position += scrollSize * -0.5f; float pivot = m_ChildPivot - 0.5f; float direction = (axis == 0 ? 1f : -1f); float wheelPosition = scrollRect.content.localPosition[axis] * -direction; float infiniteOffsetFloor = 0; if (infinite) { infiniteOffsetFloor = Mathf.Floor(wheelPosition / scrollSize) * scrollSize; } if (wheelEffect) { float perspective = m_ScrollRect.wheelPerspective; float wheelRadius = wheelEffect3D != null ? wheelEffect3D.radius : scrollAreaSize[axis] * 0.5f; float circumference = (wheelRadius + wheelRadius) * Mathf.PI; float ru = (Mathf.PI + Mathf.PI) / circumference * direction; for (int childIndex = 0; childIndex < m_childTransformList.Count; ++childIndex) { RectTransform childTransform = m_childTransformList[childIndex]; float size = cacheRect[childIndex].size[axis]; float tmp; if (!infinite) { tmp = position + size * 0.5f; } else { tmp = infiniteOffsetFloor + position + size * 0.5f; if (Mathf.Abs(tmp - wheelPosition) > Mathf.Abs(tmp + scrollSize - wheelPosition)) { tmp += scrollSize; } } position += size + spacing; float rad = (tmp - wheelPosition) * ru; float offset = tmp * direction; m_itemOffsetList[childIndex] = offset; PickerItem item = m_pickerItemList[childIndex]; item.position = -offset; if (Mathf.Abs(rad) < Mathf.PI * 0.5f) { if (wheelEffect3D == null) { float scale = Mathf.Cos(rad); Vector3 localScale = childTransform.localScale; localScale[axis] = scale; float scale2 = (1 - perspective) + scale * perspective; localScale[1 - axis] = scale2; childTransform.localScale = localScale; Vector2 center = cacheRect[childIndex].center; Vector3 childPosition = Vector2.zero; childPosition[axis] = Mathf.Sin(rad) * wheelRadius + wheelPosition * direction - center[axis] * scale; float childPivot = childTransform.pivot[1 - axis] - 0.5f; float childAnchorMin = childTransform.anchorMin[1 - axis]; float childAnchorMax = childTransform.anchorMax[1 - axis]; float revision = (childPivot * (childAnchorMax - childAnchorMin) + (childAnchorMax + childAnchorMin - 1) * 0.5f) * scrollAreaSize[1 - axis]; childPosition[1 - axis] = (scrollAreaSize[1 - axis] - cacheRect[childIndex].size[1 - axis] * scale2) * pivot - center[1 - axis] * scale2 - revision; childPosition.z = 0; childTransform.localPosition = childPosition; if (childTransform.localRotation != Quaternion.identity) { childTransform.localRotation = Quaternion.identity; } } else { Vector2 center = cacheRect[childIndex].center; Vector3 childPosition = Vector3.zero; childPosition[axis] = Mathf.Sin(rad) * wheelRadius + wheelPosition * direction - center[axis]; Vector3 eulerAngles = childTransform.localRotation.eulerAngles; eulerAngles[1 - axis] = rad * -Mathf.Rad2Deg * direction; childTransform.localRotation = Quaternion.Euler(eulerAngles); float childPivot = childTransform.pivot[1 - axis] - 0.5f; float childAnchorMin = childTransform.anchorMin[1 - axis]; float childAnchorMax = childTransform.anchorMax[1 - axis]; float revision = (childPivot * (childAnchorMax - childAnchorMin) + (childAnchorMax + childAnchorMin - 1) * 0.5f) * scrollAreaSize[1 - axis]; childPosition[1 - axis] = (scrollAreaSize[1 - axis] - cacheRect[childIndex].size[1 - axis]) * pivot - center[1 - axis] - revision; childPosition.z = wheelRadius - Mathf.Cos(rad) * wheelRadius; if (childTransform.localScale != Vector3.one) { childTransform.localScale = Vector3.one; } childTransform.localPosition = childPosition; } } else { Vector3 scale = childTransform.localScale; if (scale.x != 0 || scale.y != 0) { scale.x = 0; scale.y = 0; childTransform.localScale = scale; } } } } else { for (int childIndex = 0; childIndex < m_childTransformList.Count; ++childIndex) { RectTransform childTransform = m_childTransformList[childIndex]; PickerItem item = m_pickerItemList[childIndex]; Rect rect = childTransform.rect; float size = rect.size[axis]; float tmp; if (!infinite) { tmp = position + size * 0.5f; } else { tmp = infiniteOffsetFloor + position + size * 0.5f; if (Mathf.Abs(tmp - wheelPosition) > Mathf.Abs(tmp + scrollSize - wheelPosition)) { tmp += scrollSize; } } float offset = tmp * direction; m_itemOffsetList[childIndex] = offset; item.position = -offset; position += size + spacing; Vector3 childPosition = childTransform.anchoredPosition; childPosition[axis] = tmp * direction - rect.center[axis]; float childPivot = childTransform.pivot[1 - axis] - 0.5f; float childAnchorMin = childTransform.anchorMin[1 - axis]; float childAnchorMax = childTransform.anchorMax[1 - axis]; float revision = (childPivot * (childAnchorMax - childAnchorMin) + (childAnchorMax + childAnchorMin - 1) * 0.5f) * scrollAreaSize[1 - axis]; childPosition[1 - axis] = (scrollAreaSize[1 - axis] - rect.size[1 - axis]) * pivot - rect.center[1 - axis] - revision; childPosition.z = 0; if (childTransform.localPosition != childPosition) { childTransform.localPosition = childPosition; } if (childTransform.localRotation != Quaternion.identity) { childTransform.localRotation = Quaternion.identity; } if (childTransform.localScale != Vector3.one) { childTransform.localScale = Vector3.one; } } } if (direction < 0) { m_itemOffsetList.Reverse(); m_pickerItemList.Reverse(); } int infiniteScrollOffset = 0; if (infinite) { //sort offset & item int i; int count = m_itemOffsetList.Count; if (count > 1) { for (i = 1; i < count; ++i) { if (m_itemOffsetList[i - 1] >= m_itemOffsetList[i]) { break; } } infiniteScrollOffset = i; if (i < count) { if (swapBufferOffset == null || i > swapBufferOffset.Length) { swapBufferOffset = new float[i]; swapBufferItem = new PickerItem[i]; } m_itemOffsetList.CopyTo(0, swapBufferOffset, 0, i); m_pickerItemList.CopyTo(0, swapBufferItem, 0, i); int j; for (j = 0; j + i < count; ++j) { m_itemOffsetList[j] = m_itemOffsetList[j + i]; m_pickerItemList[j] = m_pickerItemList[j + i]; } for (int k = 0; k + j < count; ++k) { m_itemOffsetList[k + j] = swapBufferOffset[k]; m_pickerItemList[k + j] = swapBufferItem[k]; } } } } if (scrollRect != null && Application.isPlaying) { scrollRect.SetInitialPosition(infiniteScrollOffset); } }