Unity 实用代码 小工具

代码很简单没有难度,都有注解,随便 康一康 就会了。

Unity 屏幕截图

全屏截图方法

优点:响应速度快,几乎不用考虑优化问题。
缺点:只能截全屏。
/// <summary>
    /// 屏幕截图
    /// </summary>
    /// <param 截图保存名字="_ImageName"></param>
    /// <returns></returns>
    IEnumerator Screenshot(string _ImageName)
    {
    
    
        //等待当前帧结束
        yield return new WaitForEndOfFrame();

        //Environment.CurrentDirectory 相对路径:在项目文件夹
        //如果这个文件夹不存在就创建一个
        if (Directory.Exists(Environment.CurrentDirectory + "\\Screenshot ") == false)
        {
    
    
            Directory.CreateDirectory(Environment.CurrentDirectory + "\\Screenshot ");

            ScreenCapture.CaptureScreenshot(Environment.CurrentDirectory + "\\Screenshot\\" + _ImageName + ".png");
        }
        else
        {
    
    
            ScreenCapture.CaptureScreenshot(Environment.CurrentDirectory + "\\Screenshot\\" + _ImageName + ".png");
        }


        yield break;
    }

全屏截图方法 带委托事件

给两个参考文档:
Texture2D.ReadPixels 参考文档

Rect类 参考文档

额。。。就是带了一个委托
/// <summary>
    /// 屏幕截图
    /// </summary>
    /// <param 委托事件="_Action"></param>
    /// <param 截图名称="_ImageName"></param>
    /// <returns></returns>
    IEnumerator Screenshot(Action _Action, string _ImageName)
    {
    
    
        //等待当前帧结束
        yield return new WaitForEndOfFrame();

        //Environment.CurrentDirectory 相对路径:在项目文件夹
        //如果这个文件夹不存在就创建一个
        if (Directory.Exists(Environment.CurrentDirectory + "\\Screenshot ") == false)
        {
    
    
            Directory.CreateDirectory(Environment.CurrentDirectory + "\\Screenshot ");

            ScreenCapture.CaptureScreenshot(Environment.CurrentDirectory + "\\Screenshot\\" + _ImageName + ".png");
        }
        else
        {
    
    
            ScreenCapture.CaptureScreenshot(Environment.CurrentDirectory + "\\Screenshot\\" + _ImageName + ".png");
        }

        _Action.Invoke();

        yield break;
    }

自定义截图方法

可自定义保存路径,截图名称,截图大小,就很银杏化
/// <summary>
    /// 屏幕截图
    /// </summary>
    /// <param 保存路径="_FilePath"></param>
    /// <param 截图名称="_ImageName"></param>
    /// <param 截图长度="_ImageWidth"></param>
    /// <param 截图高度="_ImageHeight"></param>
    /// <returns></returns>
    IEnumerator Screenshot(string _FilePath, string _ImageName,int _ImageWidth,int _ImageHeight)
    {
    
    
        //等待当前帧结束
        yield return new WaitForEndOfFrame();

        Texture2D _DestinationTexture;

        // 创建一个新的带有屏幕宽度和高度的Texture2D,并缓存它以便重用  
        _DestinationTexture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGBA32, false);

        if (_ImageWidth == 0)
        {
    
    
            _ImageWidth = Screen.width;
        }
        if (_ImageHeight == 0)
        {
    
    
            _ImageHeight = Screen.height;
        }

        // 定义ReadPixels操作的参数  
        Rect _RegionToReadFrom = new Rect(0, 0, _ImageWidth, _ImageHeight);
        int xPosToWriteTo = 0;
        int yPosToWriteTo = 0;



        // 从相机的渲染目标复制像素到纹理  
        _DestinationTexture.ReadPixels(_RegionToReadFrom, xPosToWriteTo, yPosToWriteTo);

        // 将纹理数据上传到GPU,由GPU渲染更新后的纹理  
        // 注意:这个方法代价很高,应该只在需要时调用它  
        // 如果您不打算呈现更新后的纹理,此时没有必要调用此方法  
        //destinationTexture.Apply();

        //截图数据存储
        byte[] _BytesImage = _DestinationTexture.EncodeToPNG();
        File.WriteAllBytes(_FilePath + "\\" + _ImageName + ".png", _BytesImage);

        yield break;
    }

自定义截图方法 带委托

没错  又是多了一个委托事件
 /// <summary>
    /// 屏幕截图
    /// </summary>
    /// <param 委托事件响应="_Action"></param>
    /// <param 保存路径="_FilePath"></param>
    /// <param 截图名称="_ImageName"></param>
    /// <param 截图长度="_ImageWidth"></param>
    /// <param 截图高度="_ImageHeight"></param>
    /// <returns></returns>
    IEnumerator Screenshot(Action _Action, string _FilePath, string _ImageName, int _ImageWidth, int _ImageHeight)
    {
    
    
        //等待当前帧结束
        yield return new WaitForEndOfFrame();

        Texture2D _DestinationTexture;

        // 创建一个新的带有屏幕宽度和高度的Texture2D,并缓存它以便重用  
        _DestinationTexture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGBA32, false);

        if (_ImageWidth == 0)
        {
    
    
            _ImageWidth = Screen.width;
        }
        if (_ImageHeight == 0)
        {
    
    
            _ImageHeight = Screen.height;
        }

        // 定义ReadPixels操作的参数  
        Rect _RegionToReadFrom = new Rect(0, 0, _ImageWidth, _ImageHeight);
        int xPosToWriteTo = 0;
        int yPosToWriteTo = 0;



        // 从相机的渲染目标复制像素到纹理  
        _DestinationTexture.ReadPixels(_RegionToReadFrom, xPosToWriteTo, yPosToWriteTo);

        // 将纹理数据上传到GPU,由GPU渲染更新后的纹理  
        // 注意:这个方法代价很高,应该只在需要时调用它  
        // 如果您不打算呈现更新后的纹理,此时没有必要调用此方法  
        //destinationTexture.Apply();

        //截图数据存储
        byte[] _BytesImage = _DestinationTexture.EncodeToPNG();
        File.WriteAllBytes(_FilePath + "\\" + _ImageName + ".png", _BytesImage);

        //委托事件响应
        _Action.Invoke();
        yield break;
    }
// An highlighted block
var foo = 'bar';

延迟工具

携程延迟方法

使用 协程特性实现程序等待
    /// <summary>
    /// 延迟工具
    /// </summary>
    /// <param 延迟时间="_Time"></param>
    /// <returns></returns>
    public IEnumerator DelayedTime(float _Time)
    {
    
    
        yield return new WaitForSeconds(_Time);
        Debug.Log($"延迟{_Time}秒");
    }

携程延迟带委托方法

和上面那个相似 不过加了个 委托事件
    /// <summary>
    /// 延迟工具
    /// </summary>
    /// <param 委托响事件="_Action"></param>
    /// <param 延迟时间="_Time"></param>
    /// <returns></returns>
    public IEnumerator DelayedTime(Action _Action, float _Time)
    {
    
    
        yield return new WaitForSeconds(_Time);
        //延迟 _Time 秒 再响应委托方法
        _Action.Invoke();

        Debug.Log($"延迟{_Time}秒");
    }

场景加载

场景加载 方法

是的  是场景加载
   /// <summary>
    /// 场景加载
    /// </summary>
    /// <param 加载场景名称="_StrMap"></param>
    /// <returns></returns>
    IEnumerator LoadSceneMap(string _StrMap)
    {
    
    
        SceneManager.LoadScene(_StrMap);
        yield return null;
    }

场景加载方法 带委托

没看错 就是简单的场景加载
  /// <summary>
    /// 场景加载
    /// </summary>
    /// <param 可使用委托事件调用="_ActionMaop"></param>
    /// <param 加载场景名称="_StrMap"></param>
    /// <returns></returns>
    IEnumerator LoadSceneMap(Action _ActionMaop,string _StrMap)
    {
    
    
        SceneManager.LoadScene(_StrMap);
        yield return null;
    }

异步场景加载 方法

异步场景加载 连委托都没有了
    /// <summary>
    /// 异步场景加载
    /// </summary>
    /// <param 想要加载的场景名称="_StrMap"></param>
    /// <param 加载滑动条="_SliderLoad"></param>
    /// <param 加载百分比="_TextLoad"></param>
    /// <returns></returns>
    IEnumerator LoadSceneMap(string _StrMap, Slider _SliderLoad, Text _TextLoad)
    {
    
    
        //想要加载的场景
        AsyncOperation _Operation = SceneManager.LoadSceneAsync(_StrMap);
        //允许场景被激活  为True 时跳转
        _Operation.allowSceneActivation = false;

        //当场景没有加载完毕
        while (!_Operation.isDone)
        {
    
    
            //场景加载程度
            Debug.Log(_Operation.progress);
            //转换成百分比
            Debug.Log((_Operation.progress * 100).ToString() + "%");



            //滑动条 赋值
            _SliderLoad.value = Mathf.Lerp(_SliderLoad.value, _Operation.progress, Time.deltaTime * 1);
            //加载进度文字显示
            _TextLoad.text = (_Operation.progress * 100).ToString() + "%";


            //场景加载大于 0.9f 证明基本加载完毕
            if (_Operation.progress >= 0.9f)
            {
    
    
                Debug.Log("100%");
                //允许场景被激活  为True 时跳转
                _Operation.allowSceneActivation = true;
            }
            yield return null;
        }
    }

计时器方法

倒数计时器 附带委托 可自由变形
/// <summary>
    /// 计时器
    /// </summary>
    /// <param 委托事件调用="_ActionTimer"></param>
    /// <param 定时 时间="_RefreshTime"></param>
    /// <returns></returns>
    public IEnumerator TimerController(Action _ActionTimer, float _RefreshTime)
    {
    
    

        while (true)
        {
    
    
            //时间衰减
            _RefreshTime -= Time.deltaTime;

            Debug.Log($"时间流逝{_RefreshTime}秒");

            //衰减小于 0 时 执行方法
            if (_RefreshTime <= 0)
            {
    
    
                //计时结束
                _ActionTimer.Invoke();
                yield break;
            }
            yield return null;
        }
    }

鼠标双击方法

算是对计时器的一个变种吧
 /// <summary>
    /// 鼠标双击事件
    /// </summary>
    /// <param 委托事件响应="_ActionTimer"></param>
    /// <param 状态布尔="_BoolState"></param>
    /// <returns></returns>
    public IEnumerator MouseClickDown(Action _ActionTimer, bool _BoolState)
    {
    
    
        float _StarTime = 0.0f;
        float _EndTime = 0.0f;
        int _Number = 0;
        while (true)
        {
    
    
            if (Input.GetMouseButtonDown(0))
            {
    
    
                _Number++;

                if (_Number == 1)
                {
    
    
                    //游戏开始后以秒为单位的实时时间(只读)。
                    _StarTime = Time.realtimeSinceStartup;
                }
                else if (_Number >= 2)
                {
    
    
                    //游戏开始后以秒为单位的实时时间(只读)。
                    _EndTime = Time.realtimeSinceStartup;

                    //鼠标双击 满足条件 执行委托
                    if (_EndTime - _StarTime <= 0.23f)
                    {
    
    
                        _ActionTimer.Invoke();

                        //状态布尔 如果为True 就只执行一次  如果为 False 会重复执行
                        if (!_BoolState)
                        {
    
    
                            yield break;
                        }
                    }
                    _Number = 0;
                }

            }
            yield return null;
        }
    }

最大最小值限定方法

是的呢  就是你看到的意思 啧... 真简单
 /// <summary>
    /// 最大最小值限定
    /// </summary>
    /// <param 返回值="_Value"></param>
    /// <param 最小值="_Min"></param>
    /// <param 最大值="_Max"></param>
    /// <returns></returns>
    public float Clam(float _Value, float _Min, float _Max)
    {
    
    
        //如果传递值 _Value 小于最小值 就返回最小值
        if (_Value < _Min)
        {
    
    
            return _Min;
        }
        //如果传递值 _Value 大于最大值 就返回最大值
        if (_Value > _Max)
        {
    
    
            return _Max;
        }
        //否则就返回当前值
        return _Value;
    }

完整代码

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

/// <summary>
/// 实用工具集合
/// </summary>
public class CodeTools_ZH:MonoBehaviour 
{
    
    
    //单例
    public static CodeTools_ZH _Instance;


    private void Awake()
    {
    
    
        _Instance = this;
    }

    void Start()
    {
    
    
        StartCoroutine(DelayedTime(3.0f));

        StartCoroutine(DelayedTime(() => {
    
     Debug.Log("方法延迟"); }, 4.0f));

        StartCoroutine(TimerController(() => {
    
     Debug.Log("计时结束后的方法调用"); }, 4.0f));

        StartCoroutine(MouseClickDown(() => {
    
     Debug.Log("鼠标双击事件"); }, false));

        StartCoroutine(Screenshot( "全屏截图"));

        StartCoroutine(Screenshot("F:\\桌面\\11","自定义截图",100,100));

        StartCoroutine(Screenshot(()=> {
    
     Debug.Log("带委托的截图方法"); },"F:\\桌面\\11", "自定义截图", 100, 100));

        Clam(12, 0, 50);
    }

    void Update()
    {
    
    
        if (Input.GetKeyDown(KeyCode.Q))
        {
    
    
          
        }
    }



    #region 延迟响应

    /// <summary>
    /// 延迟工具
    /// </summary>
    /// <param 延迟时间="_Time"></param>
    /// <returns></returns>
    public IEnumerator DelayedTime(float _Time)
    {
    
    
        yield return new WaitForSeconds(_Time);
        Debug.Log($"延迟{_Time}秒");
    }

    /// <summary>
    /// 延迟工具
    /// </summary>
    /// <param 委托响事件="_Action"></param>
    /// <param 延迟时间="_Time"></param>
    /// <returns></returns>
    public IEnumerator DelayedTime(Action _Action, float _Time)
    {
    
    
        yield return new WaitForSeconds(_Time);
        //延迟 _Time 秒 再响应委托方法
        _Action.Invoke();

        Debug.Log($"延迟{_Time}秒");
    }

    #endregion


    #region 屏幕截图

    /// <summary>
    /// 屏幕截图
    /// </summary>
    /// <param 截图保存名字="_ImageName"></param>
    /// <returns></returns>
    IEnumerator Screenshot(string _ImageName)
    {
    
    
        //等待当前帧结束
        yield return new WaitForEndOfFrame();

        //Environment.CurrentDirectory 相对路径:在项目文件夹
        //如果这个文件夹不存在就创建一个
        if (Directory.Exists(Environment.CurrentDirectory + "\\Screenshot ") == false)
        {
    
    
            Directory.CreateDirectory(Environment.CurrentDirectory + "\\Screenshot ");

            ScreenCapture.CaptureScreenshot(Environment.CurrentDirectory + "\\Screenshot\\" + _ImageName + ".png");
        }
        else
        {
    
    
            ScreenCapture.CaptureScreenshot(Environment.CurrentDirectory + "\\Screenshot\\" + _ImageName + ".png");
        }


        yield break;
    }

    /// <summary>
    /// 屏幕截图
    /// </summary>
    /// <param 委托事件="_Action"></param>
    /// <param 截图名称="_ImageName"></param>
    /// <returns></returns>
    IEnumerator Screenshot(Action _Action, string _ImageName)
    {
    
    
        //等待当前帧结束
        yield return new WaitForEndOfFrame();

        //Environment.CurrentDirectory 相对路径:在项目文件夹
        //如果这个文件夹不存在就创建一个
        if (Directory.Exists(Environment.CurrentDirectory + "\\Screenshot ") == false)
        {
    
    
            Directory.CreateDirectory(Environment.CurrentDirectory + "\\Screenshot ");

            ScreenCapture.CaptureScreenshot(Environment.CurrentDirectory + "\\Screenshot\\" + _ImageName + ".png");
        }
        else
        {
    
    
            ScreenCapture.CaptureScreenshot(Environment.CurrentDirectory + "\\Screenshot\\" + _ImageName + ".png");
        }

        _Action.Invoke();

        yield break;
    }

    /// <summary>
    /// 屏幕截图
    /// </summary>
    /// <param 保存路径="_FilePath"></param>
    /// <param 截图名称="_ImageName"></param>
    /// <param 截图长度="_ImageWidth"></param>
    /// <param 截图高度="_ImageHeight"></param>
    /// <returns></returns>
    IEnumerator Screenshot(string _FilePath, string _ImageName,int _ImageWidth,int _ImageHeight)
    {
    
    
        //等待当前帧结束
        yield return new WaitForEndOfFrame();

        Texture2D _DestinationTexture;

        // 创建一个新的带有屏幕宽度和高度的Texture2D,并缓存它以便重用  
        _DestinationTexture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGBA32, false);

        if (_ImageWidth == 0)
        {
    
    
            _ImageWidth = Screen.width;
        }
        if (_ImageHeight == 0)
        {
    
    
            _ImageHeight = Screen.height;
        }

        // 定义ReadPixels操作的参数  
        Rect _RegionToReadFrom = new Rect(0, 0, _ImageWidth, _ImageHeight);
        int xPosToWriteTo = 0;
        int yPosToWriteTo = 0;



        // 从相机的渲染目标复制像素到纹理  
        _DestinationTexture.ReadPixels(_RegionToReadFrom, xPosToWriteTo, yPosToWriteTo);

        // 将纹理数据上传到GPU,由GPU渲染更新后的纹理  
        // 注意:这个方法代价很高,应该只在需要时调用它  
        // 如果您不打算呈现更新后的纹理,此时没有必要调用此方法  
        //destinationTexture.Apply();

        //截图数据存储
        byte[] _BytesImage = _DestinationTexture.EncodeToPNG();
        File.WriteAllBytes(_FilePath + "\\" + _ImageName + ".png", _BytesImage);

        yield break;
    }

    /// <summary>
    /// 屏幕截图
    /// </summary>
    /// <param 委托事件响应="_Action"></param>
    /// <param 保存路径="_FilePath"></param>
    /// <param 截图名称="_ImageName"></param>
    /// <param 截图长度="_ImageWidth"></param>
    /// <param 截图高度="_ImageHeight"></param>
    /// <returns></returns>
    IEnumerator Screenshot(Action _Action, string _FilePath, string _ImageName, int _ImageWidth, int _ImageHeight)
    {
    
    
        //等待当前帧结束
        yield return new WaitForEndOfFrame();

        Texture2D _DestinationTexture;

        // 创建一个新的带有屏幕宽度和高度的Texture2D,并缓存它以便重用  
        _DestinationTexture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGBA32, false);

        if (_ImageWidth == 0)
        {
    
    
            _ImageWidth = Screen.width;
        }
        if (_ImageHeight == 0)
        {
    
    
            _ImageHeight = Screen.height;
        }

        // 定义ReadPixels操作的参数  
        Rect _RegionToReadFrom = new Rect(0, 0, _ImageWidth, _ImageHeight);
        int xPosToWriteTo = 0;
        int yPosToWriteTo = 0;



        // 从相机的渲染目标复制像素到纹理  
        _DestinationTexture.ReadPixels(_RegionToReadFrom, xPosToWriteTo, yPosToWriteTo);

        // 将纹理数据上传到GPU,由GPU渲染更新后的纹理  
        // 注意:这个方法代价很高,应该只在需要时调用它  
        // 如果您不打算呈现更新后的纹理,此时没有必要调用此方法  
        //destinationTexture.Apply();

        //截图数据存储
        byte[] _BytesImage = _DestinationTexture.EncodeToPNG();
        File.WriteAllBytes(_FilePath + "\\" + _ImageName + ".png", _BytesImage);

        //委托事件响应
        _Action.Invoke();
        yield break;
    }

    #endregion



    #region 场景加载

    /// <summary>
    /// 异步场景加载
    /// </summary>
    /// <param 想要加载的场景名称="_StrMap"></param>
    /// <param 加载滑动条="_SliderLoad"></param>
    /// <param 加载百分比="_TextLoad"></param>
    /// <returns></returns>
    IEnumerator LoadSceneMap(string _StrMap, Slider _SliderLoad, Text _TextLoad)
    {
    
    
        //想要加载的场景
        AsyncOperation _Operation = SceneManager.LoadSceneAsync(_StrMap);
        //允许场景被激活  为True 时跳转
        _Operation.allowSceneActivation = false;

        //当场景没有加载完毕
        while (!_Operation.isDone)
        {
    
    
            //场景加载程度
            Debug.Log(_Operation.progress);
            //转换成百分比
            Debug.Log((_Operation.progress * 100).ToString() + "%");



            //滑动条 赋值
            _SliderLoad.value = Mathf.Lerp(_SliderLoad.value, _Operation.progress, Time.deltaTime * 1);
            //加载进度文字显示
            _TextLoad.text = (_Operation.progress * 100).ToString() + "%";


            //场景加载大于 0.9f 证明基本加载完毕
            if (_Operation.progress >= 0.9f)
            {
    
    
                Debug.Log("100%");
                //允许场景被激活  为True 时跳转
                _Operation.allowSceneActivation = true;
            }
            yield return null;
        }
    }

    /// <summary>
    /// 场景加载
    /// </summary>
    /// <param 可使用委托事件调用="_ActionMaop"></param>
    /// <param 加载场景名称="_StrMap"></param>
    /// <returns></returns>
    IEnumerator LoadSceneMap(Action _ActionMaop,string _StrMap)
    {
    
    
        SceneManager.LoadScene(_StrMap);
        yield return null;
    }

    /// <summary>
    /// 场景加载
    /// </summary>
    /// <param 加载场景名称="_StrMap"></param>
    /// <returns></returns>
    IEnumerator LoadSceneMap(string _StrMap)
    {
    
    
        SceneManager.LoadScene(_StrMap);
        yield return null;
    }

    #endregion




    /// <summary>
    /// 计时器
    /// </summary>
    /// <param 委托事件调用="_ActionTimer"></param>
    /// <param 定时 时间="_RefreshTime"></param>
    /// <returns></returns>
    public IEnumerator TimerController(Action _ActionTimer, float _RefreshTime)
    {
    
    

        while (true)
        {
    
    
            //时间衰减
            _RefreshTime -= Time.deltaTime;

            Debug.Log($"时间流逝{_RefreshTime}秒");

            //衰减小于 0 时 执行方法
            if (_RefreshTime <= 0)
            {
    
    
                //计时结束
                _ActionTimer.Invoke();
                yield break;
            }
            yield return null;
        }
    }

    /// <summary>
    /// 鼠标双击事件
    /// </summary>
    /// <param 委托事件响应="_ActionTimer"></param>
    /// <param 状态布尔="_BoolState"></param>
    /// <returns></returns>
    public IEnumerator MouseClickDown(Action _ActionTimer, bool _BoolState)
    {
    
    
        float _StarTime = 0.0f;
        float _EndTime = 0.0f;
        int _Number = 0;
        while (true)
        {
    
    
            if (Input.GetMouseButtonDown(0))
            {
    
    
                _Number++;

                if (_Number == 1)
                {
    
    
                    //游戏开始后以秒为单位的实时时间(只读)。
                    _StarTime = Time.realtimeSinceStartup;
                }
                else if (_Number >= 2)
                {
    
    
                    //游戏开始后以秒为单位的实时时间(只读)。
                    _EndTime = Time.realtimeSinceStartup;

                    //鼠标双击 满足条件 执行委托
                    if (_EndTime - _StarTime <= 0.23f)
                    {
    
    
                        _ActionTimer.Invoke();

                        //状态布尔 如果为True 就只执行一次  如果为 False 会重复执行
                        if (!_BoolState)
                        {
    
    
                            yield break;
                        }
                    }
                    _Number = 0;
                }

            }
            yield return null;
        }
    }




    /// <summary>
    /// 最大最小值限定
    /// </summary>
    /// <param 返回值="_Value"></param>
    /// <param 最小值="_Min"></param>
    /// <param 最大值="_Max"></param>
    /// <returns></returns>
    public float Clam(float _Value, float _Min, float _Max)
    {
    
    
        //如果传递值 _Value 小于最小值 就返回最小值
        if (_Value < _Min)
        {
    
    
            return _Min;
        }
        //如果传递值 _Value 大于最大值 就返回最大值
        if (_Value > _Max)
        {
    
    
            return _Max;
        }
        //否则就返回当前值
        return _Value;
    }


}

暂时先这样吧,如果有时间的话就会更新,实在看不明白就留言,看到我会回复的。
路漫漫其修远兮,与君共勉。

猜你喜欢

转载自blog.csdn.net/weixin_43925843/article/details/122221153