Unity3D相关知识点笔记汇总
这篇⽂章将作为⼀些平时的⼩知识点笔记来记录,如果有错误望指出来,也欢迎⼤家在评论底下分享你们的笔记。
1.检测点击或者触摸到UI。
public static bool CheckClickUI()
{
bool isClickUI = false;
if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer)
{
if (EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId))
{
isClickUI = true;
}
}
error parse newelse if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.OSXEditor)
{
if (EventSystem.current.IsPointerOverGameObject())
{
isClickUI = true;
}
}
return isClickUI;
}
2.发现content size fitter使⽤后,宽和⾼没有实时刷新,⽽是下⼀帧刷新,不知道是不是bug,这⾥要调⽤ ForceUpdateCanvases() 来强制刷新Canvas。
Canvas.ForceUpdateCanvases();
3.获取⽂本的绘制长度,不同于text的rectTransform.sizeDelta。
public static int GetFontlen(string str)
{
int len = 0;
Font font;
font = Font.CreateDynamicFontFromOSFont("Arial", 25);
font.RequestCharactersInTexture(str);
for (int i = 0; i < str.Length; i++)
{
CharacterInfo ch;
font.GetCharacterInfo(str[i], out ch);
len += ch.advance;
}
return len;
}
4.游戏的FPS,不知道为什么很多⼈都还要⾃⼰去计算?
Time.smoothDeltaTime;
5.简便⽅法随机 Vector2 和 Vector3。
UnityEngine.Random.insideUnitCircle;
UnityEngine.Random.insideUnitSphere;
6.利⽤富⽂本可以改变OnGUI上⾯的按钮和⽂字的⼤⼩。
void OnGUI()
{
GUILayout.Label("<color=green><size=80>我是⼤⽂字</size></color>");
GUILayout.Button("<color=green><size=80>我是⼤按钮</size></color>");
}
7.计算代码执⾏⽤时。
System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
//
stopwatch.Stop();
TimeSpan timeSpan = stopwatch.Elapsed;
8.获取⾃⼰,⼦对象和⼦对象的⼦对象……
Transform[] ts = Obj.GetComponentsInChildren<Transform>();
for (int i = 0; i < ts.Length; i++)
{
ts[i].gameObject.layer = LayerMask.NameToLayer("UI");
}
9.windows控制台窗⼝显⽰⼿机Debug信息
创建⼀个批处理⽂件,输⼊以下代码,保存为.bat格式,连接⼿机后双击该⽂件即可显⽰Debug信息了,电脑必须安装adb,⼿机必须打开开发者模式。
@echo off
start cmd /k "adb logcat -s Unity"
10.判断对象为空不要⽤以下的代码,是因为gameobject是unity的对象,它除了在托管内存区域有⼀份对象外,还在native内存区域存在⼀份对象,这两份对象通过⼀个我们可以称为内存桥(Memory Bridge)来交流,这个多少会造成⼀些overhead。
if (gameObject == null)
{
}
要尽量⽤以下的代码来判空操作
if (System.Object.ReferenceEquals(gameObject, null))
{
}
11.⽤CompareTag()代替gameobject.tag,不然会造成上⾯的Memory Bridge的overhead,以及会产⽣
gc。
12.使⽤static batch时,要将这些物体最开始就放⼊场景中,并勾选static才能使static batch⽣效。在运⾏时⾃动⽣成的物体,就算勾选了static batch,也不会和场景中默认的static batch 的物体合并到⼀起。
13.对⽂件⽐较⼤,且使⽤⽐较频繁的⾳频⽂件,勾选⾳频⽂件的loadType 设置为compressed in memory来压缩。
14.勾选了mip map会导致贴图的内存占⽤增⾼原来的30%。因此,那些可以确保不会随着游戏的进⾏,与摄像机的距离发⽣明显变化的物
体,例如UI,天空盒,主⾓等不需要勾选mip map。其他的物体,⽐如3D世界中的场景物件可以按需勾选mip map。
15.使⽤GPU Instancing功能,减少Draw Call,这种⼀般⽤于绘制⼤量简单的相似的物体,⽐如成⽚的草地,树⽊等。
16.使⽤LOD是⽤⼀定的内存和CPU时间,来换取Draw call,填充率和现存带宽。但这项技术建议不要⼀开始就使⽤,只有当我们意识到性
能问题再GPU端时,且有⼀定的内存和CPU预算时,才考虑使⽤LOD功能。可以看到的是:如果游戏有很丰富的场景,摄像机可以看到很
远时,就可以在早期就使⽤LOD,若是俯视⾓,固定视⾓,室内等场景时,或许并不需要使⽤LOD。
17.对于不交互的UI元素,要禁⽤Ratcast Target选项,我们可以重写这些创建接⼝,默认禁⽤Ratcast Target。
18.UI动静分离,将Canvas分为三个,Static,Incidental Dynamic,和Continuous Dynamic。Static的Canvas下主要放⼀些背景图⽚
的元素,基本上从来都不会动的。Incidental Dynamic的canvas下主要放⼀些响应事件的UI,⽐如提⽰框,包含UI按钮的UI等。
Continuous Dynamic下放⼀些频繁变化的UI,⽐如进度条或者有动画的UI元素。
19.为World  Canvas指定⼀个Camera,否则它会每帧都执⾏Camera.Main,⽽Camera.Main会持续调⽤Gameobj.Find⽅法。
20.在性能不敏感的时期主动出发垃圾回收(System.GC.Collect⽅法),⽐如在切换场景,暂停游戏时等。
21.在使⽤string时,若有多字符的链接操作(即+操作符),若要处理较多字符串的连接,则使⽤stringBuilder类;若较少,则使⽤
String.Format⽅法或者String.Concact⽅法。多字符连接数⼤于2时,就避免使⽤+操作符了。
StringBuilder sb = new StringBuilder(5); //当指定分配⼤⼩之后,性能就会得到提升。在达到容量之前,它不会为其⾃⼰重新分配空间。如果超过指定⼤⼩系统会当前sb.Append('china');
StringBuilder sb = new StringBuilder("Hello World!");
sb.Append(" What a beautiful day.");
int MyInt = 25;
StringBuilder sb = new StringBuilder("Your total is ");
sb.AppendFormat("{0:C}  ",  MyInt);
22.在调⽤UnityAPI时,那些会返回⼀个数组的API都会在堆上分配新的内存空间,⽐如GetComponents<T>(),mesh.vertices等。每次
调⽤都会创建⼀个全新的数据,因此,我们必须谨慎的调⽤这些⽅法,并缓存结果。
23.GetComponent()会有⼀定的GC产⽣,应该避免频繁调⽤并缓存,禁⽌在Update⾥⾯调⽤GetComponent()相关的⽅法。
24.必要情况下,在Dictionary的键中,我们要缓存Unity对象时,使⽤UnityObject的InstanceID来作为字典的键,⽽不是直接使⽤Object
的引⽤。
25.
==它是⽐较的栈⾥⾯的值是否相等(值⽐较)
Equals它⽐较的是堆⾥⾯的值是否相等(引⽤地址值⽐较)
Object.ReferenceEquals(obj1,obj2)它是⽐较的是内存地址是否相等
26.⽬前在⼀些典型的3D游戏的制作中,全屏不超过10万个顶点和200个draw call左右,不然对中端机器会有⼀定压⼒。
27.颜⾊编码和Color之间的转换。
Color color = ColorUtility.ToHtmlStringRGB(strcolor);
private Color GetColor(string colorcode)
{
Color color;
StringBuilder sb = new StringBuilder("#");
sb.Append(colorcode);
ColorUtility.TryParseHtmlString(sb.ToString(), out color);
return color;
}
28.获取渐变⾊。
private Gradient GetGradient(Color color)
{
Gradient gradient = new Gradient();
gradient.SetKeys(
new GradientColorKey[] { new GradientColorKey(color, 0.0f), new GradientColorKey(color, 1.0f) },            new GradientAlphaKey[] { new GradientAlphaKey(1, 0.0f), new GradientAlphaKey(1, 1.0f) }
);
return gradient;
}
29.获取渐变⾊。需要主要的是Gradient的key长度最⼤为8。
/// <summary>
/// 获取渐变⾊,Gradient的key长度最⼤为8
/// </summary>
/// <param name="strColors">颜⾊编码集合</param>
/// <returns>渐变⾊</returns>
public static Gradient GetGradient(List<string> strColors)
{
Gradient gradient = new Gradient();
GradientColorKey[] colorKey = new GradientColorKey[strColors.Count];
GradientAlphaKey[] alphaKey = new GradientAlphaKey[strColors.Count];
float offset = 1.0f / (strColors.Count - 1);
for (int i = 0; i < strColors.Count; i++)
{
Color color = GetColor(strColors[i]);
float time = i * offset;
XMDebug.Log(time);
colorKey[i].color = color;
colorKey[i].time = time;
alphaKey[i].alpha = 1.0f;
alphaKey[i].time = time;
}
gradient.SetKeys(colorKey, alphaKey);
return gradient;
}
30.设置随机种⼦
private float[] noiseValues;
void Start()
{
Random.InitState(42);
noiseValues = new float[10];
for (int i = 0; i < noiseValues.Length; i++)
{
noiseValues[i] = Random.value;
Debug.Log(noiseValues[i]);
}
}
31.时间戳的转换
/// <summary>
/// 时间戳转换为时间
/// </summary>
/// <param name="timeStamp"></param>
/// <returns></returns>
public static DateTime StampToDateTime(string timeStamp)
{
DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
long mTime = long.Parse(timeStamp + "0000");
TimeSpan toNow = new TimeSpan(mTime);
return startTime.Add(toNow);
}
/// <summary>
/// 时间转时间戳
/// </summary>
/// <param name="now"></param>
/// <returns></returns>
public static string DateTimeToStamp(DateTime now)
{
DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); // 当地时区
long timeStamp = (long)(now - startTime).TotalMilliseconds; // 相差毫秒数
return timeStamp.ToString();
}
32.复制粘贴
GUIUtility.systemCopyBuffer
33.UGUI在使⽤DOTween的时候其实有⼀些坑的,⽐如移动,⾃⼰封装⼀个拓展⽅法。
public static void Move(this RectTransform rect, Vector2 endValue, float duration, Action callback = null)
{
DOTween.To(() => { return rect.anchoredPosition; }, v => { rect.anchoredPosition = v; }, endValue, duration).OnComplete(() =>        {
callback?.Invoke();
});
}
34.从⽂本中删除富⽂本标签(HTML标签),需求⽐如要统计⽂字个数。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。