• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Unity完美的上色并检测完成度工具

武飞扬头像
努力长头发的程序猿
帮助1

直接将代码放在RawImage上(不能放在Image上面)

附加代码的物体RawImage上面的Texture需要设定为空,然后附加Mask组件,子物体同时需要RawImage组件并设定为需要上色展示的图像,可以忽略透明区域检测上色百分比

需要注意revocations变量不能等于1或者0,否则会进入死循环

用起来如果有卡顿,就改变RawImage的Scale值,Scale越大绘画越流畅

  1.  
    using System;
  2.  
    using System.Collections.Generic;
  3.  
    using UnityEngine;
  4.  
    using UnityEngine.EventSystems;
  5.  
    using UnityEngine.UI;
  6.  
     
  7.  
    public class Painting : MonoBehaviour,IPointerEnterHandler,IPointerExitHandler
  8.  
    {
  9.  
    public Color color;
  10.  
    //radius的值不能等于1和0,不然会进入死循环
  11.  
    public int radius = 5;
  12.  
    private Canvas canvas;
  13.  
    private RawImage mainImage;
  14.  
    private RectTransform mainRect;
  15.  
    private Texture2D texture;
  16.  
    private Texture2D minTexture;
  17.  
    private bool handIn;
  18.  
    private Vector2 lastPos;
  19.  
    private Color backgroundColor = new Color(1,1,1,0);
  20.  
    List<Dictionary<Vector2,Color>> revocations = new List<Dictionary<Vector2,Color>>();
  21.  
    public Action<float> setColorFill = fill => { };
  22.  
    private float setNow = 0, setMax = 0;
  23.  
    public bool isClose;
  24.  
    public float getFill
  25.  
    {
  26.  
    get { return setNow / setMax; }
  27.  
    }
  28.  
     
  29.  
    void Start()
  30.  
    {
  31.  
    canvas = transform.root.GetComponent<Canvas>();
  32.  
    mainImage = GetComponent<RawImage>();
  33.  
    mainRect = mainImage.rectTransform;
  34.  
    minTexture = GetMinTexture((Texture2D) transform.GetChild(0).GetComponent<RawImage>().texture);
  35.  
    for (int i = 0; i < minTexture.width; i )
  36.  
    {
  37.  
    for (int j = 0; j < minTexture.height; j )
  38.  
    {
  39.  
    if (minTexture.GetPixel(i, j).a > 0.1f)
  40.  
    {
  41.  
    setMax ;
  42.  
    }
  43.  
    }
  44.  
    }
  45.  
    texture = new Texture2D((int)mainRect.sizeDelta.x,(int)mainRect.sizeDelta.y);
  46.  
    for (int i = 0; i < texture.width; i )
  47.  
    {
  48.  
    for (int j = 0; j < texture.height; j )
  49.  
    {
  50.  
    texture.SetPixel(i,j,backgroundColor);
  51.  
    }
  52.  
    }
  53.  
     
  54.  
    setMax *= 0.99f;
  55.  
    texture.Apply();
  56.  
    mainImage.texture = texture;
  57.  
    mainImage.SetNativeSize();
  58.  
    }
  59.  
     
  60.  
    private void Update()
  61.  
    {
  62.  
    if(!handIn || isClose){return;}
  63.  
     
  64.  
    if (FanGameManager.Main.GetClick())
  65.  
    {
  66.  
    revocations.Insert(0,new Dictionary<Vector2, Color>());
  67.  
    }
  68.  
     
  69.  
    if (FanGameManager.Main.GetClickAlways())
  70.  
    {
  71.  
    Vector2 pos = GetPosForTexture();
  72.  
    if (lastPos.x == 0 && lastPos.y == 0 || Vector2.Distance(pos,lastPos) <= radius/2)
  73.  
    {
  74.  
    DrawPoint((int)pos.x,(int)pos.y);
  75.  
    }
  76.  
    else
  77.  
    {
  78.  
    DrawLine((int)lastPos.x,(int)lastPos.y,(int)pos.x,(int)pos.y);
  79.  
    }
  80.  
    lastPos = pos;
  81.  
    }
  82.  
     
  83.  
    if (FanGameManager.Main.GetClickUp())
  84.  
    {
  85.  
    lastPos = Vector2.zero;
  86.  
    }
  87.  
     
  88.  
    if (Input.GetKeyDown(KeyCode.Z))
  89.  
    {
  90.  
    Revocation();
  91.  
    }
  92.  
    if (Input.GetKeyDown(KeyCode.C))
  93.  
    {
  94.  
    ClearAll();
  95.  
    }
  96.  
    }
  97.  
     
  98.  
    Vector2 GetPosForTexture()
  99.  
    {
  100.  
    Vector2 pos = Vector2.zero;
  101.  
    RectTransformUtility.ScreenPointToLocalPointInRectangle
  102.  
    (mainImage.rectTransform,FanGameManager.Main.GetNumPos(), canvas.worldCamera, out pos);
  103.  
    pos.x = mainRect.sizeDelta.x * 0.5f;
  104.  
    pos.y = mainRect.sizeDelta.y * 0.5f;
  105.  
    return pos;
  106.  
    }
  107.  
     
  108.  
    void DrawLine(int startX, int startY, int endX, int endY)
  109.  
    {
  110.  
    float k = ((float)endY - startY) / ((float)endX - startX);
  111.  
    int b = startY - (int)(startX*k);
  112.  
    int minX = startX < endX ? startX : endX;
  113.  
    int maxX = startX > endX ? startX : endX;
  114.  
    int minY = startY < endY ? startY : endY;
  115.  
    int maxY = startY > endY ? startY : endY;
  116.  
    if (maxY - minY > maxX - minX)
  117.  
    {
  118.  
    for (int i = 0; i <= maxY - minY; i =radius/2)
  119.  
    {
  120.  
    if (endX == startX)
  121.  
    {
  122.  
    DrawPoint(minX,minY i);
  123.  
    }
  124.  
    else
  125.  
    {
  126.  
    DrawPoint((int)(((minY i) - b) / k),minY i);
  127.  
    }
  128.  
    }
  129.  
    }
  130.  
    else
  131.  
    {
  132.  
    for (int i = 0; i <= maxX - minX; i =radius/2)
  133.  
    {
  134.  
    DrawPoint(minX i,b (int)((minX i) * k));
  135.  
    }
  136.  
    }
  137.  
    }
  138.  
     
  139.  
    void DrawPoint(int x,int y)
  140.  
    {
  141.  
    int setY = 0;
  142.  
    for (int i = -radius x; i <= radius x; i )
  143.  
    {
  144.  
    setY = (radius * radius) - ((i - x) * (i - x));
  145.  
    setY = (int) (Math.Sqrt(setY)) y;
  146.  
    for (int j = y - (setY - y); j <= setY; j )
  147.  
    {
  148.  
    if(i<0||i>texture.width||j<0||j>texture.height){break;}
  149.  
    if (texture.GetPixel(i, j) != color)
  150.  
    {
  151.  
    if (minTexture.GetPixel(i,j).a > 0.1f)
  152.  
    {
  153.  
    setNow ;
  154.  
    setColorFill(setNow / setMax);
  155.  
    }
  156.  
    try
  157.  
    {
  158.  
    if (!revocations[0].ContainsKey(new Vector2(i, j)))
  159.  
    {
  160.  
    revocations[0].Add(new Vector2(i,j),texture.GetPixel(i,j));
  161.  
    }
  162.  
    }catch (Exception e){}
  163.  
    }
  164.  
    texture.SetPixel(i,j,color);
  165.  
    }
  166.  
    }
  167.  
    SetTexture();
  168.  
    }
  169.  
     
  170.  
    void SetTexture()
  171.  
    {
  172.  
    texture.Apply();
  173.  
    mainImage.texture = texture;
  174.  
    }
  175.  
     
  176.  
    void Revocation()
  177.  
    {
  178.  
    if(revocations.Count == 0){return;}
  179.  
    foreach (var pos in revocations[0])
  180.  
    {
  181.  
    texture.SetPixel((int)pos.Key.x,(int)pos.Key.y,pos.Value);
  182.  
    }
  183.  
    revocations.RemoveAt(0);
  184.  
    SetTexture();
  185.  
    }
  186.  
     
  187.  
    void ClearAll()
  188.  
    {
  189.  
    revocations.Insert(0,new Dictionary<Vector2, Color>());
  190.  
    for (int i = 0; i <= texture.width; i )
  191.  
    {
  192.  
    for (int j = 0; j <= texture.height; j )
  193.  
    {
  194.  
    if (texture.GetPixel(i, j) != backgroundColor)
  195.  
    {
  196.  
    revocations[0].Add(new Vector2(i,j), texture.GetPixel(i,j));
  197.  
    }
  198.  
    texture.SetPixel(i, j, backgroundColor);
  199.  
    }
  200.  
    }
  201.  
     
  202.  
    if (revocations[0].Count == 0)
  203.  
    {
  204.  
    revocations.RemoveAt(0);
  205.  
    }
  206.  
     
  207.  
    SetTexture();
  208.  
    }
  209.  
     
  210.  
    public void OnPointerEnter(PointerEventData eventData)
  211.  
    {
  212.  
    handIn = true;
  213.  
    }
  214.  
     
  215.  
    public void OnPointerExit(PointerEventData eventData)
  216.  
    {
  217.  
    handIn = false;
  218.  
    }
  219.  
     
  220.  
    public Texture2D GetTexture()
  221.  
    {
  222.  
    return texture;
  223.  
    }
  224.  
     
  225.  
    Texture2D GetMinTexture(Texture2D texture)
  226.  
    {
  227.  
    int scaleX = (int) transform.localScale.x;
  228.  
    int scaleY = (int) transform.localScale.y;
  229.  
    int outX = texture.width % scaleX / 2;
  230.  
    int outY = texture.height % scaleY / 2;
  231.  
    Texture2D t = new Texture2D(texture.width/scaleX,texture.height/scaleY);
  232.  
    List<float> alpha;
  233.  
    int q = 0;
  234.  
    int e = 0;
  235.  
    for (int i = outX; i < texture.width - outX; i = scaleX)
  236.  
    {
  237.  
    for (int j = outY; j < texture.height - outY; j = scaleY)
  238.  
    {
  239.  
    alpha = new List<float>();
  240.  
    for (int k = 0; k < scaleX; k )
  241.  
    {
  242.  
    for (int l = 0; l < scaleY; l )
  243.  
    {
  244.  
    alpha.Add(texture.GetPixel(i k,j l).a);
  245.  
    }
  246.  
    }
  247.  
    t.SetPixel(q,e,new Color(0,0,0,GetMeanValue(alpha)));
  248.  
    e ;
  249.  
    }
  250.  
    q ;
  251.  
    }
  252.  
    t.Apply();
  253.  
    return t;
  254.  
    }
  255.  
     
  256.  
    float GetMeanValue(List<float> value)
  257.  
    {
  258.  
    float meanValue = 0;
  259.  
    foreach (float i in value)
  260.  
    {
  261.  
    meanValue = i;
  262.  
    }
  263.  
    meanValue /= value.Count;
  264.  
    return meanValue;
  265.  
    }
  266.  
     
  267.  
     
  268.  
    }
学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfkikec
系列文章
更多 icon
同类精品
更多 icon
继续加载