最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Unity使用LineRender實現(xiàn)簽名效果

 更新時間:2021年10月10日 14:01:25   作者:吸血鬼1124  
這篇文章主要為大家詳細介紹了Unity使用LineRender實現(xiàn)簽名效果,制作簽名功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文為大家分享了Unity制作簽名功能的具體代碼,供大家參考,具體內容如下

前言:項目中需要做一個簽名的功能,同時需要兩個兩個屏幕進行顯示,但是都是在UI上,從網(wǎng)上查了大量資料。

找到兩種方法:

1、修改圖片像素點  但是是馬賽克效果,不滿足需求
2、使用LineRenderer 的3D簽名制作出2D效果

改像素點:

先上代碼

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
 
public class Test : ObjBase
{
 
    public GameObject m_obj;
    private Texture2D m_tex;
    public Color m_color;
    public int size = 3;
    private Color[] m_textureColorsStart;
 
 
    public RawImage showImg;
    void Start()
    {
        if (Display.displays.Length > 1)
            Display.displays[1].Activate();
        if (Display.displays.Length > 2)
            Display.displays[2].Activate();
        m_tex = m_obj.GetComponent<MeshRenderer>().material.mainTexture as Texture2D;
        //從紋理中獲取像素顏色
        m_textureColorsStart = m_tex.GetPixels();
        Debug.Log(m_tex.name);
    }
 
 
    void Update()
    {
        //Vector3 oldPos=Vector3.zero;
        //oldPos = Input.mousePosition;
        //Ray ray = uiCam.ScreenPointToRay(Input.mousePosition);
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;
        if (Input.GetMouseButton(0))
        {
            // float m_magnitude = (Input.mousePosition - oldPos).magnitude;
            // Vector3 dir = Input.mousePosition - oldPos;  
            if (Physics.Raycast(ray, out hit))
            {
                //在碰撞位置處的UV紋理坐標。
                Vector2 pixelUV = hit.textureCoord;
                //以像素為單位的紋理寬度
                pixelUV.x *= m_tex.width;
                pixelUV.y *= m_tex.height;
                //貼圖UV坐標以右上角為原點
                for (float i = pixelUV.x - 1; i < pixelUV.x + size; i++)
                {
                    for (float j = pixelUV.y - 1; j < pixelUV.y + size; j++)
                    {
                        m_tex.SetPixel((int)i, (int)j, m_color);
                    }
                }
                Debug.Log(pixelUV);
                m_tex.Apply();
                showImg.texture = m_tex;
            }
        }
        if (Input.GetKeyDown(KeyCode.Space))
        {
            //還原
            m_tex.SetPixels(m_textureColorsStart);
            m_tex.Apply();
        }
 
 
        //在處理鼠標按下的記錄下位置,抬起的時候記錄下位置,取2個位置中間的位置發(fā)射射線
        //if (Input.GetMouseButtonDown(0))
        //{
 
        //}
        //if (Input.GetMouseButtonUp(0))
        //{
 
        //}
    }
 
    public void OnClick()
    {
       
        showImg.texture = m_tex;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class ObjBase : MonoBehaviour
{
    
 
    public bool IsShow
    {
        get { return gameObject.activeSelf; }
    }
 
    // Use this for initialization
    void Start()
    {
 
    }
 
    /// <summary>
    /// 顯示
    /// </summary>
    /// <param name="parameter"></param>
    public virtual void Show(object parameter = null)
    {
       
        gameObject.SetActive(true);
    }
 
    /// <summary>
    /// 隱藏
    /// </summary>
    /// <param name="parameter"></param>
    public virtual void Hide(object parameter = null)
    {
        gameObject.SetActive(false);
    }
 
   
 
}

Test腳本是用來修改像素點的,ObjBase只是一個根父類,控制顯示和隱藏。

測試場景用的Quad,通過讀取他的mainTexture對應的像素,進行修改,UI中的話就是將一張圖片轉成Texture2D形式,通過讀取像素點,進行修改即可,同時還可以實現(xiàn)同步效果。

項目中的Hierarchy窗口設置:

項目需求:使用了兩個畫布,MainCamera照射Quad,兩個UI相機分別照射兩個畫布,畫布的Render Mode設置為Screen Space -Camera格式。GameObject掛載腳本,Quad用來修改其上的圖片的像素點。

效果圖:

使用LineRenderer   3D劃線方法實現(xiàn)2D簽名效果:

先上代碼:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Text;
using System.IO;
using UnityEngine.EventSystems;
 
public class Test5 : MonoBehaviour {
 
    public GameObject drawObj;
    private bool beginDraw;
    private GameObject obj;
    public Transform parent;
    public RawImage rawImg;
    public Camera UICam;
    public Camera main;//主相機和UI相機共同照射到的地方進行截圖
    Color[] colors;
    Texture2D myTexture2D;
    public RawImage photo;
 
    public RawImage showImg;
    [SerializeField] private string _name;
 
    public RectTransform canvas1;
 
    public void SaveFile()
    {
        Camera mainCam;
        GameObject cam = Camera.main.gameObject;
 
        if (cam)
        {
            mainCam = cam.GetComponent<Camera>();
        }
        else
        {
            return;
        }
 
        RenderTexture renderTex;
 
        renderTex = new RenderTexture(Screen.width, Screen.height, 24);
        mainCam.targetTexture = renderTex;
        mainCam.Render();
 
         myTexture2D = new Texture2D(renderTex.width, renderTex.height);
        RenderTexture.active = renderTex;
        myTexture2D.ReadPixels(new Rect(0, 0, renderTex.width, renderTex.height), 0, 0);
        
       
        myTexture2D.Apply();
        byte[] bytes = myTexture2D.EncodeToJPG();
 
        myTexture2D.Compress(true);
        myTexture2D.Apply();
        RenderTexture.active = null;
 
        File.WriteAllBytes(Application.dataPath + "/StreamingAssets/TextureTemp.png", bytes);
        mainCam.targetTexture = null;
        GameObject.Destroy(renderTex);
    }
 
    public void OnClick()
    {
       
        main.rect = new Rect(0, 0, 1, 1);
       CaptureCamera( main,new Rect(Screen.width * 0f, Screen.height * 0f, Screen.width * 1f, Screen.height * 1f));
 
        
    }
 
 
    /// <summary>  
    /// 對相機截圖。   
    /// </summary>  
    /// <returns>The screenshot2.</returns>  
    /// <param name="camera">Camera.要被截屏的相機</param>  
    /// <param name="rect">Rect.截屏的區(qū)域</param>  
    Texture2D CaptureCamera(Camera camera,Rect rect)
    {
        // 創(chuàng)建一個RenderTexture對象  
        RenderTexture rt = new RenderTexture((int)rect.width, (int)rect.height, 0);
        // 臨時設置相關相機的targetTexture為rt, 并手動渲染相關相機  
        camera.targetTexture = rt;
        camera.Render();
        //ps: --- 如果這樣加上第二個相機,可以實現(xiàn)只截圖某幾個指定的相機一起看到的圖像。  
         //camera2.targetTexture = rt;  
        // camera2.Render();  
        //ps: -------------------------------------------------------------------  
 
        // 激活這個rt, 并從中中讀取像素。  
        RenderTexture.active = rt;
        Texture2D screenShot = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGB24, false);
        screenShot.ReadPixels(rect, 0, 0);// 注:這個時候,它是從RenderTexture.active中讀取像素  
        screenShot.Apply();
 
        // 重置相關參數(shù),以使用camera繼續(xù)在屏幕上顯示  
        camera.targetTexture = null;
       // camera2.targetTexture = null;
        //ps: camera2.targetTexture = null;  
        RenderTexture.active = null; // JC: added to avoid errors  
        GameObject.Destroy(rt);
        // 最后將這些紋理數(shù)據(jù),成一個png圖片文件  
        byte[] bytes = screenShot.EncodeToPNG();
        string filename = Application.dataPath + string.Format("/Screenshot_{0}.png", _name);
        System.IO.File.WriteAllBytes(filename, bytes);
        Debug.Log(string.Format("截屏了一張照片: {0}", filename));
        showImg.texture = screenShot;
        main.rect = new Rect(0.25f, 0.35f, 0.5f, 0.5f);
        return screenShot;
    }
   
 
    void Start () {
        if (Display.displays.Length > 1)
            Display.displays[1].Activate();
        if (Display.displays.Length > 2)
            Display.displays[2].Activate();
    }
 
 // Update is called once per frame
 void Update () {
        if (Input.GetMouseButtonDown(0))
        {
            beginDraw = true;
            obj = Instantiate(drawObj) as GameObject;
            obj.transform.parent = parent;
        }
        if (Input.GetMouseButtonUp(0))
        {
            beginDraw = false;
        }
 
        if (beginDraw)
        {
            Vector3 position = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10f);
            position = Camera.main.ScreenToWorldPoint(position);
            //Vector3 localPoint;
            //if(RectTransformUtility.ScreenPointToWorldPointInRectangle(canvas1, position, null, out localPoint))
            //{
            //    position = localPoint;
            //}
           
 
            DrawText dt = obj.GetComponent<DrawText>();
            dt.points.Add(position);
            dt.Draw();
            dt.line.startColor = Color.yellow;
            dt.line.endColor = Color.yellow;
            dt.line.startWidth = 0.03f;
            dt.line.endWidth = 0.03f;
        }
 
    }
}

Test5是劃線和截取簽名的操作,綁定在空物體上,OnClick函數(shù)綁定在按鈕上

Line:制作簽名預制體

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class DrawText : MonoBehaviour {
 
 
    public List<Vector3> points = new List<Vector3>();
    public  LineRenderer line;
    private void Awake()
    {
        line = GetComponent<LineRenderer>();
    }
    public  void Draw()
    {
        line.positionCount = points.Count;
        for (int i = 0; i < points.Count; i++)
        {
            line.SetPosition(i, points[i]);
            line.startWidth =2f;
            line.endWidth =2f;
        }
    }
    // Use this for initialization
    void Start () {
  
 }
 
 // Update is called once per frame
 void Update () {
  
 }
}

Draw Text腳本掛在預制體Line上,Line 添加LineRenderer組件,同時Material中加入自己創(chuàng)建的材質球

項目需求:Hierarchy窗口設置

和上面一種方法一樣,也是兩個畫布,兩個UI相機,同時需要一個MainCamera

parent為空物體,用來作為根節(jié)點,將簽名時實時生成的預制體放在其下面,作為子節(jié)點,方便后面進行銷毀,重新簽名。

重點:

第二種方法使用的是特定相機照射畫面進行截圖,Test5中的CaptureCamera方法就是截取主相機照射到的畫面。由于簽名不能進行全屏進行截圖,只能部分截圖,類似相面的畫面

下面會有一些常規(guī)的功能按鈕,重新簽名,保存簽名等等操作,這些操作就是在UI上進行簽名。

所以,通過修改MainCamera的Viewport Rect窗口來進行截圖,同時能夠實現(xiàn)正常的簽名操作。

MainCamera的Viewport Rect設置:

運行剛開始:

通過設置這個屬性,可以使簽名界面呈現(xiàn)上一個圖的效果,前面是UI層,后面是3D層。

然而在截屏圖的時候如果始終保持Viewport Rect是上面的設置,則截圖的時候仍把周圍的黑色部分也截取出來,剛開始以為特定相機照射截圖只截取Viewport Rect中的圖像,后來測試是周圍的所有黑色部分也截取了,這樣就不滿足要求。

所以,在代碼中簽字 的時候保持上面的設置,截圖之前main.rect = new Rect(0, 0, 1, 1);設置成全屏,截好之后重新回復成原來的設置  main.rect = new Rect(0.25f, 0.35f, 0.5f, 0.5f);,截圖完成之后將簽名圖片賦值給第二個屏幕畫布中的RawImage進行展示。

達到效果。結合UI實際簽名過程中

中間的白色部分,通過設置MainCamera中的Camera組件中的Background(設置為白色)以及天空盒(Windows->Lighting->Settings->Scene->Skybox Material設置為空),設置為需要的顏色。UI制作的時候需要簽名的部分制作成透明的即可。

效果圖:

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • C#?Winform文本面板帶滾動條的實現(xiàn)過程

    C#?Winform文本面板帶滾動條的實現(xiàn)過程

    當數(shù)據(jù)過多時,往往無法在一頁中展示,所以非常需要一個滾動條來調節(jié)頁面內容,這篇文章主要給大家介紹了關于C#?Winform文本面板帶滾動條的實現(xiàn)過程,需要的朋友可以參考下
    2022-12-12
  • unity 實現(xiàn)攝像機繞某點旋轉一周

    unity 實現(xiàn)攝像機繞某點旋轉一周

    這篇文章主要介紹了unity 實現(xiàn)攝像機繞某點旋轉一周,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • C#實現(xiàn)單鏈表(線性表)完整實例

    C#實現(xiàn)單鏈表(線性表)完整實例

    這篇文章主要介紹了C#實現(xiàn)單鏈表(線性表)的方法,結合完整實例形式分析了單鏈表的原理、實現(xiàn)方法與相關注意事項,需要的朋友可以參考下
    2016-06-06
  • C#面向對象編程中接口隔離原則的示例詳解

    C#面向對象編程中接口隔離原則的示例詳解

    在面向對象編程中,SOLID?是五個設計原則的首字母縮寫,旨在使軟件設計更易于理解、靈活和可維護。本文將通過實例詳細講講C#面向對象編程中接口隔離原則,需要的可以參考一下
    2022-07-07
  • C# IEnumerator枚舉器的具體使用

    C# IEnumerator枚舉器的具體使用

    本文主要介紹了C# IEnumerator枚舉器的具體使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-06-06
  • C#七大經(jīng)典排序算法系列(下)

    C#七大經(jīng)典排序算法系列(下)

    這篇文章主要為大家詳細介紹了C#七大經(jīng)典排序算法系列下篇,直接插入排序,希爾排序和歸并排序,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • C#中yield用法使用說明

    C#中yield用法使用說明

    本文介紹了C#中yield的使用方法,yield 語句不能出現(xiàn)在匿名方法,其他相關內容就仔細閱讀下文吧
    2015-10-10
  • C#多線程之線程控制詳解

    C#多線程之線程控制詳解

    這篇文章主要為大家詳細介紹了C#多線程之線程控制的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • 使用revit api畫垂直于風管的風管示例

    使用revit api畫垂直于風管的風管示例

    這篇文章主要介紹了使用revit api畫垂直于風管的風管示例,需要的朋友可以參考下
    2014-03-03
  • C#如何在窗體程序中操作數(shù)據(jù)庫數(shù)據(jù)

    C#如何在窗體程序中操作數(shù)據(jù)庫數(shù)據(jù)

    這篇文章主要介紹了C#如何在窗體程序中操作數(shù)據(jù)庫數(shù)據(jù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04

最新評論

古浪县| 资兴市| 怀化市| 阿拉善左旗| 舒兰市| 绥棱县| 凤山市| 海林市| 天峻县| 晋江市| 修文县| 得荣县| 花莲市| 肇源县| 汝城县| 岑巩县| 翼城县| 讷河市| 鹤峰县| 财经| 邛崃市| 简阳市| 卓资县| 松潘县| 广安市| 若羌县| 探索| 博野县| 晋中市| 玛多县| 通山县| 庆云县| 永和县| 郁南县| 炉霍县| 连云港市| 巩留县| 望奎县| 柘荣县| 昆明市| 英吉沙县|