【问题标题】:Unity Buttons: non-rectangular shapeUnity Buttons:非矩形
【发布时间】:2020-11-16 21:15:37
【问题描述】:

请查看所附图片以了解我。您可以看到按钮一和按钮二。但不幸的是,按钮总是矩形的,但我希望它是平行四边形。

请帮帮我

【问题讨论】:

    标签: unity3d user-interface assets shapes


    【解决方案1】:

    在您的 Button 源图像中,在您的 Button 组件中,您可以使用 Unity 的 UISprite 默认按钮精灵作为按钮。

    如果您转到您的 Canvas 游戏对象 | Canvas Scaler Component / Reference Pixels Per Unit并增加值,按钮会更圆,如果减少值,按钮会更矩形。

    【讨论】:

    • 这不会回答 OP 的问题,即如何获得不同形状的按钮,而不是它们如何呈现,而是它们如何交互......
    【解决方案2】:

    这已经完成并且仍在工作

    结帐this thread

    设置:

    调整你的形状纹理并制作它

    • 像往常一样的 Sprite(2D 和 UI)
    • MeshType = 全矩形
    • 已启用读/写 = true

    将您的按钮放在Mask 对象下,这样您就有了类似的层次结构

    Canvas
    |---MaskObject1 (with trapez texture)
    |   |---Button1
    |
    |---MaskObject2
        |---Button2
    

    在您的Mask 上有一个附加组件RaycastMask

    脚本如下所示

    using UnityEngine;
    using UnityEngine.UI;
     
    [RequireComponent(typeof(RectTransform))]
    [RequireComponent(typeof(Image))]
    public class RaycastMask : MonoBehaviour, ICanvasRaycastFilter
    {
        private Image _image;
        private Sprite _sprite;
     
        void Start ()
        {
            _image = GetComponent<Image>();
        }
     
        public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera)
        {
            _sprite = _image.sprite;
     
            var rectTransform = (RectTransform)transform;
            Vector2 localPositionPivotRelative;
            RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform) transform, sp, eventCamera, out localPositionPivotRelative);
     
            // convert to bottom-left origin coordinates
            var localPosition = new Vector2(localPositionPivotRelative.x + rectTransform.pivot.x*rectTransform.rect.width,
                localPositionPivotRelative.y + rectTransform.pivot.y*rectTransform.rect.height);
         
            var spriteRect = _sprite.textureRect;
            var maskRect = rectTransform.rect;
     
            var x = 0;
            var y = 0;
            // convert to texture space
            switch (_image.type)
            {
             
                case Image.Type.Sliced:
                {
                    var border = _sprite.border;
                    // x slicing
                    if (localPosition.x < border.x)
                    {
                        x = Mathf.FloorToInt(spriteRect.x + localPosition.x);
                    }
                    else if (localPosition.x > maskRect.width - border.z)
                    {
                        x = Mathf.FloorToInt(spriteRect.x + spriteRect.width - (maskRect.width - localPosition.x));
                    }
                    else
                    {
                        x = Mathf.FloorToInt(spriteRect.x + border.x +
                                             ((localPosition.x - border.x)/
                                             (maskRect.width - border.x - border.z)) *
                                             (spriteRect.width - border.x - border.z));
                    }
                    // y slicing
                    if (localPosition.y < border.y)
                    {
                        y = Mathf.FloorToInt(spriteRect.y + localPosition.y);
                    }
                    else if (localPosition.y > maskRect.height - border.w)
                    {
                        y = Mathf.FloorToInt(spriteRect.y + spriteRect.height - (maskRect.height - localPosition.y));
                    }
                    else
                    {
                        y = Mathf.FloorToInt(spriteRect.y + border.y +
                                             ((localPosition.y - border.y) /
                                             (maskRect.height - border.y - border.w)) *
                                             (spriteRect.height - border.y - border.w));
                    }
                }
                    break;
                case Image.Type.Simple:
                default:
                    {
                        // conversion to uniform UV space
                        x = Mathf.FloorToInt(spriteRect.x + spriteRect.width * localPosition.x / maskRect.width);
                        y = Mathf.FloorToInt(spriteRect.y + spriteRect.height * localPosition.y / maskRect.height);
                    }
                    break;
            }
     
            // destroy component if texture import settings are wrong
            try
            {
                return _sprite.texture.GetPixel(x,y).a > 0;
            }
            catch (UnityException e)
            {
                Debug.LogError("Mask texture not readable, set your sprite to Texture Type 'Advanced' and check 'Read/Write Enabled'");
                Destroy(this);
                return false;
            }
        }
    }
    

    结果看起来像

    【讨论】:

      【解决方案3】:

      您可以通过 1 行代码在您的 Button 上添加新脚本来获得相同的结果:

      1. 在这个脚本中,在Start() 上写:

        GetComponent<Image>().alphaHitTestMinimumThreshold = 0.1f;
        
      2. 但是您需要如上所述更改图像的设置:

        • Sprite(2D 和 UI)
        • MeshType = 全矩形
        • 已启用读/写 = true
      3. 教程链接:https://www.youtube.com/watch?v=8QxN7hQXkO8

      【讨论】:

        猜你喜欢
        • 2019-09-06
        • 1970-01-01
        • 1970-01-01
        • 2012-11-12
        • 1970-01-01
        • 1970-01-01
        • 2010-12-06
        • 2011-04-27
        • 1970-01-01
        相关资源
        最近更新 更多