Unity3D常用API和功能
前言
喜欢请点赞
目标阅读者:Unity新手 项目程序员
简单的前置:编程习惯
Unity常用API
-
按键Input
image.gifvoid Update() { if (Input.GetKey("up")) { print("up arrow key is held"); } if (Input.GetKeyDown("down")) { print("down arrow key is held down"); } if (Input.GetMouseButton(0)) { print("鼠标左键点击"); } }
-
OnGUI
image.gifvoid OnGUI() { if (GUI.Button(new Rect(10, 10, 150, 100), "I am a button")) { } }
-
Log
image.gif/*正常Log*/ Debug.Log("<color=#9400D3> You clicked the button! </color>"); /*跳转到GameObject*/ Debug.Log(Obj,"跳转"); /*颜色*/ //green 绿色 #008000ff red 红色 #ff0000ff //white 白色 #ffffffff yellow 黄色 #ffff00ff /*转义符*/ \’ 单引号符 \” 单引号符 \\ 反斜线符"\" \n 换行 \r 回车 text在运行后\会自动变成了\\,所以无效解决方法: msgText.text = msg.Replace("\\n", "\n");
日志路径 C:\Users\Administrator\AppData\LocalLow\DefaultCompany
封装Unity的Debug,在打包的时候方便改为全不输出(以免影响性能),
在输出的时候,根据位运算选择输出信息(例如战斗信息、场景信息、帧同步信息等)
取消发布log消耗 -
移动与旋转
image.gif//-------------旋转------------ // //设置角度 //EulerAngles transform.localEulerAngles = new Vector3(0,0,0); //Quaternion transform.rotation = Quaternion.AngleAxis(30, Vector3.up);//绕轴旋转正方向30 //转换 Quaternoin quaternoin= Quaternion.Euler(vector3); Vector3 rotation = Quaternion.EulerAngles(quaternoin); //旋转角度 transform.Rotate (new Vector3(20 * Time.dealtime, 0, 0)); //绕点旋转 transform.RotateAround(Vector3.zero, Vector3.up, 50 * Time.dealtime); //-----------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下的 其他平台路径各有区别
//作为重要功能 深入研究会发现坑很多
image.gif image image.gif/************创建****************/ /*********Resource文件夹*********/ /*同步加载*/ GameObject prefab = Resources.Load("资源路径/名字") as GameObject; /*异步加载*/ GameObject prefab2 = Resources.LoadAsync<Object>(path); /*实例化*/ GameObject go = Instantiate(prefab) as GameObject; /*************非Resourece**************/ //路径为 Assets/XX/XX.prefab 这样的格式 UnityEditor.AssetDatabase.LoadAssetAtPath<T>(path); /**************AssetBundle**************/ AssetBundle bundle = AssetBundle.LoadFromFile(path); Object obj = bundle.LoadAsset<GameObject>("XXXX"); /******************删除****************/ //非AB GameObject.Destroy(go);//下一帧删除 GameObject.DestroyImmediate(go);//马上删除 //AB Destroy UnloadAB(true) 如果没清除依赖UnloadUnUseAsset然后GC
-
U3D射线射碰撞体与层
image.gif//(检测是否碰撞) 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的几次幂。
-
GameObject
image.gif//获取自己index int id = self.GetSiblingIndex();
-
协程IEnumerator
image.gifvoid 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可以添加脚本处理状态!重置动画(播放动画第一帧)
image.giffirstAnimName = GetComponent<Animator>().GetCurrentAnimatorClipInfo(0)[0].clip.name; GetComponent<Animator>().Play (firstAnimName,-1,0);
获取某个动画名字的时间长度
image.gifprivate 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) 当逗留碰撞器
```
![image.gif](https://img.haomeiwen.com/i906135/c29664fffc0de86e.gif?imageMogr2/auto-orient/strip)
- 平台预处理
```
#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);
```
![image.gif](https://img.haomeiwen.com/i906135/8e282911c2a8be71.gif?imageMogr2/auto-orient/strip)
- DoFile 读取一个Txt
```
string localConfig = Application.dataPath + "/Config/123.txt";
if (File.Exists(localConfig))
{
string[] strs = File.ReadAllLines(localConfig);
}
```
![image.gif](https://img.haomeiwen.com/i906135/184397d7aa52adfc.gif?imageMogr2/auto-orient/strip)
-
Editor常用
https://blog.csdn.net/u014528558/article/details/104991179 -
画线画圆画弧
①Debug.DrawLine
```
public 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);
}
}
```
![image.gif](https://img.haomeiwen.com/i906135/82b7f8c4d5d4f359.gif?imageMogr2/auto-orient/strip)
②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));
}
```
![image.gif](https://img.haomeiwen.com/i906135/59d7c708da703e4f.gif?imageMogr2/auto-orient/strip)
-
控制全局音量
通过 AudioListener.volume来控制场景场景音量 -
UGUI
进度条 -- 通过改变UI的FillAmount值 UnityEngine.UI.Image healthBar.fillAmount = 0.0f;
艺术字体 -- 对于Text 使用材质和Outline可以制作 但会引起drawcall增加
Mask -- 可以遮挡 对于制作一些动画比较好 但会引起drawcall增加
自动排列用 Layout Group 如果要适配改变大小 都要加Content Size Fitter 要改变的设置为preferred size;
- 渲染
设置窗口(Window->Lighting->Settings)是主要控制unity全局光照(GlobalIllumination GI)的地方。尽管GI的默认设置已经有了很好的效果,lighting设置面板的一些属性可以调节GI处理的很多方面,从而可以定制场景或者优化场景的质量、速度和存储空间。窗口还包括环境光、光晕、雾效、烘焙的设置。
可使用Class.UnityEngine.RenderSettings代码改变这些
- 路径
各路径的定义:
a、Resources路径
Resources文件夹是Unity里自动识别的一种文件夹,可在Unity编辑器的Project窗口里创建,并将资源放置在里面。Resources文件夹下的资源不管是否有用,全部会打包进.apk或者.ipa,并且打包时会将里面的资源压缩处理。加载方法是Resources.Load<T>(文件名),需要注意:文件名不包括扩展名,打包后不能更改Resources下的资源内容,但是从Resources文件夹中加载出来的资源可以更改。
b、Application.dataPath路径
这个属性返回的是程序的数据文件所在文件夹的路径,例如在Editor中就是项目的Assets文件夹的路径,通过这个路径可以访问项目中任何文件夹中的资源,但是在移动端它是完全没用。
c、Application.streamingAssetsPath路径
这个属性用于返回流数据的缓存目录,返回路径为相对路径,适合设置一些外部数据文件的路径。在Unity工程的Assets目录下起一个名为“StreamingAssets”的文件夹即可,然后用Application.streamingAssetsPath访问,这个文件夹中的资源在打包时会原封不动的打包进去,不会压缩,一般放置一些资源数据。在PC/MAC中可实现对文件的“增删改查”等操作,但在移动端是一个只读路径。
d、Application.persistentDataPath路径
此属性返回一个持久化数据存储目录的路径,可以在此路径下存储一些持久化的数据文件。这个路径可读、可写,但是只能在程序运行时才能读写操作,不能提前将数据放入这个路径。在IOS上是应用程序的沙盒,可以被iCloud自动备份,可以通过同步推送一类的助手直接取出文件;在Android上的位置是根据Project Setting里设置的Write Access路径,可以设置是程序沙盒还是sdcard,注意:如果在Android设置保存在沙盒中,那么就必须root以后才能用电脑取出文件,因此建议写入sdcard里。一般情况下,建议将获得的文件保存在这个路径下,例如可以从StreamingAsset中读取的二进制文件或者从AssetBundle读取的文件写入PersistentDatapath。
e、Application.temporaryCachePath路径
此属性返回一个临时数据的缓存目录,跟Application.persistentDataPath类似,但是在IOS上不能被自动备份。
以上各路径中的资源加载方式都可以用WWW类加载,但要注意各个平台路径需要加的访问名称,例如Android平台的路径前要加"jar:file://",其他平台使用"file://"。以下是各路径在各平台中的具体位置信息:
路径对应目录:
安卓
Application.dataPath : /data/app/xxx.xxx.xxx.apk
Application.streamingAssetsPath : jar:file:///data/app/xxx.xxx.xxx.apk/!/assets(只读不可写)
Application.persistentDataPath : /data/data/xxx.xxx.xxx/files(可读写)
Application.temporaryCachePath : /data/data/xxx.xxx.xxx/cache
IOS平台
Application.dataPath : Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxx.app/Data
Application.streamingAssetsPath : Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxx.app/Data/Raw
Application.persistentDataPath : Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/Documents
Application.temporaryCachePath : Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/Library/Caches
PC
Application.dataPath : 项目路径/Assets
Application.streamingAssetsPath: 项目路径/Assets/StreamingAssets
Application.temporaryCachePath: C:\Users\username\AppData\Local\Temp\company name\product name
Application.persistentDataPath: C:\Users\username\AppData\LocalLow\company name\product name
- 每秒/改变时绘制
在Scene预览模型 例子:
```
GameObject preview;
void OnDrawGizmos()
{
if(!Application.isPlaying)
{
if(preview == null)
Resources.Load<GameObject>("path");
else
{
MeshFilter[] meshFilters = mPreview.GetComponentsInChildren<MeshFilter>();
for(int i = 0; i < meshFilters.Length; i++)
{
Gizmos.DrawMesh(meshFilter[i].sharedMesh,
transform.position + mPreview.transform.GetChild(i).position * scale,
mPreview.transform.GetChild(i).rotation,
transform.localScale)
}
}
}
}
```
![image.gif](https://img.haomeiwen.com/i906135/23a582e3eccc8ab2.gif?imageMogr2/auto-orient/strip)
Unity特性
1.unity具有特殊意义的文件夹
2.unity时间函数执行顺序
image image.gif
C#相关API
-
Only one exe只允许打开一个程序
image.gifint count=Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length ; if (count> 1) { // MessageBox.Show(count.ToString());调试使用 Process.GetCurrentProcess().Kill();//杀掉当前 }
-
一个C#的API 可以用于打开一个网页..应用..或者进程..或者控制面板内的功能..例如打印..
image.gifpublic 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(); //开始打印 }
-
改变鼠标位置和隐藏鼠标
image.gifusing 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; }
-
输出栈堆
image.gifstring trackStr = new System.Diagnostics.StackTrace().ToString(); Debug.Log ("Stack Info:" + trackStr);
数学相关
向量与夹角与三角函数
//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;
image.gif
其他
-
Windows工具:
svn项目同步
AutoHotKey作为快捷键操作打开
Clover作为打开文件夹的工具
SETUNA作为截图工具 -
Mac鸡工具
连接:可以使用vnc viewer
项目管理:Cornerstone -
调试
调试安卓:直接在调试面板Console/Profiler输入ip链接(unity在2020的新版中甚至支持无需编译改代码)
苹果:链接XCode调试