代码很简单没有难度,都有注解,随便 康一康 就会了。
优点:响应速度快,几乎不用考虑优化问题。
缺点:只能截全屏。
///
/// 屏幕截图
///
///
///
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类 参考文档
额。。。就是带了一个委托
///
/// 屏幕截图
///
///
///
///
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;
}
可自定义保存路径,截图名称,截图大小,就很银杏化
///
/// 屏幕截图
///
///
///
///
///
///
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;
}
没错 又是多了一个委托事件
///
/// 屏幕截图
///
///
///
///
///
///
///
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';
使用 协程特性实现程序等待
///
/// 延迟工具
///
///
///
public IEnumerator DelayedTime(float _Time)
{
yield return new WaitForSeconds(_Time);
Debug.Log($"延迟{_Time}秒");
}
和上面那个相似 不过加了个 委托事件
///
/// 延迟工具
///
///
///
///
public IEnumerator DelayedTime(Action _Action, float _Time)
{
yield return new WaitForSeconds(_Time);
//延迟 _Time 秒 再响应委托方法
_Action.Invoke();
Debug.Log($"延迟{_Time}秒");
}
是的 是场景加载
///
/// 场景加载
///
///
///
IEnumerator LoadSceneMap(string _StrMap)
{
SceneManager.LoadScene(_StrMap);
yield return null;
}
没看错 就是简单的场景加载
///
/// 场景加载
///
///
///
///
IEnumerator LoadSceneMap(Action _ActionMaop,string _StrMap)
{
SceneManager.LoadScene(_StrMap);
yield return null;
}
异步场景加载 连委托都没有了
///
/// 异步场景加载
///
///
///
///
///
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;
}
}
倒数计时器 附带委托 可自由变形
///
/// 计时器
///
///
///
///
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;
}
}
算是对计时器的一个变种吧
///
/// 鼠标双击事件
///
///
///
///
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;
}
}
是的呢 就是你看到的意思 啧... 真简单
///
/// 最大最小值限定
///
///
///
///
///
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;
///
/// 实用工具集合
///
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 延迟响应
///
/// 延迟工具
///
///
///
public IEnumerator DelayedTime(float _Time)
{
yield return new WaitForSeconds(_Time);
Debug.Log($"延迟{_Time}秒");
}
///
/// 延迟工具
///
///
///
///
public IEnumerator DelayedTime(Action _Action, float _Time)
{
yield return new WaitForSeconds(_Time);
//延迟 _Time 秒 再响应委托方法
_Action.Invoke();
Debug.Log($"延迟{_Time}秒");
}
#endregion
#region 屏幕截图
///
/// 屏幕截图
///
///
///
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;
}
///
/// 屏幕截图
///
///
///
///
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;
}
///
/// 屏幕截图
///
///
///
///
///
///
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;
}
///
/// 屏幕截图
///
///
///
///
///
///
///
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 场景加载
///
/// 异步场景加载
///
///
///
///
///
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;
}
}
///
/// 场景加载
///
///
///
///
IEnumerator LoadSceneMap(Action _ActionMaop,string _StrMap)
{
SceneManager.LoadScene(_StrMap);
yield return null;
}
///
/// 场景加载
///
///
///
IEnumerator LoadSceneMap(string _StrMap)
{
SceneManager.LoadScene(_StrMap);
yield return null;
}
#endregion
///
/// 计时器
///
///
///
///
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;
}
}
///
/// 鼠标双击事件
///
///
///
///
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;
}
}
///
/// 最大最小值限定
///
///
///
///
///
public float Clam(float _Value, float _Min, float _Max)
{
//如果传递值 _Value 小于最小值 就返回最小值
if (_Value < _Min)
{
return _Min;
}
//如果传递值 _Value 大于最大值 就返回最大值
if (_Value > _Max)
{
return _Max;
}
//否则就返回当前值
return _Value;
}
}
暂时先这样吧,如果有时间的话就会更新,实在看不明白就留言,看到我会回复的。
路漫漫其修远兮,与君共勉。