unity 扩展方法

标签: unity 扩展
10人阅读 评论(0) 收藏 举报
分类:


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

public static class QGlobalFunction
{
    public static readonly Vector2 Vector2Center = new Vector2(0.5f, 0.5f);
    public static readonly Vector3 Vector3Center = new Vector3(0.5f, 0.5f, 0.5f);

    /// <summary>
    /// 2D旋转矩阵
    /// </summary>
    /// <param name="mat"></param>
    /// <param name="angle"></param>
    /// <returns></returns>
    public static Matrix4x4 Rotate2D(this Matrix4x4 mat, float angle)
    {
        angle = angle * Mathf.Deg2Rad;
        mat.m00 = Mathf.Cos(angle);
        mat.m01 = Mathf.Sin(angle);
        mat.m10 = -Mathf.Sin(angle);
        mat.m11 = Mathf.Cos(angle);
        return mat;
    }

    /// <summary>
    /// UV旋转
    /// </summary>
    /// <param name="mesh"></param>
    /// <param name="angle"></param>
    /// <param name="channelIndex"></param>
    /// <returns></returns>
    public static Mesh RotateUV(this Mesh mesh, float angle, int channelIndex = 0)
    {
        List<Vector2> uvs = new List<Vector2>(mesh.uv);

        var mat = Rotate2D(new Matrix4x4(), angle);

        for (int i = 0; i < uvs.Count; i++)
        {
            Vector2 uv = uvs[i] - Vector2Center;
            uv = (mat * uv);
            uv += Vector2Center;
            uvs[i] = uv;
        }
        mesh.SetUVs(channelIndex, uvs);
        return mesh;
    }

    /// <summary>
    /// 纹理分割
    /// </summary>
    /// <param name="target"></param>
    /// <param name="rect"></param>
    /// <returns></returns>
    public static Texture2D TextureClipRect(Texture2D target, RectInt rect)
    {
        var width = rect.width;
        var height = rect.height;

        if(rect.x + rect.width >= target.width) width = target.width - rect.x;
        if(rect.y + rect.height >= target.height) height = target.height - rect.y;

        var result = new Texture2D(width,height);
        var data = target.GetPixels(rect.x,rect.y,width,height);
        result.SetPixels(data);
        result.Apply();

        return result;
    }

    /// <summary>
    /// 绘制矩形
    /// </summary>
    /// <param name="target"></param>
    /// <param name="result"></param>
    /// <param name="rect"></param>
    /// <param name="color"></param>
    public static void DrawRect(Texture2D target, ref Texture2D result, RectInt rect, Color color)
    {
        var data = target.GetPixels();
        var width = target.width;
        var offsetWidth = rect.width - rect.x;
        var offsetHeight = rect.height - rect.y;

        if (offsetWidth >= offsetHeight)
        {
            offsetWidth = rect.x + rect.width;
            offsetHeight = rect.y + rect.height;
            if (offsetWidth > width) offsetWidth = width;
            if (offsetHeight > target.height) offsetHeight = target.height;
            for (int y = rect.y; y < offsetHeight; y++)
            {
                for (int x = rect.x; x < offsetWidth; x++)
                {
                    data[y * width + x] = color;
                }
            }
        }
        else
        {
            offsetWidth = rect.x + rect.width;
            offsetHeight = rect.y + rect.height;
            if (offsetWidth > width) offsetWidth = width;
            if (offsetHeight > target.height) offsetHeight = target.height;
            for (int x = rect.x; x < offsetWidth; x++)
            {
                for (int y = rect.y; y < offsetHeight; y++)
                {
                    data[y * width + x] = color;
                }
            }
        }
        result.SetPixels(data);
        result.Apply();
    }

    /// <summary>
    /// 绘制矩形
    /// </summary>
    /// <param name="target"></param>
    /// <param name="result"></param>
    /// <param name="rect"></param>
    /// <param name="coefficient"></param>
    public static void DrawRect(Texture2D target, ref Texture2D result, RectInt rect, float coefficient)
    {
        var data = target.GetPixels();
        var width = target.width;
        var offsetWidth = rect.width - rect.x;
        var offsetHeight = rect.height - rect.y;
        Color color;

        var w = rect.x + rect.width;
        var h = rect.y + rect.height;
        if (w > width) w = width;
        if (h > target.height) h = target.height;

        if (offsetWidth >= offsetHeight)
        {
            offsetWidth = rect.x + rect.width;
            offsetHeight = rect.y + rect.height;
            if (offsetWidth > width) offsetWidth = width;
            if (offsetHeight > target.height) offsetHeight = target.height;
            for (int y = rect.y; y < h; y++)
            {
                for (int x = rect.x; x < w; x++)
                {
                    color = data[y * width + x];
                    data[y * width + x] = new Color(color.r * coefficient, color.g * coefficient, color.b * coefficient, color.a);
                }
            }
        }
        else
        {
            offsetWidth = rect.x + rect.width;
            offsetHeight = rect.y + rect.height;
            if (offsetWidth > width) offsetWidth = width;
            if (offsetHeight > target.height) offsetHeight = target.height;
            for (int x = rect.x; x < w; x++)
            {
                for (int y = rect.y; y < h; y++)
                {
                    color = data[y * width + x];
                    data[y * width + x] = new Color(color.r * coefficient, color.g * coefficient, color.b * coefficient, color.a);
                }
            }
        }
        result.SetPixels(data);
        result.Apply();
    }

    /// <summary>
    /// 交换值
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    public static void Swap<T>(ref T a, ref T b)
    {
        var tmp = a;
        a = b;
        b = tmp;
    }

    /// <summary>
    /// 绘制直角三角形
    /// </summary>
    /// <param name="target"></param>
    /// <param name="result"></param>
    /// <param name="color"></param>
    /// <param name="p1"></param>
    /// <param name="p2"></param>
    /// <param name="p3"></param>
    public static void DrawRightAngleTriangle(Texture2D target, ref Texture2D result, Color color, Vector2Int p1, Vector2Int p2, Vector2Int p3)
    {
        var data = target.GetPixels();
        var width = target.width;

        #region 确定 p3
        if (p1.y < p2.y) QGlobalFunction.Swap(ref p1, ref p2);
        if (p2.y < p3.y) QGlobalFunction.Swap(ref p2, ref p3);
        #endregion

        #region 确定 p2
        if (p1.x < p2.x) QGlobalFunction.Swap(ref p1, ref p2);
        #endregion

        int count = 0;
        Vector2Int[] pos = null;
        if (p1.x == p3.x)
        {
            if (p2.y == p3.y)
            {
                pos = GetBLinePoints(p2, p1);
            }

            else
            {
                pos = GetBLinePoints(p2, p3);
            }
            Debug.Log(p1 + "" + p2 + p3);

            for (int i = 0; i < pos.Length; i++)
            {
                count = p1.x - pos[i].x;
                while (count-- != 0)
                {
                    data[pos[i].y * width + pos[i].x + count] = color;
                }
            }
        }
        else
        {
            if (p1.y == p3.y)
                pos = GetBLinePoints(p1, p2);
            else
                pos = GetBLinePoints(p1, p3);
            for (int i = 0; i < pos.Length; i++)
            {
                count = pos[i].x - p2.x;
                while (count-- != 0)
                {
                    data[pos[i].y * width + count + p2.x] = color;
                }
            }
        }

        result.SetPixels(data);
        result.Apply();
    }

    public static void DrawRightAngleTriangleTest(Texture2D target, ref Texture2D result)
    {
        var center = target.height/2;
        DrawRightAngleTriangle(target, ref result, Color.green, new Vector2Int(0, 0), new Vector2Int(0, center), new Vector2Int(target.width, center));
        DrawRightAngleTriangle(result, ref result, Color.blue, new Vector2Int(0, 0), new Vector2Int(target.width-1, 0), new Vector2Int(target.width-1, center));
        DrawRightAngleTriangle(result, ref result, Color.red, new Vector2Int(0, center+1), new Vector2Int(0, target.height-1), new Vector2Int(target.width, target.height-1));
        DrawRightAngleTriangle(result, ref result, Color.black, new Vector2Int(0, center+1), new Vector2Int(target.width-1, center+1), new Vector2Int(target.width-1, target.height-1));
    }

    /// <summary>
    /// 绘制直角三角形
    /// </summary>
    /// <param name="target"></param>
    /// <param name="result"></param>
    /// <param name="coefficient">系数</param>
    /// <param name="p1"></param>
    /// <param name="p2"></param>
    /// <param name="p3"></param>
    public static void DrawRightAngleTriangle(Texture2D target, ref Texture2D result, float coefficient, Vector2Int p1, Vector2Int p2, Vector2Int p3)
    {
        var data = target.GetPixels();
        var width = target.width;

        #region 确定 p3
        if (p1.y < p2.y) Swap(ref p1, ref p2);
        if (p2.y < p3.y) Swap(ref p2, ref p3);
        #endregion

        #region 确定 p2
        if (p1.x < p2.x) Swap(ref p1, ref p2);
        #endregion

        int count = 0;
        Vector2Int[] pos = null;
        Color color;
        int index;

        if (p1.x == p3.x)
        {
            if (p2.y == p3.y)
            {
                Debug.Log(123 + "" + p1 + p2 + p3);
                pos = GetBLinePoints(p2, p1);
            }

            else
            {
                Debug.Log(233 + "" + p1 + p2 + p3);
                pos = GetBLinePoints(p2, p3);
            }

            for (int i = 0; i < pos.Length; i++)
            {
                count = p1.x - pos[i].x;
                while (count-- != 0)
                {
                    index = pos[i].y * width + pos[i].x + count;
                    color = data[index];
                    data[index] = new Color(color.r * coefficient, color.g * coefficient, color.b * coefficient, color.a);
                }
            }
        }
        else
        {
            if (p1.y == p3.y)
                pos = GetBLinePoints(p1, p2);
            else
                pos = GetBLinePoints(p1, p3);
            for (int i = 0; i < pos.Length; i++)
            {
                count = pos[i].x - p2.x;
                while (count-- != 0)
                {
                    index = pos[i].y * width + count + p2.x;
                    color = data[index];
                    data[index] = new Color(color.r * coefficient, color.g * coefficient, color.b * coefficient, color.a);
                }
            }
        }

        result.SetPixels(data);
        result.Apply();
    }

    /// <summary>
    /// 获得直线坐标
    /// </summary>
    /// <param name="point0"></param>
    /// <param name="point1"></param>
    /// <returns></returns>
    public static Vector2Int[] GetBLinePoints(Vector2Int point0, Vector2Int point1)
    {
        var points = new List<Vector2Int>();
        int x0 = (int)point0.x;
        int y0 = (int)point0.y;
        int x1 = (int)point1.x;
        int y1 = (int)point1.y;

        var dx = Math.Abs(x1 - x0);
        var dy = Math.Abs(y1 - y0);
        var sx = (x0 < x1) ? 1 : -1;
        var sy = (y0 < y1) ? 1 : -1;
        var err = dx - dy;
        int err2;

        while (true)
        {
            points.Add(new Vector2Int(x0, y0));
            if ((x0 == x1) && (y0 == y1))
            {
                break;
            }

            err2 = 2 * err;

            if (err2 + dy > 0)
            {
                x0 += sx;
                err -= dy;
            }

            if (err2 - dx < 0)
            {
                y0 += sy;
                err += dx;
            }
        }
        return points.ToArray();

    }

    /// <summary>
    /// 绘制直线
    /// </summary>
    /// <param name="result"></param>
    /// <param name="width"></param>
    /// <param name="color"></param>
    /// <param name="point0"></param>
    /// <param name="point1"></param>
    public static void DrawBLine(ref Color[] result, int width, Color color, Vector2 point0, Vector2 point1)
    {
        int x0 = (int)point0.x;
        int y0 = (int)point0.y;
        int x1 = (int)point1.x;
        int y1 = (int)point1.y;

        var dx = Math.Abs(x1 - x0);
        var dy = Math.Abs(y1 - y0);
        var sx = (x0 < x1) ? 1 : -1;
        var sy = (y0 < y1) ? 1 : -1;
        var err = dx - dy;
        int err2;

        while (true)
        {
            result[x0 + y0 * width] = color;
            if ((x0 == x1) && (y0 == y1))
            {
                break;
            }

            err2 = 2 * err;

            if (err2 + dy > 0)
            {
                x0 += sx;
                err -= dy;
            }

            if (err2 - dx < 0)
            {
                y0 += sy;
                err += dx;
            }
        }
    }
}

查看评论

unity中扩展方法的简单使用

我们在做项目的时候有些时候会遇到这种情况,使用别人封装的方法,但是又觉得方法没有自己所需求的,或者不是自己想要得,还有一种情况就是当你去接收别人的项目的时候,需要做修改而不能变动以前代码的时候,可能就...
  • gzw187327
  • gzw187327
  • 2016-08-13 23:02:31
  • 1106

Unity3D-C#扩展方法

什么是扩展方法?   扩展方法从字面上理解是指扩展的方法,而对应到面向对象编程这个格局中则是指为一个类提供的扩展方法。按照我们通常的理解,我们首先需要获得某个类的源代码,然后在这个类代码中增加成员方...
  • wsc122181582
  • wsc122181582
  • 2015-12-19 12:16:38
  • 1464

unity-扩展类的方法

再不使用继承的方式的情况下,扩展引擎类的方法 也是看了 DOTween 插件,才知道原来可以这样扩展引擎类。 一个 DOTween api的使用transform.DOMoveX(10, 3f).O...
  • yangxuan0261
  • yangxuan0261
  • 2016-10-12 14:25:39
  • 848

unity 系统类的扩展方法

扩展系统类,自定义编辑器。
  • Testiness_Wind
  • Testiness_Wind
  • 2018-03-01 18:03:24
  • 40

Unity3d的C#扩展方法Extension methods应用吧

扩展方法的条件:必须声明为静态类必须声明为静态方法方法的第一个参数为this首先来扩展Unity中的协程Coroutine,using UnityEngine; using System.Collec...
  • u010019717
  • u010019717
  • 2015-04-11 13:07:47
  • 2069

Unity添加自定义拓展方法

通常你会发现你不能修改正在使用的那些类,无论它是基础的数据类型还是已有框架的一部分,它提供的方法让你困苦不堪。不过。。C# 提供了一种巧妙的方式来让你扩充已有的类,也就是我们今天要讲的扩展方法。 ...
  • Shepherdog
  • Shepherdog
  • 2014-04-04 16:26:09
  • 840

Unity之拓展Button:支持双击与长按

Unity之拓展Button:支持双击与长按
  • qq_26999509
  • qq_26999509
  • 2017-08-06 18:32:52
  • 511

Java8新特性 - 虚拟扩展方法

Java8新特性-虚拟扩展方法,为接口中的函数提供了默认实现方法,使得开发者只关注接口中需要的函数和业务需求。...
  • l460133921
  • l460133921
  • 2017-05-07 21:30:32
  • 1287

unity扩展MonoBehaviour

using UnityEngine; using System.Collections.Generic; using System; using System.ComponentModel; ...
  • u014761712
  • u014761712
  • 2016-02-16 16:31:05
  • 931

Unity3D中扩展已有类的方法

这篇文章翻译自:http://unitypatterns.com/extension-methods/ 转载自王选易博客:http://www.cnblogs.com/neverdie/p/39...
  • sakyaer
  • sakyaer
  • 2015-03-16 11:47:50
  • 827
    个人资料
    持之以恒
    等级:
    访问量: 3万+
    积分: 954
    排名: 5万+