前言
喜歡請點贊
目標(biāo)閱讀者:Unity新手 項目程序員
簡單的前置:編程習(xí)慣
Unity常用API
-
按鍵Input
void 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("鼠標(biāo)左鍵點擊"); } }
-
OnGUI
void OnGUI() { if (GUI.Button(new Rect(10, 10, 150, 100), "I am a button")) { } }
-
Log
/*正常Log*/ Debug.Log("<color=#9400D3> You clicked the button! </color>"); /*跳轉(zhuǎn)到GameObject*/ Debug.Log(Obj,"跳轉(zhuǎn)"); /*顏色*/ //green 綠色 #008000ff red 紅色 #ff0000ff //white 白色 #ffffffff yellow 黃色 #ffff00ff /*轉(zhuǎn)義符*/ \’ 單引號符 \” 單引號符 \\ 反斜線符"\" \n 換行 \r 回車 text在運行后\會自動變成了\\,所以無效解決方法: msgText.text = msg.Replace("\\n", "\n");
日志路徑 C:\Users\Administrator\AppData\LocalLow\DefaultCompany
封裝Unity的Debug苫纤,在打包的時候方便改為全不輸出(以免影響性能),
在輸出的時候括勺,根據(jù)位運算選擇輸出信息(例如戰(zhàn)斗信息兜辞、場景信息捆昏、幀同步信息等)
取消發(fā)布log消耗 -
移動與旋轉(zhuǎn)
//-------------旋轉(zhuǎn)------------ // //設(shè)置角度 //EulerAngles transform.localEulerAngles = new Vector3(0,0,0); //Quaternion transform.rotation = Quaternion.AngleAxis(30, Vector3.up);//繞軸旋轉(zhuǎn)正方向30 //轉(zhuǎn)換 Quaternoin quaternoin= Quaternion.Euler(vector3); Vector3 rotation = Quaternion.EulerAngles(quaternoin); //旋轉(zhuǎn)角度 transform.Rotate (new Vector3(20 * Time.dealtime, 0, 0)); //繞點旋轉(zhuǎn) 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));
-
資源加載和創(chuàng)建刪除
資源加載API分為Editor下的和非Editor下的 其他平臺路徑各有區(qū)別
//作為重要功能 深入研究會發(fā)現(xiàn)坑很多/************創(chuàng)建****************/ /*********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射線射碰撞體與層
//(檢測是否碰撞) if (Physics.Raycast(origin, Vector3.down, 1f,1 << LayerMask.NameToLayer("Ground"))) { //層的說明 //int 1-31是未轉(zhuǎn)化的層index 而用于射線LayerMask 是1<<int 運算后的 是一個很大的數(shù) // 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")); //發(fā)射碰撞體 Physics.OverXXX
在Unity中每個GameObject都有Layer屬性漩绵,默認(rèn)的Layer都是Default贱案。在Unity中可編輯的Layer共有24個(8—31層),官方已使用的是0—7層止吐,默認(rèn)不可編輯宝踪!
LayerMask實際上是一個位碼操作,在Unity3D中一共有32個Layer層碍扔,并且不可增加瘩燥。
位運算符
按位運算符:~、|不同、&厉膀、^溶耘。位運算符主要用來對二進(jìn)制位進(jìn)行操作。邏輯運算符:&&服鹅、||凳兵、!菱魔。邏輯運算符把語句連接成更復(fù)雜的復(fù)雜語句留荔。
按位運算符:左移運算符<<吟孙,左移表示乘以2澜倦,左移多少位表示乘以2的幾次冪。
-
GameObject
//獲取自己index int id = self.GetSiblingIndex();
-
協(xié)程IEnumerator
void Start(){ StartCoroutine(Test()); } IEnumerator Test() { yield return null; // 下一幀再執(zhí)行后續(xù)代碼 yield return 0; //下一幀再執(zhí)行后續(xù)代碼 yield return 6;//(任意數(shù)字) 下一幀再執(zhí)行后續(xù)代碼 yield break; //直接結(jié)束該協(xié)程的后續(xù)操作 yield return asyncOperation;//等異步操作結(jié)束后再執(zhí)行后續(xù)代碼 yield return StartCoroution(/*某個協(xié)程*/);//等待某個協(xié)程執(zhí)行完畢后再執(zhí)行后續(xù)代碼 yield return WWW();//等待WWW操作完成后再執(zhí)行后續(xù)代碼 yield return new WaitForEndOfFrame();//等待幀結(jié)束,等待直到所有的攝像機和GUI被渲染完成后杰妓,在該幀顯示在屏幕之前執(zhí)行 yield return new WaitForSeconds(0.3f);//等待0.3秒藻治,一段指定的時間延遲之后繼續(xù)執(zhí)行,在所有的Update函數(shù)完成調(diào)用的那一幀之后(這里的時間會受到Time.timeScale的影響); yield return new WaitForSecondsRealtime(0.3f);//等待0.3秒巷挥,一段指定的時間延遲之后繼續(xù)執(zhí)行桩卵,在所有的Update函數(shù)完成調(diào)用的那一幀之后(這里的時間不受到Time.timeScale的影響); yield return WaitForFixedUpdate();//等待下一次FixedUpdate開始時再執(zhí)行后續(xù)代碼 yield return new WaitUntil()//將協(xié)同執(zhí)行直到 當(dāng)輸入的參數(shù)(或者委托)為true的時候....如:yield return new WaitUntil(() => frame >= 10); yield return new WaitWhile()//將協(xié)同執(zhí)行直到 當(dāng)輸入的參數(shù)(或者委托)為false的時候.... 如:yield return new WaitWhile(() => frame < 10); }
-
Animator
Animator可以被繼承!
Animator可以添加腳本處理狀態(tài)!重置動畫(播放動畫第一幀)
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:質(zhì)量(kg)
Drag:空氣阻力 越大越難推動
Angular Drag:旋轉(zhuǎn)阻力 越大越不會旋轉(zhuǎn) 0無阻力 10以后基本無慣性
Use Gravity:是否使用重力
Constraints
Freeze Position:鎖定位置
Freeze Rotation:鎖定旋轉(zhuǎn)
- 物體碰撞
Edit-Project Settings-Physics 打開物理管理器(Physics Manager)里面可以設(shè)置層級相互間的碰撞
碰撞條件是都帶Collider 其中一個帶rigidbody
```
//觸發(fā)器
MonoBehaviour.OnTriggerEnter(Collider collider)當(dāng)進(jìn)入觸發(fā)器
MonoBehaviour.OnTriggerExit(Collider collider)當(dāng)退出觸發(fā)器
MonoBehaviour.OnTriggerStay(Collider collider)當(dāng)逗留觸發(fā)器
//碰撞信息檢測:
MonoBehaviour.OnCollisionEnter(Collision collision) 當(dāng)進(jìn)入碰撞器
MonoBehaviour.OnCollisionExit(Collision collision) 當(dāng)退出碰撞器
MonoBehaviour.OnCollisionStay(Collision collision) 當(dāng)逗留碰撞器
```
![image.gif](https://upload-images.jianshu.io/upload_images/906135-c29664fffc0de86e.gif?imageMogr2/auto-orient/strip)
- 平臺預(yù)處理
```
#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://upload-images.jianshu.io/upload_images/906135-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://upload-images.jianshu.io/upload_images/906135-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://upload-images.jianshu.io/upload_images/906135-82b7f8c4d5d4f359.gif?imageMogr2/auto-orient/strip)
②LineRender
```
private LineRenderer line;//畫線
line = this.gameObject.AddComponent<LineRenderer>();
//只有設(shè)置了材質(zhì) setColor才有作用
line.material = new Material(Shader.Find("Particles/Additive"));
line.SetVertexCount(2);//設(shè)置兩點
line.SetColors(Color.yellow, Color.red); //設(shè)置直線顏色
line.SetWidth(0.1f, 0.1f);//設(shè)置直線寬度
//設(shè)置指示線的起點和終點
line.SetPosition(0, start.position);
line.SetPosition(1, end.position);
public float R;//半徑
public int N;//不要超過45
line.SetVertexCount(N+1);//這里要加1,達(dá)成閉合曲線
for (int i = 0; i < N + 1; i++)
{
float x = R * Mathf.Cos((360 / N * i) * Mathf.Deg2Rad) + transform.position.x; //確定x坐標(biāo)
float z = R * Mathf.Sin((360 / N * i) * Mathf.Deg2Rad) + transform.position.z; //確定z坐標(biāo)
line.SetPosition(i, new Vector3(x, transform.position.y, z));
}
```
![image.gif](https://upload-images.jianshu.io/upload_images/906135-59d7c708da703e4f.gif?imageMogr2/auto-orient/strip)
控制全局音量
通過 AudioListener.volume來控制場景場景音量UGUI
進(jìn)度條 -- 通過改變UI的FillAmount值 UnityEngine.UI.Image healthBar.fillAmount = 0.0f;
藝術(shù)字體 -- 對于Text 使用材質(zhì)和Outline可以制作 但會引起drawcall增加
Mask -- 可以遮擋 對于制作一些動畫比較好 但會引起drawcall增加
自動排列用 Layout Group 如果要適配改變大小 都要加Content Size Fitter 要改變的設(shè)置為preferred size;
- 渲染
設(shè)置窗口(Window->Lighting->Settings)是主要控制unity全局光照(GlobalIllumination GI)的地方。盡管GI的默認(rèn)設(shè)置已經(jīng)有了很好的效果高职,lighting設(shè)置面板的一些屬性可以調(diào)節(jié)GI處理的很多方面钩乍,從而可以定制場景或者優(yōu)化場景的質(zhì)量、速度和存儲空間怔锌。窗口還包括環(huán)境光寥粹、光暈、霧效埃元、烘焙的設(shè)置涝涤。
可使用Class.UnityEngine.RenderSettings代碼改變這些
- 路徑
各路徑的定義:
a、Resources路徑
Resources文件夾是Unity里自動識別的一種文件夾岛杀,可在Unity編輯器的Project窗口里創(chuàng)建阔拳,并將資源放置在里面。Resources文件夾下的資源不管是否有用类嗤,全部會打包進(jìn).apk或者.ipa糊肠,并且打包時會將里面的資源壓縮處理。加載方法是Resources.Load<T>(文件名)土浸,需要注意:文件名不包括擴展名罪针,打包后不能更改Resources下的資源內(nèi)容,但是從Resources文件夾中加載出來的資源可以更改黄伊。
b泪酱、Application.dataPath路徑
這個屬性返回的是程序的數(shù)據(jù)文件所在文件夾的路徑,例如在Editor中就是項目的Assets文件夾的路徑,通過這個路徑可以訪問項目中任何文件夾中的資源墓阀,但是在移動端它是完全沒用毡惜。
c、Application.streamingAssetsPath路徑
這個屬性用于返回流數(shù)據(jù)的緩存目錄斯撮,返回路徑為相對路徑经伙,適合設(shè)置一些外部數(shù)據(jù)文件的路徑。在Unity工程的Assets目錄下起一個名為“StreamingAssets”的文件夾即可勿锅,然后用Application.streamingAssetsPath訪問帕膜,這個文件夾中的資源在打包時會原封不動的打包進(jìn)去,不會壓縮溢十,一般放置一些資源數(shù)據(jù)垮刹。在PC/MAC中可實現(xiàn)對文件的“增刪改查”等操作,但在移動端是一個只讀路徑张弛。
d荒典、Application.persistentDataPath路徑
此屬性返回一個持久化數(shù)據(jù)存儲目錄的路徑,可以在此路徑下存儲一些持久化的數(shù)據(jù)文件吞鸭。這個路徑可讀寺董、可寫,但是只能在程序運行時才能讀寫操作刻剥,不能提前將數(shù)據(jù)放入這個路徑遮咖。在IOS上是應(yīng)用程序的沙盒,可以被iCloud自動備份透敌,可以通過同步推送一類的助手直接取出文件盯滚;在Android上的位置是根據(jù)Project Setting里設(shè)置的Write Access路徑,可以設(shè)置是程序沙盒還是sdcard酗电,注意:如果在Android設(shè)置保存在沙盒中魄藕,那么就必須root以后才能用電腦取出文件,因此建議寫入sdcard里撵术。一般情況下背率,建議將獲得的文件保存在這個路徑下,例如可以從StreamingAsset中讀取的二進(jìn)制文件或者從AssetBundle讀取的文件寫入PersistentDatapath嫩与。
e寝姿、Application.temporaryCachePath路徑
此屬性返回一個臨時數(shù)據(jù)的緩存目錄,跟Application.persistentDataPath類似划滋,但是在IOS上不能被自動備份饵筑。
以上各路徑中的資源加載方式都可以用WWW類加載,但要注意各個平臺路徑需要加的訪問名稱处坪,例如Android平臺的路徑前要加"jar:file://"根资,其他平臺使用"file://"架专。以下是各路徑在各平臺中的具體位置信息:
路徑對應(yīng)目錄:
安卓
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預(yù)覽模型 例子:
```
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://upload-images.jianshu.io/upload_images/906135-23a582e3eccc8ab2.gif?imageMogr2/auto-orient/strip)
Unity特性
1.unity具有特殊意義的文件夾
2.unity時間函數(shù)執(zhí)行順序
?
C#相關(guān)API
-
Only one exe只允許打開一個程序
int count=Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length ; if (count> 1) { // MessageBox.Show(count.ToString());調(diào)試使用 Process.GetCurrentProcess().Kill();//殺掉當(dāng)前 }
-
一個C#的API 可以用于打開一個網(wǎng)頁..應(yīng)用..或者進(jìn)程..或者控制面板內(nèi)的功能..例如打印..
public void PrintFile() { System.Diagnostics.Process process = new System.Diagnostics.Process(); //系統(tǒng)進(jìn)程 process.StartInfo.CreateNoWindow = false; //不顯示調(diào)用程序窗口 process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;// process.StartInfo.UseShellExecute = true; //采用操作系統(tǒng)自動識別模式 process.StartInfo.FileName=path; //要打印的文件路徑 process.StartInfo.Verb="print"; //指定執(zhí)行的動作,打有痢:print打開:open………… process.Start(); //開始打印 }
-
改變鼠標(biāo)位置和隱藏鼠標(biāo)
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; }
-
輸出棧堆
string trackStr = new System.Diagnostics.StackTrace().ToString(); Debug.Log ("Stack Info:" + trackStr);
數(shù)學(xué)相關(guān)
向量與夾角與三角函數(shù)
//U3D Vector3.forward 實際是(0,0,1) 向前的意思 也就是右上角Z軸方向
//forward是藍(lán)色箭頭方向 back是反方向 right是紅色箭頭方向 left反之 up是綠色箭頭方向 down反之
Vector3 vector = targetPos - originPos;//任意兩點向量 = V3目標(biāo)位置 - V3起點位置
float angle = Vector3.Angle(from, to); //向量夾角 v3.angle(向量A,向量B)
Vector3.Normalize;//單位向量
//Deg2Rad 度轉(zhuǎn)弧度 ; Rad2Deg 弧度轉(zhuǎn)度
//求角度的三角函數(shù)值
Mathf.Sin(Mathf.Deg2Rad * angle);
//求變長求角度
Mathf.Atan2(y,x) * Mathf.Rad2Deg;
其他
Windows工具:
svn項目同步
AutoHotKey作為快捷鍵操作打開
Clover作為打開文件夾的工具
SETUNA作為截圖工具-
Mac雞工具
連接:可以使用vnc viewer
項目管理:Cornerstone 調(diào)試
調(diào)試安卓:直接在調(diào)試面板Console/Profiler輸入ip鏈接(unity在2020的新版中甚至支持無需編譯改代碼)
蘋果:鏈接XCode調(diào)試