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 参考文档
额。。。就是带了一个委托
/// <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.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class InputSwitching_ZH : MonoBehaviour
{
//输入列表
private List<GameObject> _InputList = new List<GameObject>();
//响应 事件
private EventSystem _System;
/// <summary>
/// 初始化
/// </summary>
public void Initialize()
{
//获取 响应 事件
_System = EventSystem.current;
//输入列表添加
_InputList.AddRange(GameObject.FindGameObjectsWithTag("输入"));
}
private void Update()
{
//按下 Tab 建
if (Input.GetKeyDown(KeyCode.Tab))
{
//判断当前输入 对象是否存在
if (_InputList.Contains(_System.currentSelectedGameObject))
{
//获取下一个输入对象
GameObject _Next = GetNextInput(_System.currentSelectedGameObject);
//设置选定的游戏对象
_System.SetSelectedGameObject(_Next);
}
}
}
/// <summary>
/// 上一个输出
/// </summary>
/// <param 当前输入物体="_InputGam"></param>
/// <returns></returns>
private GameObject GetPreviousInput(GameObject _InputGam)
{
//获取当前输入 下标
int _IndeNow = IndexNow(_InputGam);
//判断是否是第一个
//如果不是
if (_IndeNow - 1 >= 0)
{
return _InputList[_IndeNow - 1].gameObject;
}
else
{
//否则返回输入列表 最后一个
return _InputList[_InputList.Count - 1].gameObject;
}
}
/// <summary>
/// 下一个输入
/// </summary>
/// <param 当前输入物体="_InputGam"></param>
/// <returns></returns>
private GameObject GetNextInput(GameObject _InputGam)
{
//获取当前输入 下标
int _IndeNow = IndexNow(_InputGam);
//判断是否是最后一个
//如果不是
if (_IndeNow + 1 < _InputList.Count)
{
return _InputList[_IndeNow + 1].gameObject;
}
else
{
//否则返回输入列表第一个
return _InputList[0].gameObject;
}
}
/// <summary>
/// 返回当前 列表 下标
/// </summary>
/// <param 当前输入="_Input"></param>
/// <returns></returns>
private int IndexNow(GameObject _InputNow)
{
int _IndeNow = 0;
for (int i = 0; i < _InputList.Count; i++)
{
if (_InputNow == _InputList[i])
{
_IndeNow = i;
break;
}
}
return _IndeNow;
}
}
完整代码
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;
}
}
暂时先这样吧,如果有时间的话就会更新,实在看不明白就留言,看到我会回复的。
路漫漫其修远兮,与君共勉。