您好,欢迎来到化拓教育网。
搜索
您的当前位置:首页unity3d小技巧合集

unity3d小技巧合集

来源:化拓教育网


【Unity】技巧集合

转发,请保持地址:http://blog.csdn.net/stalendp/article/details/17114135

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

1)保存运行中的状态

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

2)Layer的用法

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

3D Raycast

[csharp] view plaincopy

1. 2. RaycastHit hit; if(Physics.Raycast(cam3d.ScreenPointToRay(Input.mousePosition), out hit, Mathf.Infinity, (1<[csharp] view plaincopy

1. 2. 3. 4. Collider2D h = Physics2D.OverlapPoint(cam2d.ScreenToWorldPoint(Input.mousePosition), (1<[csharp] view plaincopy

1. 2. 3. 4. 5. 6. 7. Texture2D exactCamData() { // get the sample pixels Texture2D snap = new Texture2D((int)detectSize.x, (int)detectSize.y); snap.SetPixels(webcamTexture.GetPixels((int)detectStart.x, (int)detectStart.y, (int)detectSize.x, (int)detectSize.y)); snap.Apply(); return snap; } 保存截图:

[csharp] view plaincopy

1. System.IO.File.WriteAllBytes(Application.dataPath + \"/test.png\", exactCamData().EncodeToPNG()); 4) 操作componenent

添加:

[csharp] view plaincopy

1. 2. CircleCollider2D cld = (CircleCollider2D)colorYuan[i].AddComponent(typeof(CircleCollider2D)); cld.radius = 1; 删除:

[csharp] view plaincopy

1. Destroy(transform.gameObject.GetComponent()); 5)动画相关

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

触发fsShake:

[csharp] view plaincopy

1. 2. 3. 4. 5. 6. 7. void Awake() { anims = new Animator[(int)FColorType.ColorNum]; } .... if(needShake) { curAnim.SetTrigger(\"shake\"); }

关闭fsShake

[csharp] view plaincopy

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. void Update() { .... if(curAnim) { AnimatorStateInfo stateInfo = curAnim.GetCurrentAnimatorStateInfo(0); if(stateInfo.nameHash == Animator.StringToHash(\"Base Layer.fsShake\")) { curAnim.SetBool(\"shake\", false); curAnim = null; print (\"======>>>>> stop shake!!!!\"); } } .... } 6)scene的切换

同步方式:

[csharp] view plaincopy

1. Application.LoadLevel(currentName); 异步方式:

[csharp] view plaincopy

1. Application.LoadLevelAsync(\"ARScene\"); 7)加载资源

[csharp] view plaincopy

1. Resources.Load(string.Format(\"{0}{1:D2}\", mPrefix, 5)); 8)Tag VS. Layer

-> Tag用来查询对象

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

9)旋转

transform.eulerAngles 可以访问 rotate的 xyz

[csharp] view plaincopy

1. transform.RotateAround(pivotTransVector, Vector3.up, -0.5f * (tmp-preX) * speed); 10)保存数据

[csharp] view plaincopy

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

1. 2. 3. 4. 5. Transform[] transforms = target.GetComponentsInChildren(); for (int i = 0, imax = transforms.Length; i < imax; ++i) { Transform t = transforms[i]; t.gameObject.SendMessage(functionName, gameObject, SendMessageOptions.DontRequireReceiver); } 13)音效的播放

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

[csharp] view plaincopy

1. 2. 3. 4. 5. public AudioClip aClip; ... void Start () { ... audio.clip = aClips; 6. 7. 8. audio.Play(); ... } 另外,如果是3d音效的话,需要调整audio Souce中的panLevel才能听到声音,不清楚原因。

14)调试技巧(Debug)

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

[csharp] view plaincopy

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. #if UNITY_EDITOR ///

/// Draw a visible orange outline of the bounds. /// void OnDrawGizmos () { if (mPanel != null) { Bounds b = bounds; Gizmos.matrix = transform.localToWorldMatrix; Gizmos.color = new Color(1f, 0.4f, 0f); Gizmos.DrawWireCube(new Vector3(b.center.x, b.center.y, b.min.z), new Vector3(b.size.x, b.size.y, 0f)); } } #endif 15)延时相关( StartCoroutine)

[csharp] view plaincopy

1. 2. 3. 4. 5. 6. 7. 8. StartCoroutine(DestoryPlayer()); ... IEnumerator DestoryPlayer() { Instantiate(explosionPrefab, transform.position, transform.rotation); gameObject.renderer.enabled = false; yield return new WaitForSeconds(1.5f); gameObject.renderer.enabled = true; } 16)Random做种子

[csharp] view plaincopy

1. Random.seed = System.Environment.TickCount; 2. 3. 或者 Random.seed = System.DateTime.Today.Millisecond; 17) 调试技巧(debug),可以把值方便地在界面上打印出来

[csharp] view plaincopy

1. 2. 3. void OnGUI() { GUILayout.Label(\"deltaTime is: \" + Time.deltaTime); } 18)分发消息

sendMessage, BroadcastMessage等

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

[csharp] view plaincopy

1. Time.timeScale = 0; 20) 实例化一个prefab

[csharp] view plaincopy

1. Rigidbody2D propInstance = Instantiate(backgroundProp, spawnPos, Quaternion.identity) as Rigidbody2D; 21)Lerp函数的使用场景

[csharp] view plaincopy

1. 2. // Set the health bar's colour to proportion of the way between green and red based on the player's health. healthBar.material.color = Color.Lerp(Color.green, Color.red, 1 - health * 0.01f); 22)在特定位置播放声音

[csharp] view plaincopy

1. 2. // Play the bomb laying sound. AudioSource.PlayClipAtPoint(bombsAway,transform.position); 23) 浮点数相等的判断(由于浮点数有误差, 所以判断的时候最好不要用等号,尤其是计算出来的结果)

[csharp] view plaincopy

1. 2. if (Mathf.Approximately(1.0, 10.0/10.0)) print (\"same\"); 24)通过脚本修改shader中uniform的值

[csharp] view plaincopy

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. //shader的写法 Properties { ... disHeight (\"threshold distance\", Float) = 3 } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag ... uniform float disHeight; ... // =================================== // 修改shader中的disHeight的值 gameObject.renderer.sharedMaterial.SetFloat(\"disHeight\", height); 25) 获取当前level的名称

[csharp] view plaincopy

1. Application.loadedLevelName 26)双击事件

[csharp] view plaincopy

1. 2. 3. 4. 5. 6. void OnGUI() { Event Mouse = Event.current; if ( Mouse.isMouse && Mouse.type == EventType.MouseDown && Mouse.clickCount == 2) { print(\"Double Click\"); } }

27) 日期:

[csharp] view plaincopy

1. System.DateTime dd = System.DateTime.Now; 2. GUILayout.Label(dd.ToString(\"M/d/yyyy\")); 28) RootAnimation中移动的脚本处理

[csharp] view plaincopy

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. class RootControl : MonoBehaviour { void OnAnimatorMove() { Animator anim = GetComponent(); if(anim) { Vector3 newPos = transform.position; newPos.z += anim.GetFloat(\"Runspeed\") * Time.deltaTime; transform.position = newPos; } } } 29) BillBoard效果(广告牌效果,或者向日葵效果,使得对象重视面向摄像机)

[csharp] view plaincopy

1. 2. 3. 4. 5. 6. public class BillBoard : MonoBehaviour { // Update is called once per frame void Update () { transform.LookAt(Camera.main.transform.position, Vector3.up); } } 30)script中的属性编辑器(Property Drawers),还可以自定义属性编辑器

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

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

[csharp] view plaincopy

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. public class Example : MonoBehaviour { public string playerName = \"Unnamed\"; [Multiline] public string playerBiography = \"Please enter your biography\"; [Popup (\"Warrior\", \"Mage\", \"Archer\", \"Ninja\")] public string @class = \"Warrior\"; [Popup (\"Human/Local\", \"Human/Network\", \"AI/Easy\", \"AI/Normal\", \"AI/Hard\")] 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. public string controller; [Range (0, 100)] public float health = 100; [Regex (@\"^(?:\\d{1,3}\\.){3}\\d{1,3}$\", \"Invalid IP address!\\nExample: '127.0.0.1'\")] public string serverAddress = \"192.168.0.1\"; [Compact] public Vector3 forward = Vector3.forward; [Compact] public Vector3 target = new Vector3 (100, 200, 300); public ScaledCurve range; public ScaledCurve falloff; [Angle] public float turnRate = (Mathf.PI / 3) * 2; } 31)Mobile下面使用lightmapping问题的解决方案

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

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

[csharp] view plaincopy

1. Debug.DrawLine (Vector3.zero, new Vector3 (10, 0, 0), Color.red);

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

[cpp] view plaincopy

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

[csharp] view plaincopy

1. _curve.keys[_curve.length-1].time; 35)C#中string转变成byte[]:

[csharp] view plaincopy

1. 2. 3. 4. 5. 6. byte[] b1 = System.Text.Encoding.UTF8.GetBytes (myString); byte[] b2 = System.Text.Encoding.ASCII.GetBytes (myString); System.Text.Encoding.Default.GetBytes(sPara) new ASCIIEncoding().GetBytes(cpara); char[] cpara=new char[bpara.length]; for(int i=0;i [csharp] view plaincopy

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

1. 2. 3. public class ResourceLoad : MonoBehaviour { [HideInInspector] public string ressName = \"Sphere\"; public string baseUrl = \"http://192.168.56.101/ResUpdate/{0}.assetbundle\"; [csharp] view plaincopy

1. 2. 3. 4. 5. 6. Shader \"stalendp/imageShine\" { Properties { [HideInInspector] _image (\"image\", 2D) = \"white\" {} _percent (\"_percent\", Range(-5, 5)) = 1 _angle(\"_angle\", Range(0, 1)) = 0 } 40)属性的序列化

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

[csharp] view plaincopy

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

1. 2. 3. void Awake() { DontDestroyOnLoad(transform.gameObject); } 43) 使用Animation播放unity制作的AnimationClip:

首先需要设置AnimationType的类型为1 (需要在animationClip的Debug模式的属性中进行设置,如下图。另外,如果需要在animator中播放动画,需要类型为2);

代码如下:

[csharp] view plaincopy

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. string clipName = \"currentClip\"; AnimationClip clip = ...; // 设置animationClip if (anim == null) { anim = gameObject.AddComponent(); } anim.AddClip(clip, clipName); anim[clipName].speed = _speedScale; // 计算时间 float duration = anim[clipName].length; duration /= _speedScale; // 播放动画 anim.Play(clipName); yield return new WaitForSeconds(duration + 0.1f); // 动画结束动作 anim.Stop(); anim.RemoveClip(clipName);

44) RenderTexture的全屏效果 cs端:

[csharp] view plaincopy

1. 2. 3. 4. 5. MeshFilter mesh = quard.GetComponent (); // 创建和摄像机相关的renderTexture RenderTexture rTex = new RenderTexture ((int)cam.pixelWidth, (int)cam.pixelHeight, 16); cam.targetTexture = rTex; mesh.renderer.material.mainTexture = rTex; shader端:

[csharp] view plaincopy

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. #include \"UnityCG.cginc\" sampler2D _MainTex; sampler2D _NoiseTex; struct v2f { half4 pos:SV_POSITION; half2 uv : TEXCOORD0; float4 srcPos: TEXCOORD1; }; v2f vert(appdata_full v) { v2f o; o.pos = mul (UNITY_MATRIX_MVP, v.vertex); o.uv = v.texcoord.xy; o.srcPos = ComputeScreenPos(o.pos); return o; } fixed4 frag(v2f i) : COLOR0 { float tmp = saturate(1-(length(i.uv-float2(0.5,0.5)))*2)*0.04; float2 wcoord = (i.srcPos.xy/i.srcPos.w) + tex2D(_NoiseTex, i.uv) * tmp - tmp/2; return tex2D(_MainTex, wcoord); } 45)使用RenderTexture制作屏幕特效:

[csharp] view plaincopy

1. 2. 3. 4. 5. 6. 7. [ExecuteInEditMode] public class MyScreenEffect : MonoBehaviour { ... void OnRenderImage(RenderTexture source, RenderTexture dest) { Graphics.Blit(source, dest, material); } } 如果需要多次渲染,需要使用RenderTexture.GetTemporary生成临时的RenderTexture,这个方法会从unity维护的池中获取,所以在使用完

RenderTexture后,尽快调用RenderTexture.ReleaseTemporary使之返回池中。 RenderTexture存在于GPU的DRAM中,具体实现可以参考Cocos2dx中的写法来理解(CCRenderTexture.cpp中有具体实现)。GPU的架构请参考:

http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter30.html 46) 特定条件下暂停unity

在调试战斗的时候,需要在特定条件下暂停unity,以便查看一些对象的设置。可以使用Debug.Break();来达到目的。这是需要处于debug模式,才能够达到效果。

47)在特定exception发生时暂停执行;

默认情况下,unity在遇到异常时,是不会停止执行的。但是如果要在nullReferenceException等exception发生时,进行调试。可以在MonoDevelop的菜单中选择Run/Exceptions..., 做相关设置:

48)NGUI性能建议

相关知识:1)在NGUI中,一个Panel对应一个DrawCall(当然一个panel里面的UISprite来自多个图集,就会有多个drawCall);2)当一个UISprite等UIWidget控件的active改变时,DrawCall会重新计算一遍;3)DrawCall的计算比较耗时,首先会收集DrawCall下所有UIWidget的

verts,norms,trans,uvs,cols等信息,还要向GPU传输数据,相对比较耗时。 问题:当在一个Panel中有大量的UIWidget,有一部分是经常改变active的,有些部分则不怎么变。这样就会导致频繁地计算DrawCall。

性能提升方案:把经常改变active的控件单独到一个panel中。把不怎么变动的部分到另外的panel中。

49)NGUI中设置自定义的Shader,并改变properties的值。 使用UITexture,可以设置自定义的Material。需要注意的是,改变properties的值,需要使用UITexture中的drawCall的dynamicMaterial,如下:

[cpp] view plaincopy

1. 2. UITexture tex=....; tex.drawCall.dynamicMaterial.SetFloat(\"_percent\", du/DU);

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuo9.cn 版权所有 赣ICP备2023008801号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务