Unity小技巧收集总结--自用(二)

目录

 1、加载场景,显示进度

2、Image渐变色

3、获取物体所有的材质,并且改变这些材质的Shader

4、检查tag列表中是否有tag,没有该tag添加此tag

5、Dotween对数值进行递增或递减

6、鼠标双击

7、获取模型Bound中心点

8、绘制相机视野

9、编辑器扩展,复制物体的Position和Roation

 10、鼠标拖动物体移动

11、逐渐注视目标方向旋转

12、对象池

13、将角度限制在360

 14、获取动画状态机animator的动画clip的播放持续时长

15、更新血条位置

16、简单心跳

17、数据改变回调

18、Unity动画系统Animator动态添加事件

19、字幕轮播

20、unity运行状态下不刷新脚本

21、Game视窗还原Sence视窗功能

22、画面质量设置:低,中,高

23、一键创建unity所必须的基础文件夹

24、关闭日志输出



 1、加载场景,显示进度

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

public class SceneLoadTool : MonoBehaviour
{
    /// 
    /// 要加载场景的名称
    /// 
    public string SceneName;

    /// 
    /// 加载进度显示界面
    /// 
    public GameObject LoadingPanel;

    /// 
    /// 加载进度条
    /// 
    public Slider LoadSlider;

    /// 
    /// 加载进度文字
    /// 
    public Text txt_LoadProcess;

    /// 
    /// 进度条速度
    /// 
    private float loadSpeed = 1;

    /// 
    /// 进度条最终进度值
    /// 
    private float loadTargetValue = 0;

    public void StartLoadScene()
    {
        LoadSlider.value = 0;
        StartCoroutine(LoadScene(SceneName));
    }

    IEnumerator LoadScene(string sceneName)
    {
        LoadingPanel.SetActive(true);
        AsyncOperation operation = SceneManager.LoadSceneAsync(sceneName);
        operation.allowSceneActivation = false;
        while (!operation.isDone)
        {
            loadTargetValue = operation.progress;
            if (operation.progress >= 0.9f)
            {
                loadTargetValue = 1;
            }

            if (!loadTargetValue.Equals(LoadSlider.value))
            {
                LoadSlider.value = Mathf.Lerp(LoadSlider.value, loadTargetValue,Time.deltaTime * loadSpeed); //插值,让进度条流畅
                if (Mathf.Abs(LoadSlider.value - loadTargetValue) < 0.01f)
                {
                    LoadSlider.value = loadTargetValue;
                }
            }

            txt_LoadProcess.text =(int)(LoadSlider.value * 100) + "%";
            if ((int)(LoadSlider.value * 100) == 100)
            {
                operation.allowSceneActivation = true; //允许异步加载完毕后自动切换场景 
            }

            yield return null;
        }
    }
}

2、Image渐变色

using UnityEngine;
using UnityEngine.UI;

/// 
/// 挂Image组件上
/// 
[AddComponentMenu("UI/Effects/Gradient")]
public class GradientColor : BaseMeshEffect
{
    public Color Color1 = Color.white;
    public Color Color2 = Color.white;

    [Range(-180f, 180f)] public float Angle = -90.0f;

    public override void ModifyMesh(VertexHelper vh)
    {
        if (enabled)
        {
            var rect = graphic.rectTransform.rect;
            var dir = RotationDir(Angle);

            var localPositionMatrix = LocalPositionMatrix(rect, dir);

            var vertex = default(UIVertex);
            for (var i = 0; i < vh.currentVertCount; i++)
            {
                vh.PopulateUIVertex(ref vertex, i);
                var localPosition = localPositionMatrix * vertex.position;
                vertex.color *= Color.Lerp(Color2, Color1, localPosition.y);
                vh.SetUIVertex(vertex, i);
            }
        }
    }

    public struct Matrix2x3
    {
        public float m00, m01, m02, m10, m11, m12;

        public Matrix2x3(float m00, float m01, float m02, float m10, float m11, float m12)
        {
            this.m00 = m00;
            this.m01 = m01;
            this.m02 = m02;
            this.m10 = m10;
            this.m11 = m11;
            this.m12 = m12;
        }

        public static Vector2 operator *(Matrix2x3 m, Vector2 v)
        {
            float x = (m.m00 * v.x) - (m.m01 * v.y) + m.m02;
            float y = (m.m10 * v.x) + (m.m11 * v.y) + m.m12;
            return new Vector2(x, y);
        }
    }

    private Matrix2x3 LocalPositionMatrix(Rect rect, Vector2 dir)
    {
        float cos = dir.x;
        float sin = dir.y;
        Vector2 rectMin = rect.min;
        Vector2 rectSize = rect.size;
        float c = 0.5f;
        float ax = rectMin.x / rectSize.x + c;
        float ay = rectMin.y / rectSize.y + c;
        float m00 = cos / rectSize.x;
        float m01 = sin / rectSize.y;
        float m02 = -(ax * cos - ay * sin - c);
        float m10 = sin / rectSize.x;
        float m11 = cos / rectSize.y;
        float m12 = -(ax * sin + ay * cos - c);
        return new Matrix2x3(m00, m01, m02, m10, m11, m12);
    }

    private Vector2 RotationDir(float angle)
    {
        float angleRad = angle * Mathf.Deg2Rad;
        float cos = Mathf.Cos(angleRad);
        float sin = Mathf.Sin(angleRad);
        return new Vector2(cos, sin);
    }
}

3、获取物体所有的材质,并且改变这些材质的Shader

 #region 获取物体所有的材质,并且改变这些材质的Shader

    private Renderer[] rendArray;
    private List materials = new List();

    /// 
    /// 获取物体上所有的材质,并改变这些材质的Shader
    /// 
    private void GetModelAllMaterialsAndChange(GameObject gameObject, Shader targetShader)
    {
        materials.Clear();
        rendArray = gameObject.transform.GetComponentsInChildren(true);
        for (int i = 0; i < rendArray.Length; i++)
        {
            Material[] mats = rendArray[i].materials;
            for (int j = 0; j < mats.Length; j++)
            {
                materials.Add(mats[j]);
            }
        }

        for (int i = 0; i < materials.Count; i++)
        {
            materials[i].shader = targetShader;
        }
    }

    #endregion

4、检查tag列表中是否有tag,没有该tag添加此tag

    /// 
    /// 检查tag列表中是否有tag,没有该tag添加此tag
    /// 
    /// 所要设设置的tag
    public static void SetGameObjectTag(GameObject gameObject, string tag)
    {
        if (!UnityEditorInternal.InternalEditorUtility.tags.Equals(tag)) //如果tag列表中没有这个tag
        {
            UnityEditorInternal.InternalEditorUtility.AddTag(tag); //在tag列表中添加这个tag
        }

        gameObject.tag = tag;
    }

5、Dotween对数值进行递增或递减

    float startNum = 0f;
    float targetNum = 1f;
    public void DOTweenNum(Action  cb)
    {
        DOTween.To(() => startNum, x => startNum = x, targetNum, 10).
            SetEase(Ease.Linear).OnComplete(() => {
                cb?.Invoke();
            });
    }

    void Update()
    {

        if (Input.GetKeyDown(KeyCode.F8))
        {
            DOTweenNum(()=> { Debug.Log($"******{startNum}*****"); });
        }
    }

6、鼠标双击

using System;
using UnityEngine;

public class DoubleClickMouseButton : MonoBehaviour
{
    /// 
    /// 鼠标双击的间隔
    /// 
    private float doubleClickTime = 0.2f;

    /// 
    /// 上一次点击鼠标抬起的时间
    /// 
    private double lastClickTime;

    void Start()
    {
        lastClickTime = Time.realtimeSinceStartup;
    }

    private void Update()
    {
        DoubleClickMouseButtonEvent(0, () =>
        {
            //ToDo 双击所要执行的事件
        });
    }

    /// 
    /// 鼠标双击执行的事件
    /// 
    /// 鼠标按键
    /// 双击需要执行的事件
    private void DoubleClickMouseButtonEvent(int mouseBtnIndex, Action action)
    {
        if (Input.GetMouseButtonDown(mouseBtnIndex)) //双击鼠标右键聚焦
        {
            if (Time.realtimeSinceStartup - lastClickTime < doubleClickTime)
            {
                action();
            }

            lastClickTime = Time.realtimeSinceStartup;
        }
    }
}

7、获取模型Bound中心点

using UnityEngine;

namespace MT_Exterensions
{
    public static class GameObjectExtensions
    {
        public static Bounds CalculatePreciseBounds(this GameObject gameObject)
        {
            Bounds bounds = new Bounds();
            bool flag = false;
            MeshFilter[] componentsInChildren1 = gameObject.GetComponentsInChildren();
            if (componentsInChildren1.Length != 0)
            {
                bounds = GetMeshBounds(componentsInChildren1[0].gameObject, componentsInChildren1[0].sharedMesh);
                flag = true;
                for (int index = 1; index < componentsInChildren1.Length; ++index)
                    bounds.Encapsulate(GetMeshBounds(componentsInChildren1[index].gameObject,
                        componentsInChildren1[index].sharedMesh));
            }

            SkinnedMeshRenderer[] componentsInChildren2 = gameObject.GetComponentsInChildren();
            if (componentsInChildren2.Length != 0)
            {
                Mesh mesh = new Mesh();
                if (!flag)
                {
                    componentsInChildren2[0].BakeMesh(mesh);
                    bounds = GetMeshBounds(componentsInChildren2[0].gameObject, mesh);
                }

                for (int index = 1; index < componentsInChildren2.Length; ++index)
                {
                    componentsInChildren2[index].BakeMesh(mesh);
                    bounds = GetMeshBounds(componentsInChildren2[index].gameObject, mesh);
                }

                Object.Destroy(mesh);
            }

            return bounds;
        }

        private static Bounds GetMeshBounds(GameObject gameObject, Mesh mesh)
        {
            Bounds bounds = new Bounds();
            Vector3[] vertices = mesh.vertices;
            if (vertices.Length != 0)
            {
                bounds = new Bounds(gameObject.transform.TransformPoint(vertices[0]), Vector3.zero);
                for (int index = 1; index < vertices.Length; ++index)
                    bounds.Encapsulate(gameObject.transform.TransformPoint(vertices[index]));
            }

            return bounds;
        }

        public static Bounds CalculateBounds(this GameObject gameObject, bool localSpace = false)
        {
            Vector3 position = gameObject.transform.position;
            Quaternion rotation = gameObject.transform.rotation;
            Vector3 localScale = gameObject.transform.localScale;
            if (localSpace)
            {
                gameObject.transform.position = Vector3.zero;
                gameObject.transform.rotation = Quaternion.identity;
                gameObject.transform.localScale = Vector3.one;
            }

            Bounds bounds1 = new Bounds();
            Renderer[] componentsInChildren = gameObject.GetComponentsInChildren();
            if (componentsInChildren.Length != 0)
            {
                Bounds bounds2 = componentsInChildren[0].bounds;
                bounds1.center = bounds2.center;
                bounds1.extents = bounds2.extents;
                for (int index = 1; index < componentsInChildren.Length; ++index)
                {
                    Bounds bounds3 = componentsInChildren[index].bounds;
                    bounds1.Encapsulate(bounds3);
                }
            }

            if (localSpace)
            {
                gameObject.transform.position = position;
                gameObject.transform.rotation = rotation;
                gameObject.transform.localScale = localScale;
            }

            return bounds1;
        }

        /// 
        /// 获取模型的Bounds
        /// 
        /// 
        /// 
        public static Bounds CalculateModelBounds(GameObject gameObject)
        {
            Bounds bounds = gameObject.CalculateBounds(false);
            return bounds;
        }
    }
}

8、绘制相机视野

using UnityEngine;

/// 
/// 绘制相机视野范围
/// 
public class ShowCameraFieldOfView : MonoBehaviour
{
    private Camera mainCamera;
    private void OnDrawGizmos()
    {
        if (mainCamera == null)
            mainCamera = Camera.main;
        Gizmos.color = Color.green;
        //设置gizmos的矩阵   
        Gizmos.matrix = Matrix4x4.TRS(mainCamera.transform.position, mainCamera.transform.rotation, Vector3.one);
        Gizmos.DrawFrustum(Vector3.zero, mainCamera.fieldOfView, mainCamera.farClipPlane, mainCamera.nearClipPlane, mainCamera.aspect);
    }
}

9、编辑器扩展,复制物体的Position和Roation

using UnityEditor;
using UnityEngine;

/// 
/// 放在Editor目录下
/// 选中物体之后,在扩展窗口选择复制的选项,就可以将选中的物体的transform信息位置复制下来,然后在要复制的地方Ctrl+V就可以复制出来
/// 
public class CopyObjTransformData : Editor
{
    /// 
    /// 复制Position
    /// 
    [UnityEditor.MenuItem("复制节点Transform信息/复制坐标")]
    static void CopyXYZ()
    {
        GameObject obj = UnityEditor.Selection.activeGameObject;
        if (obj != null)
        {
            string ret = obj.transform.localPosition.x + "f,"
                                                       + obj.transform.localPosition.y + "f,"
                                                       + obj.transform.localPosition.z + "f";
            GUIUtility.systemCopyBuffer = ret;
        }
    }

    /// 
    /// 复制Rotation
    /// 
    [UnityEditor.MenuItem("复制节点Transform信息/复制旋转")]
    static void CopyObjRotation()
    {
        GameObject obj = UnityEditor.Selection.activeGameObject;
        if (obj != null)
        {
            string ret = obj.transform.localEulerAngles.x + "f," + obj.transform.localEulerAngles.y + "f," +
                         obj.transform.localEulerAngles.z + "f";
            GUIUtility.systemCopyBuffer = ret;
        }
    }
}

 10、鼠标拖动物体移动

using System.Collections;
using UnityEngine;

/// 
/// 完成两个步骤:
//  1.由于鼠标的坐标系是2维,需要转换成3维的世界坐标系  
//  2.只有3维坐标情况下才能来计算鼠标位置与物理的距离,offset即是距离
//将鼠标屏幕坐标转为三维坐标,再算出物体位置与鼠标之间的距离
/// 
public class DragObjMove : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(OnMouseDown());
    }

    IEnumerator OnMouseDown()
    {
        //将物体由世界坐标系转换为屏幕坐标系
        Vector3 screenSpace = Camera.main.WorldToScreenPoint(transform.position);//三维物体坐标转屏幕坐标
 
        Vector3 offset = transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenSpace.z));
        while (Input.GetMouseButton(0))
        {
            //得到现在鼠标的2维坐标系位置
            Vector3 curScreenSpace = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenSpace.z);
            //将当前鼠标的2维位置转换成3维位置,再加上鼠标的移动量
            Vector3 curPosition = Camera.main.ScreenToWorldPoint(curScreenSpace) + offset;
            //curPosition就是物体应该的移动向量赋给transform的position属性
            transform.position = curPosition;
            yield return new WaitForFixedUpdate(); //这个很重要,循环执行
        }

    }
}

11、逐渐注视目标方向旋转

    /// 
    /// 逐渐注视目标点旋转
    /// 
    /// 变换组件
    /// 目标点
    /// 旋转速度
    public static void LookPostion(Transform targetTF, Vector3 targetPos, float rotateSpeed)
    {
        Vector3 dir = targetPos - targetTF.position;
        LookDirection(targetTF, dir, rotateSpeed);
    }

    /// 
    /// 逐渐注视目标方向旋转
    /// 
    /// 变换组件
    /// 目标方向
    /// 旋转速度
    public static void LookDirection(Transform targetTF, Vector3 targetDir, float rotateSpeed)
    {
        //如果需要注视零方向
        if (targetDir == Vector3.zero) return;
        //transform.LookAt(目标点);      一帧旋转到位
        Quaternion dir = Quaternion.LookRotation(targetDir);
        targetTF.rotation = Quaternion.Lerp(targetTF.rotation, dir, Time.deltaTime * rotateSpeed);
    }

12、对象池

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
 
/// 
/// 对象池
/// 
public class GameObjectPool : MonoSingleton
{ 
    //1.对象池
    private Dictionary> cache;
    //private Dictionary> obj = new Dictionary>();
    //初始化:在对象创建时执行一次
    protected override void Init()
    {
        base.Init();
        cache = new Dictionary>();
    }
 
    //2.创建对象
    /// 
    /// 通过对象池创建对象
    /// 
    /// 需要创建的对象种类
    /// 需要创建的预制件
    /// 创建的位置
    /// 创建的旋转
    /// 
    public GameObject CreateObject(string key, GameObject prefab, Vector3 pos, Quaternion dir)
    {   
        //在池中查找 
        GameObject tempGo = FindUsableObject(key);
        //如果没有找到
        if (tempGo == null)
        {
            //创建物体 
            tempGo = Instantiate(prefab);
            //加入池中
            Add(key, tempGo);
            //将通过对象池创建的物体,存入对象池子物体列表中。
            tempGo.transform.SetParent(transform);
        }
        //使用
        UseObject(tempGo, pos, dir);
        return tempGo;
    }
 
    private void UseObject(GameObject go,Vector3 pos, Quaternion dir)
    {  
        //先设置位置
        go.transform.position = pos;
        go.transform.rotation = dir;
        //再启用物体
        go.SetActive(true);  
        //重置通过对象池创建物体的所有脚本对象
        foreach (var item in go.GetComponentsInChildren())
        {
            item.OnReset();
        }
    }
 
    private void Add(string key, GameObject tempGo)
    {
        //如果池中没有键  则 添加键
        if (!cache.ContainsKey(key)) cache.Add(key, new List());
        //将物体加入池中
        cache[key].Add(tempGo);
    }
 
    private GameObject FindUsableObject(string key)
    {
        if (cache.ContainsKey(key))
        {
            //  public delegate bool Predicate(T obj);
            //查找池中禁用的物体
            return cache[key].Find(o => !o.activeInHierarchy);
        }
        return null;
    }
 
    //3.即时回收
    public void CollectObject(GameObject go)
    {
        go.SetActive(false);
    }
 
    //4.延迟回收
    public void CollectObject(GameObject go, float delay)
    {
        StartCoroutine(DelayCollect(go, delay));
    }
 
    private IEnumerator DelayCollect(GameObject go, float delay)
    {
        yield return new WaitForSeconds(delay);
        CollectObject(go);
    }
 
    //5.清空
    public void ClearAll()
    { 
        //将字典中所有键存入集合
        List listKey =new List(cache.Keys);
        foreach (var item in listKey)
        {
            //遍历集合元素 删除字典记录
            Clear(item);
        }
    }
 
    public void Clear(string key)
    { 
        //倒序删除
        for (int i = cache[key].Count -1; i>=0 ; i--)
        {
            Destroy(cache[key][i]);
        }
 
        //在字典集合中清空当前记录(集合列表)
        cache.Remove(key);
    }
}

13、将角度限制在360

private float Clamp0360(float eulerAngles)
{
float result=eulerAngles-Mathf.CeilToInt(eulerAngles/360f)*360f;
if        (result<0)
{
result+=360f;
}
return result;
}

 14、获取动画状态机animator的动画clip的播放持续时长

    /// 
    /// 获取动画状态机animator的动画clip的播放持续时长
    /// 
    /// 
    /// 
    /// 
    public float GetClipLength(Animator animator, string clipName)
    {
        if (null == animator || string.IsNullOrEmpty(clipName) || null == animator.runtimeAnimatorController)
            return 0;
        // 获取所有的clips	
        var clips = animator.runtimeAnimatorController.animationClips;
        if (null == clips || clips.Length <= 0) return 0;
        AnimationClip clip;
        for (int i = 0, len = clips.Length; i < len; ++i)
        {
            clip = clips[i];
            if (null != clip && clip.name == clipName)
                return clip.length;
        }
        return 0f;
    }

15、更新血条位置


void LateUpdate() {
    var sPos = RectTransformUtility.WorldToScreenPoint(Camera.main, ch.transform.position);
    var pos = Vector2.zero;
    if (RectTransformUtility.ScreenPointToLocalPointInRectangle(pTrans, sPos, null, out pos)) {
        curTrans.anchoredPosition = pos;
    }
}

16、简单心跳

using System;
using UnityEngine;

public class Test : MonoBehaviour {

    /// 
    /// 服务器时间
    /// 
    private long serverTime;

    public long ServerTime
    {
        get
        {
            return serverTime;
        }

        set
        {
            serverTime = value;
        }
    }

    /// 
    /// 是否连接
    /// 
    private bool isConnecct;

    /// 
    /// 上一次心跳时间
    /// 
    private DateTime lastHeartTime;

    /// 
    /// 心跳间隔
    /// 
    private float Send_Heart_Interval = 10f;

	
	// Update is called once per frame
	void Update () {
        SendHeartBeat();
    }


    private void SendHeartBeat()
    {
        DateTime dt = DateTime.UtcNow;
        TimeSpan ts = dt - lastHeartTime;
        if (ts.TotalSeconds>=Send_Heart_Interval)
        {
            //客户端给服务器发消息
            //SendC2S();
            lastHeartTime = dt;
            Debug.Log($"****{lastHeartTime}****");
        }
    }


    private void HeartBeatResponse()
    {
        //ServerTime = Convert.ToInt64("");
    }
}

17、数据改变回调

/****************************************************
    文件:NotifyObject.cs
	作者:Edision
    日期:#CreateTime#
	功能:数据改变回调
*****************************************************/

using System.ComponentModel;
using System.Runtime.CompilerServices;
using UnityEngine;

public class NotifyObject : MonoBehaviour, INotifyPropertyChanged
{
    private int number;
    public int Number
    {
        get { return number; }
        set { UpdateProper(ref number, value); }
    }

    protected void UpdateProper(ref T properValue, T newValue, [CallerMemberName] string properName = "")
    {
        if (object.Equals(properValue, newValue))
        {
            Debug.LogWarning("值未改变");
            return;
        }

        properValue = newValue;
        OnPropertyChanged(properName);
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    private void Do(object sender, PropertyChangedEventArgs property)
    {
        switch (property.PropertyName)
        {
            case "Number":
                Debug.LogError($"值被改变:{Number}");
                break;
        }
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.P))
        {
            Debug.Log(Number);
            PropertyChanged = null;
            PropertyChanged += Do;
            Number = 0;
        }

        if (Input.GetKeyDown(KeyCode.O))
        {
            Debug.Log(Number);
            PropertyChanged = null;
            PropertyChanged += Do;
            Number = 1;
        }
    }
}

18、Unity动画系统Animator动态添加事件

/****************************************************
    文件:TestAnimator.cs
	作者:Edision
    日期:#CreateTime#
	功能:Unity动画系统Animator动态添加事件
*****************************************************/

using UnityEngine;

public class TestAnimator : MonoBehaviour 
{

    #region --变量定义
    private Animator animator;
    private AnimationClip[] clips;
    #endregion

    #region --系统函数
    private void Awake()
    {
        animator = this.GetComponent();
    }

    private void Start()
    {       
        clips = animator.runtimeAnimatorController.animationClips;

        AnimationClip _clip = clips[0];
        AddAnimationEvent(animator, _clip.name, "StartEvent", 0);
        AddAnimationEvent(animator, _clip.name, "HalfEvent", _clip.length * 0.5f);
        AddAnimationEvent(animator, _clip.name, "EndEvent", _clip.length);
    }
    private void OnDestroy()
    {
        CleanAllEvent();
    }
    #endregion

    #region --自定义函数
    private void StartEvent()
    {
        Debug.Log("开始播放动画");
    }
    private void HalfEvent()
    {
        Debug.Log("动画播放了一半");
    }
    private void EndEvent()
    {
        Debug.Log("播放动画完毕");
    }

    /// 
    /// 添加动画事件
    /// 
    /// 
    /// 动画名称
    /// 事件方法名称
    /// 添加事件时间。单位:秒
    private void AddAnimationEvent(Animator _animator, string _clipName, string _eventFunctionName, float _time)
    {
        AnimationClip[] _clips = _animator.runtimeAnimatorController.animationClips;
        for (int i = 0; i < _clips.Length; i++)
        {
            if (_clips[i].name == _clipName)
            {
                AnimationEvent _event = new AnimationEvent();
                _event.functionName = _eventFunctionName;
                _event.time = _time;
                _clips[i].AddEvent(_event);
                break;
            }
        }
        _animator.Rebind();
    }
    /// 
    /// 清除所有事件
    /// 
    private void CleanAllEvent()
    {
        for (int i = 0; i < clips.Length; i++)
        {
            clips[i].events = default(AnimationEvent[]);
        }
        Debug.Log("清除所有事件");
    }
    #endregion

}

19、字幕轮播

/****************************************************
    文件:CarouselText.cs
	作者:Edision
    日期:#CreateTime#
	功能:字幕轮播
*****************************************************/

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

public class CarouselText : MonoBehaviour
{
    /// 
    /// 循环间隔
    /// 
    public float timer = 2f;

    /// 
    /// 轮播的语句
    /// 
    private List strLst;

    /// 
    /// 轮播下表
    /// 
    private int textIndex = -1;

    /// 
    /// 轮播语句UI_Text
    /// 
    public Text text;

    private void Awake()
    {
        strLst = new List();
        strLst.Add("这是string01");
        strLst.Add("这是string02");
        strLst.Add("这是string03");
        strLst.Add("这是string04");
    }
    void Start()
    {
        InvokeRepeating(methodName: "ChangeText", time: 0, repeatRate: timer);
    }

    void ChangeText()
    {
        text.text = strLst[++textIndex % strLst.Count];
    }

    private void FixedUpdate()
    {
        //TODO:可修改遮挡和重新复位
        text.gameObject.transform.Translate(Vector3.left);
    }

    private void OnDestroy()
    {
        CancelInvoke(methodName: "ChangeText");
    }
}

20、unity运行状态下不刷新脚本

/****************************************************
    文件:CompilerOptionsEditorScript.cs
	作者:Edision
    日期:#CreateTime#
	功能:阻止PlayMode时编译脚本
*****************************************************/

using UnityEditor;
using UnityEngine;

[InitializeOnLoad]
public class CompilerOptionsEditorScript
{
    static bool waitingForStop = false;

    static CompilerOptionsEditorScript()
    {
        EditorApplication.update += OnEditorUpdate;
    }

    static void OnEditorUpdate()
    {
        if (!waitingForStop
            && EditorApplication.isCompiling
            && EditorApplication.isPlaying)
        {
            EditorApplication.LockReloadAssemblies();
            EditorApplication.playmodeStateChanged
                 += PlaymodeChanged;
            waitingForStop = true;
        }
    }

    static void PlaymodeChanged()
    {
        if (EditorApplication.isPlaying)
            return;

        EditorApplication.UnlockReloadAssemblies();
        EditorApplication.playmodeStateChanged
             -= PlaymodeChanged;
        waitingForStop = false;
    }
}

21、Game视窗还原Sence视窗功能

/****************************************************
    文件:SceneViewCamera.cs
	作者:Edision
    日期:#CreateTime#
	功能:Game视窗还原Sence视窗功能
*****************************************************/

using UnityEngine;


/// 
/// Make it possible to operate cameras like Scene view in Game view.
/// 
[RequireComponent(typeof(Camera))]
public class SceneViewCamera : MonoBehaviour
{
    [SerializeField, Range(0.1f, 100f)]
    private float wheelSpeed = 1f;

    [SerializeField, Range(0.1f, 100f)]
    private float moveSpeed = 0.3f;

    [SerializeField, Range(0.1f, 1f)]
    private float rotateSpeed = 0.3f;

    private Vector3 preMousePos;

    private void Update()
    {
        MouseUpdate();
        return;
    }

    private void MouseUpdate()
    {
        float scrollWheel = Input.GetAxis("Mouse ScrollWheel");
        if (scrollWheel != 0.0f)
            MouseWheel(scrollWheel);

        if (Input.GetMouseButtonDown(0) ||
           Input.GetMouseButtonDown(1) ||
           Input.GetMouseButtonDown(2))
            preMousePos = Input.mousePosition;

        MouseDrag(Input.mousePosition);
    }

    private void MouseWheel(float delta)
    {
        transform.position += transform.forward * delta * wheelSpeed;
        return;
    }

    private void MouseDrag(Vector3 mousePos)
    {
        Vector3 diff = mousePos - preMousePos;

        if (diff.magnitude < Vector3.kEpsilon)
            return;

        if (Input.GetMouseButton(2))
            transform.Translate(-diff * Time.deltaTime * moveSpeed);
        else if (Input.GetMouseButton(1))
            CameraRotate(new Vector2(-diff.y, diff.x) * rotateSpeed);

        preMousePos = mousePos;
    }

    public void CameraRotate(Vector2 angle)
    {
        transform.RotateAround(transform.position, transform.right, angle.x);
        transform.RotateAround(transform.position, Vector3.up, angle.y);
    }
}

22、画面质量设置:低,中,高

 if (Input.GetMouseButtonUp(2))
        {
            for (int i = 0; i < QualitySettings.names.Length; i++)
            {
                Debug.Log(QualitySettings.names[i].ToString());
            }
            QualitySettings.SetQualityLevel(3, true);
            Debug.Log((QualityLevel)QualitySettings.GetQualityLevel());
        }

23、一键创建unity所必须的基础文件夹

/****************************************************
    文件:GenerateFolders.cs
	作者:Edision
    日期:#CreateTime#
	功能:一键创建unity所必须的基础文件夹
*****************************************************/

using UnityEngine;
using System.IO;

#if UNITY_EDITOR
using UnityEditor;
#endif

/// 
/// 1.一键创建unity所必须的基础文件夹
/// 2.节省工作量,提升效率
/// 3.杜绝命名出错,因为有些文件夹是必须拼写正确才能正常运行 例如:Resources等
/// Directory.CreateDirectory的内部原理是存在文件则不创建,不存在才创建
/// 

public class GenerateFolders 
{
#if UNITY_EDITOR

	static string folderRoot = "Game";

	[MenuItem("Tools/CreateBaseFolder")]
	private static void CreateBaseFolder()
	{
		GenerateFolder(0);
		Debug.Log("Folders Created");
	}

	[MenuItem("Tools/CreateALLFolder")]
	private static void CreateAllFolder()
	{
		GenerateFolder(1);
		Debug.Log("Folders Created");
	}

	private static void GenerateFolder(int flag = 0)

	{
		//文件路径
		string prjPath = Application.dataPath + "/" + folderRoot + "/";

		Directory.CreateDirectory(prjPath + "Animations");//动作片段  
		Directory.CreateDirectory(prjPath + "FX"); //特效
		Directory.CreateDirectory(prjPath + "Materials"); //材质
		Directory.CreateDirectory(prjPath + "Models");  //模型
		Directory.CreateDirectory(prjPath + "Prefabs"); //预设体
		Directory.CreateDirectory(prjPath + "Textures"); //纹理图片
		Directory.CreateDirectory(prjPath + "Scenes"); //场景
		Directory.CreateDirectory(prjPath + "Scripts"); //脚本

		if (1 == flag)
		{
			Directory.CreateDirectory(prjPath + "Standard Assets");
			Directory.CreateDirectory(prjPath + "Editor");//
			Directory.CreateDirectory(prjPath + "Sprites");//
			Directory.CreateDirectory(prjPath + "Images");//
			Directory.CreateDirectory(prjPath + "Audios");//音效  Music(音乐相关的部分)/ SFX(特效音乐相关的部分)
			Directory.CreateDirectory(prjPath + "Fonts"); //字体
			Directory.CreateDirectory(prjPath + "Shaders"); //着色器
			Directory.CreateDirectory(prjPath + "Plugins"); //
			Directory.CreateDirectory(prjPath + "Resources"); //需要动态加载的资源放在这里,不管有没有使用都会全部打包
			Directory.CreateDirectory(prjPath + "StreamingAssets"); //这个目录将自动打包到导出程序,用Application.streamingAssetsPath读取
			Directory.CreateDirectory(prjPath + "Gizmos");
			Directory.CreateDirectory(prjPath + "Others");
		}

		AssetDatabase.Refresh();
	}
#endif
}

24、关闭日志输出

Debug.unityLogger.logEnabled = false;

25、脚本执行顺序

using UnityEngine;

[DefaultExecutionOrder(-1000)]
public class TestOrder01 : MonoBehaviour 
{
    private void Awake()
    {
        Debug.Log("TestOrder01");
    }
}
using UnityEngine;

[DefaultExecutionOrder(-5000)]
public class TestOrder02 : MonoBehaviour 
{
    private void Awake()
    {
        Debug.Log("TestOrder02");
    }
}

end

你可能感兴趣的:(自用工具,unity)