记录Unity遇到的坑

where

where字句后面有new()约束的话,T类型必须有public且没有参数的构造函数。

长度和占位

bit 位, 即 0或1
Byte 字节, 占8位, 即2^8, 即最大256
char 占1个字节, 即256
int 占4个字节, 即32位, 即2^32, 即4294967296, 因为要分正负号, 就得再÷2, 即[-2147483647, 2147483647]
C#里的int就是int32, 另外C#里还有int64, 你猜是占多少位…
int64 即64位, 占8个字节, 即2^64, 即18446744073709551616, 因为要分正负号, 就得再÷2
C#里的long和int64一样长, 不同的是int64是引用类型, 转为long时会损失精度
另外
short是16位
float是64位和int一样, 但只能保证6-7位有效数字:

1bit(符号位) 8bits(指数位) 23bits(尾数位)
精度是由尾数的位数来决定的
float2^23 = 8388608,一共七位,这意味着最多能有7位有效数字,
但绝对能保证的为6位,也即float的精度为6~7位有效数字;

分辨率

我们说的视频1080p, 是指视频长宽1920×1080 = 2073600个像素, 也就是我们手机拍照时, 常说的200万像素
2k 是 2560x1440
4k 是 3840*2160
注意: 只表示16:9的长宽比下, 公认的默认数值

bps和Bps

bps: bits per second, 传的是bit, 就是位, 就是0101010111
注意: 在计算传输速率时是以1000进的, 即1M bps = 1000K bps

Bps: Byte per second, 字节, 1M Bps = 1024K Bps

所以你的10M网速就是10 000 000位每秒, 1个字节是8位, 所以实际下载速度是:
10 000 000 ÷ 8 = 1 250 000字节, 就是1M多点

K M G T …

1KB (Kilobyte 千字节)=1024B,
1MB (Megabyte 兆字节 简称“兆”)=1024KB,
1GB (Gigabyte 吉字节 又称“千兆”)=1024MB,
1TB (Trillionbyte 万亿字节 太字节)=1024GB,其中1024=2^10 ( 2 的10次方),
1PB(Petabyte 千万亿字节 拍字节)=1024TB,
1EB(Exabyte 百亿亿字节 艾字节)=1024PB,
1ZB (Zettabyte 十万亿亿字节 泽字节)= 1024 EB,
1YB (Jottabyte 一亿亿亿字节 尧字节)= 1024 ZB,
1BB (Brontobyte 一千亿亿亿字节)= 1024 YB.
抄自: https://xuexi.zqnf.com/844056.html

const 和 readonly的区别

readonly可以用构造函数赋值

拼url

string str = “戴拿”;
string.Format("{0}", str);
那如果我想拼一个"{“进去呢, 会报错怎么办?
那就得打上”{ {", 就表示{

空格表示为%20, 双引号表示为%22
https://blog.csdn.net/superit401/article/details/78052965

IList< T >和List< T >的区别:

List< T >, 她里面有Sort, CopyTo, FindIndex, Reverse, Contains, ForEach, Add等等一堆方法

public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable
{
     
	//(方法太多就不贴了, 想看的自己在List身上按F12去看)
}

而IList< T >, 她只有以下功能

public interface IList<T> : ICollection<T>, IEnumerable<T>, IEnumerable
{
     
    T this[int index] {
      get; set; }
    int IndexOf(T item);
    void Insert(int index, T item);
    void RemoveAt(int index);
}

人家List< T >会的本领: 排序, 翻转, 复制, 判断包含等, 她都不会, 她只能用来存放数组;
既然她远不如List< T >强大, 那什么情况下用她而不用List< T >呢?
答: 节省空间的时候

极端的UI优化

用全屏UI时, 禁用世界相机
非全屏UI时, 用世界相机截屏, 把截图铺在UI底下做背景, 然后禁用世界相机

不需要进行点击交互的组件,取消勾选Raycast Target

CullTransparentMesh: 新版本 , Alpha 为0 的时候则无Overdraw(做"点击屏幕任意位置关闭界面"的时候, 把Alpha为0的背景图勾选上这个)

取随机不重复的一种实现办法:While

这方法肯定是没有效率的, 但是简单

		for (int i = 1; i < num; i++)
        {
     
            while (rooms.Contains(pos))
            {
     
               pos = RandomPos();
            }
            rooms.Add(pos);
        }

Static的列表不用的时候记得Clear();

一直占内存
你下次用的时候, 里面存的东西还在里面躺着

Json的读取和保存

方法非常多
1.用JsonUtility
注意!
要用[System.Serializable]特性, 序列化才能转成Json;
因为是轻量型, 不能读存多维数组
用法: JsonUtility.FromJson();

2.用Newtonsoft.Json;
注意!
要下载dll
可解析多维数组, 形如List>

	using Newtonsoft.Json;
	//类存为Json
	public static void SaveJson(MapData mapData)
    {
     
        if (!File.Exists(JsonPath()))
        {
     
            File.Create(JsonPath());
        }

        string json = JsonConvert.SerializeObject(mapData);
        File.WriteAllText(JsonPath(), json);
        //Debug.Log("保存成功");
    }
    
	//读取Json
    public static MapData ReadJson()
    {
     
        if (!File.Exists(JsonPath()))
        {
     
            Debug.LogError("文件不存在");
            return null;
        }

        string json = File.ReadAllText(JsonPath());
        MapData mapData = JsonConvert.DeserializeObject<MapData>(json);

        return mapData;
    }

改变2D Sprite的颜色

block.GetComponent().color = Color.red;

物体从相机中消失了

看相机的Layer有没有取消勾选
看相机有没有勾选OcclusionCulling(遮挡剔除)

自定义yield

很好的文章:
https://blog.csdn.net/qq_31967569/article/details/83305415

一个方法0个引用, 但是在执行, 有3种情况

0 是生命周期方法
1 用了Invoke(“方法名”,1f); 这时候Ctrl+F搜一下方法名就行了
2 直接把方法挂在物体上了, 找吧
3 方法挂在了动画的Event上, 今天遇到这个坑, 这时候Animation就变成了ReadOnly, 但是Event仍然可以在原模型中找到那个动画下的Event来改

代码调整画质

//设置画质
int qualityLevel = 0;//即Very Low
QualitySettings.SetQualityLevel(qualityLevel, true);
//Get画质
QualitySettings.GetQualityLevel();

在Hierarchy面板中, List的拖拽赋值

public List<GameObject> equips;

然后在Hierarchy面板中会显示这个list, 然后在Size输入5, 然后把5个物体依次拖进来对吧
简单的方法是: 直接选中多个物体, 直接拖进list中

Switch 我赌很多人不知道这个

		int a = 0;
        switch (a)
        {
     
            case 0:
            	//这里不写break;
            case 1:
                //0和1都会执行Do();
                Do();
                break;
            case 2:
                break;
            default:
                break;
        }

Application.OpenURL( );

↓打开浏览器并百度, 这个↓"http://"加不加都行

Application.OpenURL("http://www.baidu.com");

↓打开E盘

Application.OpenURL(@"file://E:\");

↓打开手机微信

Application.OpenURL("weixin://");

实现相机拍照的几种思路

鼠标点击, 射线检测
OnVisible(); 判断是否在视野中
Vector3.Diatance(); 判断距离
Vector3.Angle(); 判断角度
Physics.BoxCastAll(); 发一个方形射线, 在打到的数组里遍历查找

一个方法里打了2个断点, 结果第1个走了, 第2个竟然没走

你第2个断点打到 if 里去了, 而它走的 else

有个办法可以让你敲代码的速度提升2%

扣掉键盘上的"Caps Lock"和"Insert"键

struct是值类型

由于是存在栈中, 所以比class快
小玩意用struct, 比如Vector3就是struct

static 和 const

都是用来存全局变量/常亮
static可永久占内存, 可改
不可改的数据用const来存

继承mono

只有继承mono, 才能往场景里面挂;
继承mono, 就不能用构造函数了;
为了性能, 能不继承就不继承mono;
继承mono的类, 类名class和脚本名.cs必须相同, 不继承的类就无所谓了, 可以不一样;
什么时候需要继承: 需要用到Awake Update OnEnable OnTriggerEnter等时;

录制包含子物体的动画

如果想录的动画包括子物体的移动选择等, 要确保这个子物体身上没有Animator

正则

把所有 “不是数字的字符” 都换成 “.”

string str = "1,2,的撒发三份122,提问2,4,为前提";
string result = Regex.Replace(str, @"[^0-9]+",".");
print(result);
//输出1.2.122.2.4

我竟然不知道这些方法???

transform.SetPositionAndRotation(Vector3, Quaternion);
dotween.SetDelay(float);
transform.GetChild(string);
Undo.RecordObject(object, string);//Editor
list.IndexOf(T item)
Quaternion.Euler(Vector3);//传一个欧拉角进去
Physics2D.queriesStartInColliders = false;//2D射线不检测自身
//还有, 2D射线不需要Ray
dotween.SetUpdate(true);//使DOTween不受TimeScale的影响
dotween.OnUpdate( ()=>DoSomething() );//tween过程中每帧执行DoSomething();
CustomYieldInstruction //继承此类能实现自定义的yield
list.TrueForAll(x => x < 10);//返回bool

类型转化

↓类型一致的转化, 比如数值 float, int, double, enum等

float f = 1.2f;
int i = (int)f;//截取整数部分

↓类型不同的转化, 得用方法

string s = f.ToString();
Convert.ToInt32(s);//基本上都能转
int.Parse(s);//只能转换string

int ÷ int = float

//↓这样, 把其中一个数字转成float就行
1/2f
(float)1 /2

//↓没必要这样, 2个数字都转
1f/2f
(float)1 / (float)2

而1.0是double

Array.ConvertAll, 数组批量操作

有什么用呢? 能省一个for, 简洁又实用

↓string[]转化为int[]
甚至忽略了" 2 "中的空格, 正确输出123

string[] stringsArray = {
      "1", "   2", "3" };
int [] intsArray = Array.ConvertAll(stringsArray, int.Parse);
for (int i = 0; i < intsArray.Length; i++)
{
     
	Debug.LogError(intsArray[i]);
}

↓所有string, Trim();一下

options = Array.ConvertAll(options, p => p.Trim());

纹理图片勾选Generate Mip Maps

会有类似LOD的效果, 离远了就看不到纹理了

不同宽度的Grid子物体

项目要求是ABCD(可能还有EF)答题选项, 动态加载
↓要是都是这样的题型就简单了

口 A.我是选项A
口 B.我是选项B
口 C.我是选项C
口 D.我是选项D

先制作宽度一行的Toggle预制体

口 A.我是选项A

再弄个ScrollView在Content上挂上ContentSizeFitter以适应ABCD(EF), 再挂上VerticalLayoutGroup均匀排布就行了

↓但是题型有这样的

口 A.我是选项A
口 B.我是选项B, 我就是要比别的选项长, 别的选项占一行, 我就是要占好几行,, 我就是特立独行, 我就是格外一个样, 你的VerticalLayoutGroup失效了,
你拿我怎么办, 我就是我是颜色不一样的烟火
口 C.我是选项C
口 D.我是选项D

众所周知, LayoutGroup的子物体挂上ContentSizeFitter是不生效的
所以权宜之计是将Toggle预制体宽度调宽

口 A.我是选项A


效果如下, 很不好看

口 A.我是选项A


口 B.我是选项B, 我就是要比别的选项长, 别的选项占一行, 我就是要占好几行,, 我就是特立独行, 我就是格外一个样, 你的VerticalLayoutGroup失效了,
你拿我怎么办, 我就是我是颜色不一样的烟火
口 C.我是选项C


口 D.我是选项D


其实可以把Toggle预制体挂在一个Text下, 然后把这个Text作为预制体, Text上挂ContentSizeFitter是不会失效的
这个Text呢, 就用来取代Toggle中Label, 但是Label不要删, 只把字删掉就好
要是删了的话, Toggle点文字部分"A.我是选项A"就无效了, 只有点它前面的小方框才有效

GetComponentsInChildren(True);

子物体必须是活着的, 不然get不到
除非
GetComponentsInChildren(true);
加上 (true)

JSON数组的最后一个元素后面

不 ! 加 ! 逗 ! 号 !

总是不小心点到场景的一棵树上, 点出一大长串的Hierarchy?

把这个脚本, 挂在场景的最高父物体上
不论是点到了窗子还是桌子, 选中的都是场景的最高父物体

using UnityEngine;
[SelectionBase]
public class IAmAncestor : MonoBehaviour
{
     

}

↑上面的方法不行, 用下面的方法才行↓
在这里插入图片描述
给所有不想点的东西(树啊房子啊)的layer设置成XXX
然后点开图中这个Layers
再点XXX后面的小锁
这样就再也点不到那些场景中的东西了

手性翻转(镜像)模型

改变模型的Scale X Y Z的其中一个为负数就行了

协程非正常停止

带有协程的脚本.enabled = false; 协程会照常运行
带有协程脚本的gameObject.SetActive(false); 协程全部停止,即使再激活, 协程也不会继续执行

C#方法传入多个参数

用params关键字

public void Speak(params int[] s)
{
     
    for (int i = 0; i < s.Length; i++)
    {
     
		persons[i].DoAnim("Speak");
	}
}
//用的时候:
Speak(0,1);
Speak(4,5,6,7,8,9);

判断空Action 及其简化

↓这样写, 如果你没传参数进来, 会报空

void DontCheckNull(Action action = null)
{
     
	action();
}

↓需要判断一下空

void DoCheckNull(Action action = null)
{
     
	if (action != null)
	{
     
		action();
	}
}

可以简化为↓ (C#6可以, C#4不行)

void DoCheckNull(Action action = null)
{
     
	action?.Invoke();
}

后来我发现几乎所有的能被判null的都能这样写, 数值型不能判空, 因为它在栈上, 怎么会空呢,
除非在声明的时候这样写

int? a = 0;

鼠标点在UI上还是3D物体上

if (Input.GetMouseButtonDown(0) && !EventSystem.current.IsPointerOverGameObject())
{
     
	//点在物体上了
}
else if(Input.GetMouseButtonDown(0) && EventSystem.current.IsPointerOverGameObject())
{
     
	//点在UI上了
}

给按钮添加一次性委托

需求:
一个提示弹窗,
它的固定点击事件是自身窗体消失,
还可能添加别的点击事件, 点击事件仅生效一次

开搞:
↓一开始我是这样写的, 但是这样有点傻, 不管有没有委托, 都全部移除, 再添加上消失事件和自定义的委托

public void ShowTip(string tipText, Action action = null)
{
     
    textTip.text = tipText;
    panelTip.SetActive(true);

    btnTip.onClick.RemoveAllListeners();
    btnTip.onClick.AddListener(() => panelTip.SetActive(false));
    if (action != null)
    {
     
        btnTip.onClick.AddListener(() =>
        {
     
            action();
        });
    }
}

↓改进了一下, 用了EventTrigger

public void ShowTip(string tipText, Action action = null)
{
     
    textTip.text = tipText;
    panelTip.SetActive(true);

    if (action != null)
    {
     
        MyEvent btn = MyEvent.Get(btnTip);
        btn.MyBtnClick += action;
        btn.MyBtnClick += ()=> {
      btn.MyBtnClick -= action; };
    }
}

↓其实可以更简单的

public void ShowTip(string tipText, Action action = null)
{
     
    textTip.text = tipText;
    panelTip.SetActive(true);

    MyEvent btn = MyEvent.Get(btnTip);
    btn.MyBtnClick = action;
}

物体在视野内

注意1 : 不仅在Game面板下可见会触发本方法, 在Scene中可见同样会触发本方法
注意2 : 即使你把Mash Fitter设置为None, 使之不可见, 仍会触发本方法

bool isVisiable;
private void OnBecameVisible()
{
     
    isVisiable = true;
}

相机穿模

  1. 调小相机的Near Clip Plane
  2. 如果是自己手里的枪穿模, 那就另开一个相机, 只看枪, 相机的Clear Flags改为Depth only

获取当前场景的名字

string sceneName = SceneManager.GetActiveScene().name;

生命周期

刚才犯了一个很傻逼的问题:
在Start里赋值, 在OnEnable里调用;
结果报空了;

生命周期啊生命周期, 先OnEnable再Start;

Canvas - Space Camera

实现拖拽功能, 让ret跟着鼠标走, 遇到的坑:

ret.position = Input.mousePosition;

↑这样不行, ret的移动幅度特别大.

ret.parent = mather;//mather是一个点,锚点在左下角
ret.localPosition = Input.mousePosition;

↑这样才行
960 540分辨率, 能完美运行, 但是…

当我改了屏幕的分辨率就不行了;
尽管我已经做了960 540的屏幕适配, 但是切换成1920 1080的时候,
鼠标在左下角, ret也在左下角, 没错, 但鼠标移动到屏幕中间时, ret已经跑到右上角去了;
我怀疑屏幕适配没有起作用, 或者只起了一半的作用;
解决方法:

ret.parent = mather;//mather是一个点,锚点在左下角
ret.localPosition = Input.mousePosition * (540f / Screen.height);

↑乘以(除以)屏幕的放大(缩小)比例, 就行了

映射

项目要求是15个模块, 不同的场景, 不同的人物, 不同的事件, 相同点都是对话和播动画形式的. 我的思路是做3个类

1.Data类存数据;
2.SceneModel存放场景里的人物和物品和基本方法(场景人物虽然不同, 在脚本中是用相同的名字, 统统叫做Person0, Person1等);
3.SceneControl主控制器, 控制事件流程; 然后分15个子类

15个子类, 分别是Scene0Control, Scene1Control, Scene2Control…Scene14Control; 然后用映射方法, 通过不同的类名, 挂到不同的场景中

public int State = 0;
SceneControl sceneControl = gameObject.AddComponent<SceneControl>();
string ctrlClassName = "Scene" + State.ToString() + "Control";
sceneControl = Activator.CreateInstance(Type.GetType(ctrlClassName)) as SceneControl;

呃, 失败了…还是手动 if else 吧
有空再研究…


我研究回来了
因为脚本是挂在物体上的, 不需要用Activator.CreateInstance, 只要拿到Type就行了

public static ProcessMgr CreateByName(string module)
{
     
	Type type = Type.GetType("ProcessMgr" + module, true);
    return new GameObject("ProcessMgr").AddComponent(type) as ProcessMgr;
}

Editor文件夹

不需要打包的脚本放入名字是Editor的文件夹下, Editor文件夹放哪都行, 有很多叫做Editor的文件夹也行

foreach

只能读, 不能改, 而且会产生垃圾, (理论上应该尽可能的少用)

Unity的输入框打不了字

有可能是它不能输入全角字符
也有可能是发布的WebGL版, 是打不了中文的
还有WebGL版要把字体全部改为中文字体, 不然字体不显示

Text我不想换行但它自己换行了

因为你打半角空格的时候, Unity以为你打的是英语, 为了不让单词切开, 它就自动换行了;
改成全角空格就好了;

OnMouseEnter被挡住

项目需求是"光线"照射到"物体A"的时候, “物体A"显示出来, 然后再对"物体A"进行操作;
所以我用了OnTriggerEnter和OnTriggerExit;
以上都正常, 到了我在物体A上用OnMouseEnter的时候, 方法没有用, 因为"物体A"被"光线"遮住了;
解决方法, 把"光线"的Layer改成"IngoneRayCast”;

字符串比较(忽略大小写)

s1.Equals(s2, StringComparison.OrdinalIgnoreCase)

单例

不要在一个单例的Awake里使用另一个单例.
比如:
在A单例的Awake中使用B单例. 但是B单例还没执行Awake呢, 也就是说B是null, 报空;
解决方法:

  1. B在Awake时初始化. 然后在A单例的Start里使用B.instance;
  2. 单例管理, 排序一个一个地Awake;
  3. 不滥用单例

在for里AddListener

for (int i = 0; i < 10; i++)
{
     
	btns[i].onClick.AddListener(() => 
	{
     
		print(i);
	});
}

↑这样btns里的每个btn打印出来都是"10";

for (int i = 0; i < 10; i++)
{
     
	int temp = i;
	btns[i].onClick.AddListener(() => 
	{
     
		print(temp);
	});
}

↑这样打印出来才是想要的0,1,2,3,4,5,6,7,8,9

VS的中文string输出成乱码���

工具 > 自定义 > 命令 > 添加命令 > 文件 > 高级保存选项;
记录Unity遇到的坑_第1张图片
然后关闭, 再点击高级保存选项, 把编码改成UTF-8(无签名)
记录Unity遇到的坑_第2张图片

txt中用的空格

不间断空格\u00A0 让一个单词在结尾处不会换行显示
半角空格(英文符号)\u0020
全角空格(中文符号)\u3000

打包WebGL不能播放.mp3

不知道为什么, 有的mp3能播, 有的mp3不能播, 可能是mp3的问题(怀疑是假mp3格式)
方法就是转换成wav格式
正确方法是要在Unity里调mp3的WebGl设置

CameraSpaceUI

记得给物体用特定的layer
相机只看这个layer, 别的不看

录音

audioClip = Microphone.Start(null, false, RECORD_TIME, RECORD_RATE);

RECORD_TIME: 录音时长
RECORD_RATE: 录音的采样率, 填8000 - 44100

常用string方法

//取前 i个字符
str.Substring(0, i);
str.Remove(i, str.Length - i);
//去除空格
str.Replace(" ", "");
//去除空格和类似空格的东西
str.Trim();
//去除回车
str.Replace("\r", "");

↓正则表达式↓ 不用记忆这些东西, 肯定忘, 用的时候再看就行
https://www.runoob.com/csharp/csharp-regular-expressions.html

加特性[]

[RequireComponent(typeof (AudioSource))]

↑给本物体添加AudioSource组件, 省的你忘了挂上

[Obsolete("已弃用, 请使用NewMethod")]

↑提示已过时, 方法依然可以用

[Obsolete("已弃用, 请使用NewMethod", true)]

↑true表示不可用, 方法不能用了

[Conditional("IsTest")]

↑这样一来这个方法就不跑了, 除非在最上面(using XXX上面)写上:
#define IsTest;
这个方法就能跑了

[DisallowMultipleComponent]

↑只能挂一个本脚本, 不允许挂多个

[AddComponentMenu("Test")]

↑会出现在Component->Test

Unity打包路径里面不要有中文!

否则报错

时间格式

正确格式: yyyy-MM-dd HH-mm-ss-ffff

System.DateTime.Now.ToString("yyyy-MM-ddHH-mm-ss-ffff");

Y按星期算年, 会不准, 原因我忘了
M是月, m是分钟, 这个没有大小写的转换
d是当月的天数(2月1日), D是一年中的天数(32天)
H是24小时制, h是12小时制
s是秒, S是毫秒

另外的还有w之类的, 和星期相关的, 对咱们用处不大, 估计对老外有用, 因为老外过节经常: XX节是X月的第X个星期X

导入的FBX人物动画脚部乱动

因为unity给你把动画压缩了
解决方法:Animation:Anim.Compression改成off (不压缩动画)
或者下面3个error改小

所有的UI按钮失灵

不要慌, 可能只是因为你的场景里没有EventSystem.
遇到好几次了, 我怎么就记不住呢?
还有别的可能:
1.被另一个透明panel覆盖住了
2.你Canvas上没挂Graphic Raycaster(毕竟Unity的UI本来就用的是射线检测)
3.你用射线检测写的按钮按下, 但按钮上没挂Collider
4.你用的Space World模式的Canvas, 摄像机的Tag层不是Main Camera

更换UI的图片

Sprite sp = Resources.Load("Die",typeof (Sprite)) as Sprite;
img.sprite=sp;

图片的载入一定要加上typeof (Sprite), 不然没有用

OnDisable()

不要像下面这样, 在OnDisable()中给子物体换爸爸, 会报错

private void OnDisable()
    {
     
        for (int i = 0; i < transform.childCount; i++)
        {
     
            transform.GetChild(i).SetParent(null);
        }
    }

拿到一个UGUI的Height 或者Width

这样是没用的:

float x = joy.localScale.x;

这样才行:(仅锚点不分开的时候)

RectTransform rtf = joy.GetComponent<RectTransform>();
float x = rtf.sizeDelta.x;

这样也行:(锚点分开也行)

float x = rtf.rect.width;
float y = rtf.rect.height;

设置UI的宽:

rtf.SetSizeWithCurrentAnchor(RectTransform.Axis.Horizontal,100);

得到中心点:

Vector2 pivot = rtf.pivot;

UI中用到的富文本

要勾选Text组件的"Rich Text"选项:

//将"奥特曼"粗体显示
我是<b>奥特曼</b>
//斜体
我是<i>奥特曼</i>
//字体大小
我是<size=14>奥特曼</size>
//字体颜色
我是<color=red>奥特曼</color>

DOTween的坑

tw.PlayBackwards(); 并不会触发tw.OnComplete();

UI.DOMove()
项目需求: 窗口和全屏能够切换:
常用的移动到new Vector3(1,1,1)就不行了, 因为屏幕变了Vector3(1,1,1)的值也是变的(窗口自适应);
移动到Scene.height+UI自身长度也不行, 因为屏幕一变, 自身长度也是变的;
所以我放了一些点在UI里, 直接移动到点的坐标, 这里的坑是, 点的pivot一定和被移动的UI的pivot一致才行, 锚点定位是没关系的, 上下左右定哪都行, 但pivot一定要一毛一样;

比较2个List

内容一样, 顺序也一样:

using System.Linq;
if(list1.SequenceEqual(list2))

内容一样, 顺序可以不一样:

using System.Linq;
if(list1.Count == list2.Count && list1.Count(t => !list2.Contains(t)) == 0)

Unity读取.txt文件

.txt文件要另存为utf-8格式;

// 将txt中的内容加载进TextAsset中
TextAsset txt = Resources.Load("txt") as TextAsset;
// 以换行符作为分割点,保存数组, 最后记得Trim()一下, 去掉多余的空格换行符什么的
string[] strs = txt.text.Split('\n').Trim();

枚举

//正确的枚举是这样是
public enum Character
{
     
    A,
    B,
    C,
}
//而不是下面这样, 我傻了, 因为枚举本身就是个类, 不同的是他是值类型, 而类是引用类型
public class CharacterEnum 
{
     
    public enum Character
    {
     
      A,
      B,
      C,
    }
}

异步加载

IEnumerator LoadAsyncScene(string sceneName)
{
     
	AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName);
    //只要没加载完, 就一直返回空
    while (!asyncLoad.isDone)
    {
     
    	yield return null;
    }
    //加载完了
    DoSomething();
}

↓你还可以把下面这个玩意↓设为false, 等你的进度条加完了, 再设为true;

asyncLoad.allowSceneActivation;

↓带进度条的异步加载↓以及适配WebGL
https://blog.csdn.net/weixin_43994445/article/details/106231953

有几个插件找不到?

Cinemachine, ADS等Unity内置插件在商店是找不到的, 他们在这:
Windows → Package Manager

TimeLine在:
Windows → Sequencing

2018里好像没有
也可能是下架了, 没了
也可能是暂时下架了, 过几天就有了

你可能感兴趣的:(Unity,UGUI)