zoukankan      html  css  js  c++  java
  • Unity技巧集合

    地址:http://blog.csdn.net/stalendp/article/details/17114135

    这篇文章将收集unity的相关技巧,会不断地更新内容。

    1)保存运行中的状态

    unity在运行状态时是不能够保存的。但在运行时编辑的时候,有时会发现比较好的效果想保存。这时可以在 “Hierarchy”中复制相关对象树,暂停游戏后替换原来的,就可以了。

    2)Layer的用法

    LayerMask.NameToLayer("Ground");  // 通过名字获取layer

    3D Raycast

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. RaycastHit hit;  
    2. if(Physics.Raycast(cam3d.ScreenPointToRay(Input.mousePosition), out hit, Mathf.Infinity, (1<<LayerMask.NameToLayer("Ground")))) {  
    3. ...  
    4. }  

    2D Raycast

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. Collider2D h = Physics2D.OverlapPoint(cam2d.ScreenToWorldPoint(Input.mousePosition), (1<<LayerMask.NameToLayer("xxx")));  
    2. if(h) {  
    3. ...  
    4. }  

    3)物理摄像头取色(WebCamTexture)

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. Texture2D exactCamData() {  
    2.     // get the sample pixels  
    3.     Texture2D snap = new Texture2D((int)detectSize.x, (int)detectSize.y);  
    4.     snap.SetPixels(webcamTexture.GetPixels((int)detectStart.x, (int)detectStart.y, (int)detectSize.x, (int)detectSize.y));  
    5.     snap.Apply();  
    6.     return snap;  
    7. }  

    保存截图:

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. System.IO.File.WriteAllBytes(Application.dataPath + "/test.png", exactCamData().EncodeToPNG());  

     

    4) 操作componenent

    添加:

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. CircleCollider2D cld = (CircleCollider2D)colorYuan[i].AddComponent(typeof(CircleCollider2D));  
    2. cld.radius = 1;  

    删除:

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. Destroy(transform.gameObject.GetComponent<SpriteRenderer>());  

     

    5)动画相关

    状态Init到状态fsShake的的条件为:参数shake==true;代码中的写法:

    触发fsShake:

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. void Awake() {  
    2.     anims = new Animator[(int)FColorType.ColorNum];  
    3. }  
    4. ....  
    5. if(needShake) {  
    6.     curAnim.SetTrigger("shake");  
    7. }  


    关闭fsShake

     

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. void Update() {  
    2. ....  
    3. if(curAnim) {  
    4.     AnimatorStateInfo stateInfo = curAnim.GetCurrentAnimatorStateInfo(0);  
    5.     if(stateInfo.nameHash == Animator.StringToHash("Base Layer.fsShake")) {  
    6.         curAnim.SetBool("shake"false);  
    7.         curAnim = null;  
    8.         print ("======>>>>> stop shake!!!!");  
    9.     }  
    10. }  
    11. ....  
    12. }  

    6)scene的切换

    同步方式:

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. Application.LoadLevel(currentName);  

     

    异步方式:

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. Application.LoadLevelAsync("ARScene");  

    7)加载资源

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. Resources.Load<Texture>(string.Format("{0}{1:D2}", mPrefix, 5));  

     

    8)Tag VS. Layer

         -> Tag用来查询对象

         -> Layer用来确定哪些物体可以被raycast,还有用在camera render中

    9)旋转

    transform.eulerAngles 可以访问 rotate的 xyz

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. transform.RotateAround(pivotTransVector, Vector3.up, -0.5f * (tmp-preX) * speed);  

    10)保存数据

     

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. PlayerPrefs.SetInt("isInit_" + Application.loadedLevelName, 1);  

    11)动画编码

    http://www.cnblogs.com/lopezycj/archive/2012/05/18/Unity3d_AnimationEvent.html

    http://game.ceeger.com/Components/animeditor-AnimationEvents.html

    http://answers.unity3d.com/questions/8172/how-to-add-new-curves-or-animation-events-to-an-im.html

    12) 遍历子对象

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. Transform[] transforms = target.GetComponentsInChildren<Transform>();  
    2. for (int i = 0, imax = transforms.Length; i < imax; ++i) {  
    3.     Transform t = transforms[i];  
    4.     t.gameObject.SendMessage(functionName, gameObject, SendMessageOptions.DontRequireReceiver);  
    5. }  

    13)音效的播放

     先添加Auido Source, 设置Audio Clip, 也可以在代码中加入。然后在代码中调用audio.Play(), 参考如下代码:

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. public AudioClip aClip;  
    2. ...  
    3. void Start () {   
    4.     ...  
    5.     audio.clip = aClips;  
    6.     audio.Play();  
    7.     ...  
    8. }  

    另外,如果是3d音效的话,需要调整audio Souce中的panLevel才能听到声音,不清楚原因。

    14)调试技巧(Debug)

    可以在OnDrawGizmos函数来进行矩形区域等,达到调试的目的,请参考NGUI中的UIDraggablePanel.cs文件中的那个函数实现。

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. #if UNITY_EDITOR  
    2.     /// <summary>  
    3.     /// Draw a visible orange outline of the bounds.  
    4.     /// </summary>  
    5.     void OnDrawGizmos ()  
    6.     {  
    7.         if (mPanel != null)  
    8.         {  
    9.             Bounds b = bounds;  
    10.             Gizmos.matrix = transform.localToWorldMatrix;  
    11.             Gizmos.color = new Color(1f, 0.4f, 0f);  
    12.             Gizmos.DrawWireCube(new Vector3(b.center.x, b.center.y, b.min.z), new Vector3(b.size.x, b.size.y, 0f));  
    13.         }  
    14.     }  
    15. #endif  

    15)延时相关( StartCoroutine)

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. StartCoroutine(DestoryPlayer());  
    2. ...  
    3. IEnumerator DestoryPlayer() {  
    4.     Instantiate(explosionPrefab, transform.position, transform.rotation);  
    5.     gameObject.renderer.enabled = false;  
    6.     yield return new WaitForSeconds(1.5f);  
    7.     gameObject.renderer.enabled = true;  
    8. }  

     

    16)Random做种子

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. Random.seed = System.Environment.TickCount;   
    2. 或者  
    3. Random.seed = System.DateTime.Today.Millisecond;  

     

     

    17) 调试技巧(debug),可以把值方便地在界面上打印出来

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. void OnGUI() {  
    2.     GUILayout.Label("deltaTime is: " + Time.deltaTime);  
    3. }  

    18)分发消息

    sendMessage, BroadcastMessage等

    19) 游戏暂停(对timeScale进行设置)

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. Time.timeScale = 0;  

    20) 实例化一个prefab

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. Rigidbody2D propInstance = Instantiate(backgroundProp, spawnPos, Quaternion.identity) as Rigidbody2D;  

    21)Lerp函数的使用场景

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. // Set the health bar's colour to proportion of the way between green and red based on the player's health.  
    2. healthBar.material.color = Color.Lerp(Color.green, Color.red, 1 - health * 0.01f);  

    22)在特定位置播放声音

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. // Play the bomb laying sound.  
    2. AudioSource.PlayClipAtPoint(bombsAway,transform.position);  

    23) 浮点数相等的判断(由于浮点数有误差, 所以判断的时候最好不要用等号,尤其是计算出来的结果)

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. if (Mathf.Approximately(1.0, 10.0/10.0))  
    2.     print ("same");  

     

    24)通过脚本修改shader中uniform的值

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. //shader的写法  
    2. Properties {  
    3.     ...  
    4.     disHeight ("threshold distance", Float) = 3  
    5. }  
    6.    
    7. SubShader {  
    8.     Pass {  
    9.         CGPROGRAM  
    10.         #pragma vertex vert    
    11.         #pragma fragment frag   
    12.         ...  
    13.         uniform float disHeight;  
    14.         ...   
    15. // ===================================  
    16. // 修改shader中的disHeight的值  
    17. gameObject.renderer.sharedMaterial.SetFloat("disHeight", height);  

    25) 获取当前level的名称

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. Application.loadedLevelName  

    26)双击事件

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. void OnGUI() {  
    2.     Event Mouse = Event.current;  
    3.     if ( Mouse.isMouse && Mouse.type == EventType.MouseDown && Mouse.clickCount == 2) {  
    4.         print("Double Click");  
    5.     }  
    6. }  

    27) 日期:

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. System.DateTime dd = System.DateTime.Now;  
    2. GUILayout.Label(dd.ToString("M/d/yyyy"));  

    28)  RootAnimation中移动的脚本处理

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
    1. class RootControl : MonoBehaviour {  
    2.     void OnAnimatorMove() {  
    3.         Animator anim = GetComponent<Animator>();  
    4.         if(anim) {  
    5.             Vector3 newPos = transform.position;  
    6.             newPos.z += anim.GetFloat("Runspeed") * Time.deltaTime;  
    7.             transform.position = newPos;  
    8.         }  
    9.     }  
    10. }  

    29) BillBoard效果(广告牌效果,或者向日葵效果,使得对象重视面向摄像机)

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. public class BillBoard : MonoBehaviour {  
    2.     // Update is called once per frame  
    3.     void Update () {  
    4.         transform.LookAt(Camera.main.transform.position, -Vector3.up);  
    5.     }  
    6. }  

    30)script中的属性编辑器(Property Drawers),还可以自定义属性编辑器

    参考: http://blogs.unity3d.com/2012/09/07/property-drawers-in-unity-4/

    其中Popup好像无效,但是enum类型的变量,能够达到Popup的效果

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. public class Example : MonoBehaviour {  
    2.     public string playerName = "Unnamed";  
    3.   
    4.     [Multiline]  
    5.     public string playerBiography = "Please enter your biography";  
    6.   
    7.     [Popup ("Warrior""Mage""Archer""Ninja")]  
    8.     public string @class = "Warrior";  
    9.   
    10.     [Popup ("Human/Local""Human/Network""AI/Easy""AI/Normal""AI/Hard")]  
    11.     public string controller;  
    12.   
    13.     [Range (0, 100)]  
    14.     public float health = 100;  
    15.   
    16.     [Regex (@"^(?:d{1,3}.){3}d{1,3}$""Invalid IP address! Example: '127.0.0.1'")]  
    17.     public string serverAddress = "192.168.0.1";  
    18.   
    19.     [Compact]  
    20.     public Vector3 forward = Vector3.forward;  
    21.   
    22.     [Compact]  
    23.     public Vector3 target = new Vector3 (100, 200, 300);  
    24.   
    25.     public ScaledCurve range;  
    26.     public ScaledCurve falloff;  
    27.   
    28.     [Angle]  
    29.     public float turnRate = (Mathf.PI / 3) * 2;  
    30. }  

    31)Mobile下面使用lightmapping问题的解决方案

    在mobile模式下,lightmapping可能没有反应,可以尝试使用mobile下的shader,可以解决问题。更多请参考:http://forum.unity3d.com/threads/138978-Lightmap-problem-in-iPhone

    32) Unity下画线的功能(用于debug)

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. Debug.DrawLine (Vector3.zero, new Vector3 (10, 0, 0), Color.red);  

    33)Shader中代码的复用(CGINCLUDE的使用)

     

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. Shader "Self-Illumin/AngryBots/InterlacePatternAdditive" {  
    2.     Properties {  
    3.         _MainTex ("Base", 2D) = "white" {}  
    4.         //...  
    5.     }  
    6.       
    7.     CGINCLUDE  
    8.   
    9.         #include "UnityCG.cginc"  
    10.   
    11.         sampler2D _MainTex;  
    12.         //...                 
    13.                           
    14.         struct v2f {  
    15.             half4 pos : SV_POSITION;  
    16.             half2 uv : TEXCOORD0;  
    17.             half2 uv2 : TEXCOORD1;  
    18.         };  
    19.   
    20.         v2f vert(appdata_full v) {  
    21.             v2f o;  
    22.             // ...  
    23.             return o;   
    24.         }  
    25.           
    26.         fixed4 frag( v2f i ) : COLOR {    
    27.             // ...  
    28.             return colorTex;  
    29.         }  
    30.       
    31.     ENDCG  
    32.       
    33.     SubShader {  
    34.         Tags {"RenderType" = "Transparent" "Queue" = "Transparent" "Reflection" = "RenderReflectionTransparentAdd" }  
    35.         Cull Off  
    36.         ZWrite Off  
    37.         Blend One One  
    38.           
    39.     Pass {  
    40.       
    41.         CGPROGRAM  
    42.           
    43.         #pragma vertex vert  
    44.         #pragma fragment frag  
    45.         #pragma fragmentoption ARB_precision_hint_fastest   
    46.           
    47.         ENDCG  
    48.            
    49.         }  
    50.                   
    51.     }   
    52.     FallBack Off  
    53. }  

    34)获取AnimationCurve的时长

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. _curve.keys[_curve.length-1].time;  

    35)C#中string转变成byte[]:

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. byte[] b1 = System.Text.Encoding.UTF8.GetBytes (myString);  
    2. byte[] b2 = System.Text.Encoding.ASCII.GetBytes (myString);  
    3. System.Text.Encoding.Default.GetBytes(sPara)  
    4. new ASCIIEncoding().GetBytes(cpara);  
    5. char[] cpara=new char[bpara.length];  
    6. for(int i=0;i <bpara.length;i ++){char[i]=system.convert.tochar(bpara[i]);}     

    36) 排序

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. list.Sort(delegate(Object a, Object b) { return a.name.CompareTo(b.name); });  

    37) NGUI的相关类关系:

    38)使得脚本能够在editor中实时反映:

    在脚本前加上:[ExecuteInEditMode], 参考UISprite。

    39)隐藏相关属性

    属性前加上 [HideInInspector],在shader中也适用;

    比如:

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. public class ResourceLoad : MonoBehaviour {  
    2.     [HideInInspector] public string ressName = "Sphere";  
    3.     public string baseUrl = "http://192.168.56.101/ResUpdate/{0}.assetbundle";  
    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. Shader "stalendp/imageShine" {  
    2.     Properties {  
    3.         [HideInInspector] _image ("image", 2D) = "white" {}  
    4.         _percent ("_percent", Range(-5, 5)) = 1  
    5.         _angle("_angle", Range(0, 1)) = 0  
    6.     }  

    40)属性的序列化

    可被序列化的属性,可以显示在Inspector面板上(可以使用HideInInspector来隐藏);public属性默认是可被序列化的,private默认是不可序列化的。使得private属性可被序列化,可以使用[SerializeField]来修饰。如下:

     

    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. [SerializeField] private string ressName = "Sphere";  

    41)Shader编译的多样化(Making multiple shader program variants

    shader通常如下的写法:

    #pragma multi_compile FANCY_STUFF_OFF FANCY_STUFF_ON
    这样可以把Shader编译成多个版本。使用的时候,局部设置Material.EnableKeyword, DisableKeyword;或则 全局设置Shader.EnableKeyword and DisableKeyword进行设置。
    42)多个scene共享内容
    [csharp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1.  void Awake() {  
    2.     DontDestroyOnLoad(transform.gameObject);  
    3. }  
  • 相关阅读:
    Flask框架基础4
    Flask框架基础3
    Flask框架基础2
    Flask框架基础1
    项目上线流程-Django后端+vue前端
    Git操作
    DRF-jwt认证
    四种方式实现单例模式
    drf框架4-views视图家族操作
    drf框架3-ModelSerializer操作序列化与反序列化
  • 原文地址:https://www.cnblogs.com/forlove/p/3785318.html
Copyright © 2011-2022 走看看