前言
喜❤欢❤请❤点❤赞
编程习惯
- 代码命名和书写规则可以参考alibaba tx netease都有出手册..这个很重要是共同开发的基础
- 单个类内容太多的时候,可以用partial分隔类
- 参数多的时候,可以封装为一个struct
- if else太长的时候,可以多换行能一次写完的都写在一起
- 不要在参数内嵌套方法 考虑到单行长度和debug的时候不知道错误出在哪里
使用Visual Studio作为编辑器
●安装 --- unity2017以后的版本,不自带Mono了,但安装Unity时可勾选安装vs,安装vs也可勾选安装Unity,官方互gay
●调试 --- 如果不会,必须学习,调试是快速debug的重要方法。vs可一键Unity断点调试,改完代码F5Unity那边也跑起来了
●快捷键 --- 修改快捷键ctrl+w关闭当前窗口的方法,照着这样改成你自己的习惯,希望vs啥时候出个设置保存云..
●搜索 --- 使用“ Ctrl + ; ” 打开可以搜索类和方法,输入栏右方设置搜索是否包括方法;使用“ Ctrl+T/, ”可以搜索脚本内的方法
●阅读 --- 可以使用使用 #region和#endregion,用于代码的缩放,对于代码阅读编辑相当好。
●标签 --- 灵活使用标签例如//TODO就可以标注将会做(其实是骗自己...)之后可以在 视图→任务列表 查看
●DLL --- vs还可以生成解决方案DLL,然后拉过去或代码功能自动复制一份到UnityAsset内就可以给Unity使用了
Unity常用API
- 按键Input
void Update() { if (Input.GetKey("up")) { print("up arrow key is held down"); } if (Input.GetKeyDown("down")) { print("down arrow key is held down"); } }
- OnGUI 与 Log
void OnGUI() { if (GUI.Button(new Rect(10, 10, 150, 100), "I am a button")) { Debug.Log("<color=#9400D3> You clicked the button! </color>"); //green 绿色 #008000ff red 红色 #ff0000ff //white 白色 #ffffffff yellow 黄色 #ffff00ff /*转义符 \’ 单引号符 \” 单引号符 \\ 反斜线符"\" \n 换行 \r 回车 text在运行后\会自动变成了\\,所以无效解决方法: msgText.text = msg.Replace("\\n", "\n"); */ } }
- 旋转与位移
DOTween//-------------旋转------------ // //设置角度 transform.rotation = Quaternion.Euler(new Vector3(100,0,0)); transform.rotation = Quaternion.AngleAxis(30, Vector3.up);//绕轴旋转正方向30 //旋转角度 transform.Rotate (new Vector3(20, 0, 0)); //绕点旋转 transform.RotateAround(Vector3.zero, Vector3.up, 50); //角度转换 Vector3 rotationVector3 = new Vector3(0f, 30f, 0f); Quaternion rotation = Quaternion.Euler(rotationVector3); //-----------3D位移---------- // //方向 transform.Translate(Vector3.back * FallingSpeed); transform.position = Vector3.MoveTowards(transform.position,tempUpdatePos, Time.deltaTime * DisShakeThreshold); //固定时间 transform.Translate(Vector3.normalize(tarPos-selfPos) * (Vector3.Distance(selfPos,tarPos)/(setTime * Time.deltime))); //-----------2D方向移动---------- // moveDirection = mTarget.transform.position - mSelf.transform.position; moveDirection.Normalize(); float target = Mathf.Atan2(moveDirection.y, moveDirection.x) * Mathf.Rad2Deg - 90f; mSelf.transform.rotation = Quaternion.Slerp(mSelf.transform.rotation, Quaternion.Euler(0, 0, target), turnSpeed * Time.deltaTime); _controller.SetForce(speedX,speedY));
- 资源加载
资源加载API分为Editor下的和非Editor下的 其他平台路径各有区别
//作为重要功能 深入研究会发现坑很多
//*********************Editor******************// //1.Resource文件夹 //同步 GameObject prefab = Resources.Load("资源路径/名字") as GameObject; GameObject go = Instantiate(prefab) as GameObject; //异步 Resources.LoadAsync<Object>(path); //2.非Resourece //路径为 Assets/XX/XX.prefab 这样的格式 UnityEditor.AssetDatabase.LoadAssetAtPath<T>(path); //*********************AssetBundle******************// AssetBundle bundle = AssetBundle.LoadFromFile(path); Object obj = bundle.LoadAsset<GameObject>("XXXX");
-
U3D射线射碰撞体与层
//(检测是否碰撞) if (Physics.Raycast(origin, Vector3.down, 1f,1 << LayerMask.NameToLayer("Ground"))) { //层的说明 //int 1-31是未转化的层index 而用于射线LayerMask 是1<<int 运算后的 是一个很大的数 // 1 << 10 打开第10的层。 等价于 1 << LayerMask.NameToLayer("Ground"); //~(1 << 10) 打开除了第10之外的层。 //~(1 << 0) 打开所有的层。 //(1 << 10) | (1 << 8) 打开第10和第8的层。等价于 LayerMask.GetMask(("Ground", "Wall"); } //(输出信息的) Ray ray = new Ray(transform.position, Vector3.down); RaycastHit hitInfo = new RaycastHit(); if (Physics.Raycast(ray, out hitInfo, 30f, layerMask)) { Debug.Log(hitInfo.point); } //物体 gameObject.layer = (1-31层 或 LayerMask.NameToLayer("Ground")); //发射碰撞体 Physics.OverXXX
在Unity中每个GameObject都有Layer属性,默认的Layer都是Default。在Unity中可编辑的Layer共有24个(8—31层),官方已使用的是0—7层,默认不可编辑!
LayerMask实际上是一个位码操作,在Unity3D中一共有32个Layer层,并且不可增加。
位运算符
按位运算符:~、|、&、^。位运算符主要用来对二进制位进行操作。逻辑运算符:&&、||、!。逻辑运算符把语句连接成更复杂的复杂语句。
按位运算符:左移运算符<<,左移表示乘以2,左移多少位表示乘以2的几次幂。
- 协程IEnumerator
void Start(){ StartCoroutine(Test()); } IEnumerator Test() { yield return null; // 下一帧再执行后续代码 yield return 0; //下一帧再执行后续代码 yield return 6;//(任意数字) 下一帧再执行后续代码 yield break; //直接结束该协程的后续操作 yield return asyncOperation;//等异步操作结束后再执行后续代码 yield return StartCoroution(/*某个协程*/);//等待某个协程执行完毕后再执行后续代码 yield return WWW();//等待WWW操作完成后再执行后续代码 yield return new WaitForEndOfFrame();//等待帧结束,等待直到所有的摄像机和GUI被渲染完成后,在该帧显示在屏幕之前执行 yield return new WaitForSeconds(0.3f);//等待0.3秒,一段指定的时间延迟之后继续执行,在所有的Update函数完成调用的那一帧之后(这里的时间会受到Time.timeScale的影响); yield return new WaitForSecondsRealtime(0.3f);//等待0.3秒,一段指定的时间延迟之后继续执行,在所有的Update函数完成调用的那一帧之后(这里的时间不受到Time.timeScale的影响); yield return WaitForFixedUpdate();//等待下一次FixedUpdate开始时再执行后续代码 yield return new WaitUntil()//将协同执行直到 当输入的参数(或者委托)为true的时候....如:yield return new WaitUntil(() => frame >= 10); yield return new WaitWhile()//将协同执行直到 当输入的参数(或者委托)为false的时候.... 如:yield return new WaitWhile(() => frame < 10); }
- Animator
Animator可以被继承!
Animator可以添加脚本处理状态!
重置动画(播放动画第一帧)firstAnimName = GetComponent<Animator>().GetCurrentAnimatorClipInfo(0)[0].clip.name; GetComponent<Animator>().Play (firstAnimName,-1,0);
获取某个动画名字的时间长度private Animator animator; public void GetLengthByName(string name){ float length = 0; AnimationClip[] clips = animator.runtimeAnimatorController.animationClips; foreach(AnimationClip clip in clips) { if(clip.name.Equals(name)) { length = clip.length; break; } } Debug.Log(length); }
- 刚体
Mass:质量(kg)
Drag:空气阻力 越大越难推动
Angular Drag:旋转阻力 越大越不会旋转 0无阻力 10以后基本无惯性
Use Gravity:是否使用重力
Constraints
Freeze Position:锁定位置
Freeze Rotation:锁定旋转
- 物体碰撞
Edit-Project Settings-Physics 打开物理管理器(Physics Manager)里面可以设置层级相互间的碰撞
碰撞条件是都带Collider 其中一个带rigidbody//触发器 MonoBehaviour.OnTriggerEnter(Collider collider)当进入触发器 MonoBehaviour.OnTriggerExit(Collider collider)当退出触发器 MonoBehaviour.OnTriggerStay(Collider collider)当逗留触发器 //碰撞信息检测: MonoBehaviour.OnCollisionEnter(Collision collision) 当进入碰撞器 MonoBehaviour.OnCollisionExit(Collision collision) 当退出碰撞器 MonoBehaviour.OnCollisionStay(Collision collision) 当逗留碰撞器
- 平台预处理
#if UNITY_EDITOR platform = "hi,大家好,我是在unity编辑模式下"; #elif UNITY_SERVER #elif UNITY_IPHONE platform="hi,大家好,我是IPHONE平台"; #elif UNITY_ANDROID platform="hi,大家好,我是ANDROID平台"; #elif UNITY_STANDALONE_OSX #elif UNITY_STANDALONE_WIN platform="hi,大家好,我是Windows平台"; #endif Debug.Log("Current Platform:" + platform);
- DoFile 读取一个Txt
string localConfig = Application.dataPath + "/Config/123.txt"; if (File.Exists(localConfig)) { string[] strs = File.ReadAllLines(localConfig); }
- Editor
选中物体保存为预设[UnityEditor.MenuItem("Tools/Apply Selected Prefabs")] static void ApplySelectedPrefabs(){ //获取选中的gameobject对象 GameObject [] selectedsGameobject= Selection.gameObjects; GameObject prefab = PrefabUtility.FindPrefabRoot (selectedsGameobject[0]); for (int i = 0; i < selectedsGameobject.Length; i++) { GameObject obj=selectedsGameobject[i]; UnityEngine.Object newsPref= PrefabUtility.GetPrefabObject(obj); //判断选择的物体,是否为预设 if(PrefabUtility.GetPrefabType(obj) == PrefabType.PrefabInstance){ UnityEngine.Object parentObject = PrefabUtility.GetPrefabParent(obj); //string path = AssetDatabase.GetAssetPath(parentObject);//获取路径 PrefabUtility.ReplacePrefab(obj,parentObject,ReplacePrefabOptions.ConnectToPrefab);//替换预设 AssetDatabase.Refresh();//刷新 } } }
- Inspector面板自定义
用代码重新绘制了Inspector,并赋值,所以注意不能使用Ctrl+Z[CustomEditor(typeof(你的代码))] public class 你的代码Editor : Editor { SerializedObject myScript; SerializedProperty bool变量; SerializedProperty 任意变量; SerializedProperty 数组变量; void OnEnable() { myScript = new SerializedObject(target); bool变量 = myScript.FindProperty("bool变量"); 任意变量 = myScript.FindProperty("任意变量"); 数组变量 = myScript.FindProperty("数组变量"); } public override void OnInspectorGUI() { base.OnInspectorGUI(); myScript.Update(); if (bool变量.boolValue) { EditorGUILayout.LabelField("面板提示"); EditorGUILayout.PropertyField(任意变量); } else { EditorGUILayout.LabelField("面板提示"); 数组变量.arraySize = EditorGUILayout.IntField("Length", 数组变量.arraySize); for (int i = 0; i < 数组变量.arraySize; i++) EditorGUILayout.PropertyField(数组变量.GetArrayElementAtIndex(i)); } myScript.ApplyModifiedProperties(); } }
-
画线画圆画弧
①Debug.DrawLinepublic float radius; public float angle; public int smooth = 20; public Vector3 dir = Vector3.right; public bool drawSide = true; void Update() { Vector3 start = Quaternion.Euler(0, 0, -angle) * dir * radius; Vector3 firstPos = Vector3.zero; Vector3 lastPos = Vector3.zero; for (int i = 0; i <= smooth; i++) { firstPos = transform.position + Quaternion.Euler(0,0,(angle*2/smooth)*i)*start; lastPos = transform.position + Quaternion.Euler(0,0,(angle*2/smooth)*(i+1))*start; Debug.DrawLine(firstPos, lastPos, Color.red); } if (drawSide) { Debug.DrawLine(transform.position, transform.position + start, Color.red); Debug.DrawLine(transform.position, lastPos, Color.red); } }
②LineRender
private LineRenderer line;//画线 line = this.gameObject.AddComponent<LineRenderer>(); //只有设置了材质 setColor才有作用 line.material = new Material(Shader.Find("Particles/Additive")); line.SetVertexCount(2);//设置两点 line.SetColors(Color.yellow, Color.red); //设置直线颜色 line.SetWidth(0.1f, 0.1f);//设置直线宽度 //设置指示线的起点和终点 line.SetPosition(0, start.position); line.SetPosition(1, end.position); public float R;//半径 public int N;//不要超过45 line.SetVertexCount(N+1);//这里要加1,达成闭合曲线 for (int i = 0; i < N + 1; i++) { float x = R * Mathf.Cos((360 / N * i) * Mathf.Deg2Rad) + transform.position.x; //确定x坐标 float z = R * Mathf.Sin((360 / N * i) * Mathf.Deg2Rad) + transform.position.z; //确定z坐标 line.SetPosition(i, new Vector3(x, transform.position.y, z)); }
-
控制全局音量
通过 AudioListener.volume来控制场景场景音量
Unity推出了自己声音引擎
也可以用热门的引擎 如:Wwise.. - UGUI
进度条 -- 通过改变UI的FillAmount值 UnityEngine.UI.Image healthBar.fillAmount = 0.0f;
艺术字体 -- 对于Text 使用材质和Outline可以制作
Mask -- 可以遮挡 对于制作一些动画比较好
自动排列用 Layout Group 如果要适配改变大小 都要加Content Size Fitter 要改变的设置为preferred size;
- Unity播放透明动画
①UnityAnimation播放,直接全选png序列帧图(卡超级久) 然后拖到面板上(卡很久),会自动生成序列播放的animator。但我发现超过300图之后有可能会出现不明报错(大概因为输出问题),1k张感觉就没什么希望了,最重要的是在unity里1080p的图转成sprite,都会变成10m一张,导致项目发布之后更是奇大无比。
②播放mov,可以尝试播带透明通道的mov,但需要一个shader,具体我不会写,在网上找到的也不太好用,各种问题(抠色会失真和有噪点,提取透明or黑白遮罩会出现不同步
③LoadResources,先load资源文件夹内的,然后播放。load的东西如果超过2G(C#设定)则不能加载
④LoadAssets。因为是一张张地load,不会出现太大而不加载的问题。目前使用这个办法播放 -
Lighting
设置窗口(Window->Lighting->Settings)是主要控制unity全局光照(GlobalIllumination GI)的地方。尽管GI的默认设置已经有了很好的效果,lighting设置面板的一些属性可以调节GI处理的很多方面,从而可以定制场景或者优化场景的质量、速度和存储空间。窗口还包括环境光、光晕、雾效、烘焙的设置。
可使用Class.UnityEngine.RenderSettings代码改变这些
- Debug
日志路径 C:\Users\Administrator\AppData\LocalLow\DefaultCompany - 待续..
Unity特性
1.unity具有特殊意义的文件夹
2.unity时间函数执行顺序
3.持续更新;
C#相关API
- Only one exe只允许打开一个程序
int count=Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length ; if (count> 1) { // MessageBox.Show(count.ToString());调试使用 Process.GetCurrentProcess().Kill();//杀掉当前 }
- 启动一个进程
一个C#的API 可以用于打开一个网页..应用..或者进程..或者控制面板内的功能..例如打印..
public void PrintFile() { System.Diagnostics.Process process = new System.Diagnostics.Process(); //系统进程 process.StartInfo.CreateNoWindow = false; //不显示调用程序窗口 process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;// process.StartInfo.UseShellExecute = true; //采用操作系统自动识别模式 process.StartInfo.FileName=path; //要打印的文件路径 process.StartInfo.Verb="print"; //指定执行的动作,打印:print打开:open………… process.Start(); //开始打印 }
-
改变鼠标位置和隐藏鼠标
using System.Runtime.InteropServices; [DllImport("user32.dll")] public static extern int SetCursorPos(int x, int y); Void XX(){ SetCursorPos(0, 0); } [DllImport("user32.dll")] public static extern int SetCursorPos(int x, int y); void Start () { //隐藏 Cursor.visible = false; }
数学相关
向量与夹角与三角函数
//U3D Vector3.forward 实际是(0,0,1) 向前的意思 也就是右上角Z轴方向
//forward是蓝色箭头方向 back是反方向 right是红色箭头方向 left反之 up是绿色箭头方向 down反之
Vector3 vector = targetPos - originPos;//任意两点向量 = V3目标位置 - V3起点位置
float angle = Vector3.Angle(from, to); //向量夹角 v3.angle(向量A,向量B)
Vector3.Normalize;//单位向量
//Deg2Rad 度转弧度 ; Rad2Deg 弧度转度
//求角度的三角函数值
Mathf.Sin(Mathf.Deg2Rad * angle);
//求变长求角度
Mathf.Atan2(y,x) * Mathf.Rad2Deg;
其他
- uLua使用方法
注意AppConst里的LuaBundleModel变量,如果想使用AssetBundle模式,该值置为true,但是每次修改lua代码,需要执行菜单栏上的LuaFramework->Build XXX Resource,将lua资源打包,否则,你修改的lua逻辑不会更新并执行。
如果LuaBundleModel置为false,则lua代码会时时更新。
此外,修改C#代码,一定不要忘了执行菜单Lua->Clear wrap files,然后重新生成Gen Wrap + Binder
确定逻辑无误后,注册C#类,打开"CustomSettings.cs",注册我们的类。"_GT(typeof(XXXXXX)),"。最后,执行上面第2步的Lua->Clear wrap files,Gen Wrap + Binder。此时,会生成一个叫MyHelloWorldWrap.cs的文件,在Assets\LuaFramework\ToLua\Source\Generate目录下,其实所有在CustomSettings中注册的C#类都会生成Wrap文件,保存在该目录下。
- Windows工具
项目同步一般用svn或git主要是免费 大公司用收费的软件
AutoHotKey作为快捷键操作打开
- Mac鸡工具
连接:可以使用vnc viewer
项目管理:Cornerstone - 持续更新...