Unity技巧

  • 可以复制动态生成的物体,然后在编辑器模式把动态物体粘贴下来
  • EditorSceneManager可以自动保持场景
  • 利用指针,可以打开一个界面的同时,关闭一个当前打开的
  • 掌握了预制体精髓用法,就等于减少了50%的复杂度
  • 通过递归给所有btn加同一个按钮音效
  • 按住ctrl不放,然后点击,可以随意增删选择,另外unity是可以保持选择的
  • alt+shift+a快速关闭开启一个预制体
  • 横屏高1,多个canvans做法
  • 组件的写法,btn事件拖拽不需要脚本,多个场景共享不毁坏的,做成预制体,然后做成单例模式重复就销毁
  • 动画状态机 float bool trigger 就够了
  • 多个canvans写法
  • Ins面板,上下文调用函数很好啊,[Tooltip]加注释 [space]加空格
    [ContextMenu("Do Something")]
    void DoSomething()
    {
        Debug.Log("Perform operation");
    }
  • 许多测试小场景,利用场景
  • 没搞懂这个怎么实现的
  • 在这里插入图片描述
  • 事件如下代码
    [Serializable]
    public class  JJw:UnityEvent<int>
    {
        
    }
  • 多翻阅api,其一有api运用可以说是api最佳实践了,其二有一些很好的api不用自己做了比如下面的
    • Physics2D.queryHitTriggers 射线广播是否检测到配置为触发器的碰撞器?
    • Physics2D.queryStartInColliders
  • 轻量级事件更新UI
  • Canvas下面还能有Canvas而且样子不一样呢
  • 属性使用最佳实践,如果是excel策划表一开始用快速属性,如果是Unity内置面板做策划配置,优先使用字段,哪怕是公共字段,只要控制其只能被内部使用,就不会有太大复杂度管理,关键是所见所得调整参数太爽了然后逼不得已才重构成快速属性,快速属性不能的时候才用完整属性,并且set一定要为private,get不用做修改了,除非get要控制private,这样才能更改。不要用快捷属性实现readonly,不要用const实现readonly,用static readonly替代呢。
  • 属性使用最佳实践补充:当然了,还有一种方法可以兼顾上面两种特点,即可调整,又用到了属性,unity是支持边修改边编译的
    [SerializeField] private float speed = 0.2f;

    public float Speed
    {
        get { return speed; }
        private set { speed = value; }
    }


    private void Start()
    {
    }

    private void Update()
    {
        transform.Translate(Vector3.up * Time.deltaTime * Speed);
    }
  • 抽象泛型组件类是代码复用的利器,但是请注意不能太过抽象,不然复杂度也增加了,最好就一层,泛型计算可以参考下面技术
    private void Start()
    {
        // Convert.ChangeType 返回一个指定类型的对象,该对象的值等效于指定的对象。
        // Type.GetTypeCode 获取指定 Type 的基础类型代码。
        // dynamic 
        // TypeDescriptor.GetConverter 返回组件或类型的类型转换器。
        // Double 用最大容器的思想再转换的思想

        int k = Sum111(1, 2);
        float k2 = Sum111(3f, 3f);
        print(k);

    }

    private static T Sum<T>(T num1,T num2) where T : struct
    {
        dynamic v1 = num1;
        dynamic v2 = num2;
        return (T)(v1 + v2);
    }
    
    T Sum111<T> (params T [] numbers) where T:struct
    {
        double total =0;
        foreach (var value in numbers)
            total = total + Double.Parse(value.ToString());
        return (T)Convert.ChangeType(total,typeof(T));
    }
    
    public static T Sum222<T>(params T[] input) where T : struct
    {
        return (T)TypeDescriptor.GetConverter(default(T).GetType()).ConvertFrom(input.Sum(p => { return (double)((dynamic)p); }).ToString());
    }
  • 使用dynatic简化反射,还可提高性能据说
    public class Chiwo
    {
        public void Kaiche()
        {
            Debug.Log("kaiche");
        }
    }

    public class Temp : MonoBehaviour
    {
        private void Start()
        {
            Type t = typeof(Chiwo);
            
            //1种
            var obj = Activator.CreateInstance(t);
            var m = t.GetMethod("Kaiche");
            m.Invoke(obj, new object[] { });


            //2种
            dynamic bike = Activator.CreateInstance(t);
            bike.Kaiche();

        }
        
    }
  • 目前都用Start,并且都不用脚本执行顺序编辑,只是子脚本,如何管理,需要Init(),值得商榷,暂时不想用呢
  • UI模块化,层级化方便修改做锚点
  • SpriteAtlas自动设置一些东西
  • 音频再设置volume和loop
  • GUI.Label也可以用用方便嘛
  • RNGCryptoServiceProvider 类加密服务!!
  • SceneManager.MoveGameObjectToScene(gameObject, SceneManager.GetActiveScene());移动物体到场景
  • 抽象泛型类,使用了抽象泛型类的静态方法,有点6
  • 继承自泛型的IComparer
  • Enum.IsDefined判断枚举是否存在
  • 获取 DateTime todayStart = new DateTime(now.Year, now.Month, now.Day, 0, 0, 0, 0);获取今日转到信息
  • 可以使用System.Net的HttpWebRequest
  • 在面板设置GM管理,比在代码用Consts要好,因为没有侵入,仅仅相当于测试
  • new System.Diagnostics.ProcessStartInfo();运行脚本,里面有很多参数设置,并且嵌套using
  • List.Foreach多用用
  • 多用接到事件消息后,把move组件给移除,暂时不要做什么Update()里面的状态判断return,因为消耗性能,还要多种状态判断起来很麻烦不优雅。
  • 纯UI游戏
  • ExecuteInEditMode特性不用挂载
  • BuildPipeline打包相关,UIPanel转参数
  • 锚点如果不是为了设置位置,只需要设置最最最最外层搞一个锚点就行了,
  • SVN可以局部还原
  • 使用拓展放过对string类实例和静态拓展,暂时放弃Utils
  • ScriptObject带逻辑复用https://www.bilibili.com/video/BV1eA411p7Ra
  • 不断抽象改进工作流程
  • 策划的excel很重要的
  • UI不要带状态逻辑,全靠另一数据类来驱动,显示和逻辑分离
  • 游戏状态暂时忽略START,不然我真的不知道怎么来写了,Start继承复写暂时先用着
  • 非UI2D可以添加SortingGroud组件
  • 继承自TileBase,和重新绘制Editor,OnInspectorGUI,EditorWindow,IPreprocessShaders中
  • [HelpURL(“https://github.com/Unity-Technologies/NavMeshComponents#documentation-draft”)]
  • EventSystem.current.SetSelectedGameObject,委托的使用,不一定要用事件,其实就是UI聚焦时候的名字而已
EventSystem.current.currentSelectedGameObject.name
  • 特性连写
  • [DefaultExecutionOrder(100)]特性,脚本优先级,越小越优先经过实验
  • [InitializeOnLoad]特性 InitializeOnLoad 属性应用的对象是 静态构造函数,它可以保证在编辑器启动的时候调用此函数。根据这个特性,可以在编辑器中设置定期的回调(帧更新),来实现类似watchFile的
    功能。这里借助了EditorApplication类中的 update 委托,在编辑器运行时,它将每秒调用多次。
[InitializeOnLoad]
public static class JKL 
{
     static JKL()
     {
         EditorApplication.update += Update;
     }

      static void Update()
     {
         Debug.Log("woaini");
     }
}

  • [CustomPropertyDrawer(typeof (RequireInterfaceAttribute))]特性
  •         Canvas.ForceUpdateCanvases();
    
  • [CustomEditor(typeof(UITable), true)]
  • OnDrawGizmosSelected ,函数OnDrawGizmosSelected()在鼠标打击到脚本挂载的物体的身上的时候运行,是编辑器下的选择
    private void OnDrawGizmos()
    {Gizmos.DrawCube(transform.position,Vector3.one);
    }

    private void OnDrawGizmosSelected()
    {
        Gizmos.DrawSphere(transform.position,2f);
    }
  • 继承自特性
[AttributeUsage(AttributeTargets.Field)]
public sealed class RequireInterfaceAttribute : PropertyAttribute
{
    public readonly Type type;

    public RequireInterfaceAttribute(Type value)
    {
        if (!value.IsInterface)
        {
            throw new Exception("Type must be an interface!");
        }
        type = value;
    }
}
  • 上面的特性还能继承,还可以指定谁可以用特性
[JJJKKK]
[DefaultExecutionOrder(2)]
public class JKL : UnityEngine.MonoBehaviour
{
    private void Start()
    {
        print("jkl");
    }
}

[AttributeUsage(AttributeTargets.Class)]
public sealed class JJJKKK : PropertyAttribute
{
    
}
  • 利用上下文菜单做测试,更加非侵入,比如编辑器拓展我感觉还要好点,当然了只有对应脚本的对象才有
    [ContextMenu("Gamewin")]
    public void GameWin()
    {
        print("gamewin");
    }
  • 结构中可以放事件
  • ,连写,monobehaviour做静态方法根本就不需要挂载,同样当静态类使用
  • ImageEffectAllowedInSceneView,具有此属性的任何图像效果可以渲染到场景视图相机中
  • Multline特性 string多行
  • Delayd特性 按回车才能修
  • Mono单脚本自控自打,最后enabled =false
  • 多个场景共存来显示游戏,解耦
  • Unity Struct Panel获取面到点的距离
  GetComponent<Plane>().GetDistanceToPoint(Vector3.zero);
  • 这时候就需要用到CustomEditor属性了。创建一个ExampleEditor脚本,在类上添加[CustomEditor(typeof(T))]属性,重写OnInspectorGUI方法,用于扩展Inspector。
  • 特性类效果可以继承,partiral关键字暂时不可以继承
  • 继承自ScriptableObject的类不能使用new来创建,要使用ScriptableObject.CreateInstance()方法来创建
  • InitializeOnLoad、InitializeOnLoadMethod、RuntimeInitializeOnLoadMethod特性的使用
  • EditorBuildSettingsScene用于场景列表中的条目,如 Build Settings 窗口中所示。此类包含场景的场景路径和一个启用标志,该标志用于指示是否在 BuildSettings 窗口中启用了场景。
  • ModuleManager在Unity中有啥用啊
  • MonoSingleton.mInstance = null;
  • UnityEditor.EditorApplication.playModeStateChanged播放模式状态被改变
  • 带ref参数的lambada表达式
  • t:Prefab t:Mesh t:Scene t:Model t:ScriptableObject
  • is 中可以加一个类关键字
  • unity组件可以转换boolean
  • 一帧中先InverseLerp再Lerp
		if ( m_isFading )
		{
			if ( Time.time >= m_endTime )
			{
				// 经过淡入淡出时间后首次 Update

				// 将alpha值改为目标值
				m_currentAlpha = m_destinationAlpha;
				this.ui_image.color = new Color(0.0f, 0.0f, 0.0f, m_currentAlpha);

				// 淡入过程结束后将 GUITexture 设置为无效
				if ( m_destinationAlpha < 0.25f )	// 因为是float类型所以不能通过 == 0.0f 来判断
				{
					this.fade_go.SetActive(false);
				}

				// 淡入淡出结束
				m_isFading = false;
			}
			else
			{
				// 进度(0.0~1.0)
				float ratio = Mathf.InverseLerp( m_beginTime, m_endTime, Time.time );

				// 修改alpha值
				this.ui_image.color = new Color(0.0f, 0.0f, 0.0f, Mathf.Lerp(m_currentAlpha, m_destinationAlpha, ratio));
			}
		}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值