Mathf
//插值运算 - Lerp
//Lerp函数公式
//result = Mathf.Lerp(start, end, t);
//t为插值系数,取值范围为 0~1
//result = start + (end - start)*t
//插值运算用法一
//每帧改变start的值——变化速度先快后慢,位置无限接近,但是不会得到end位置
start = Mathf.Lerp(start, 10, Time.deltaTime);
//插值运算用法二
//每帧改变t的值——变化速度匀速,位置每帧接近,当t>=1时,得到结果
time += Time.deltaTime;
result = Mathf.Lerp(start, 10, time);
向量
成员属性: magnitude 模长
normalized 单位向量
向量的点乘可以用来判断物体的方位
点乘函数Vector3.Dot()
两物体之间夹角为 Mathf.Acos(Vector3.Dot(A.transform.forward.normalized,(B.transform.position – A.transform.position).normalized))
或者 Vector3.Angle(A.transform.forward, B.transform.position – A.transform.position)
叉乘使用的是左手定则,与常见的判断方式相反
向量的叉乘用于得到平面的法向量,以此判断物体的方位
叉乘函数Vector3.Cross()
如果Cross(A.transform.forward, B.transform.position – A.transform.position).y > 0,则B在A右边,反之在左边
向量插值
线性插值Vector3.Lerp(stPos,endPos,Time.deltime)
球形插值Vector3.Slerp(),区别在于这是一个球形的轨迹
四元数Quaternion
为什么要四元数
欧拉角存在缺点:
1.旋转角度不唯一
2.存在万向节死锁
知识点一 四元数 Quaternion
//四元数Q = [cos(β/2), sin(β/2)x, sin(β/2)y, sin(β/2)z]
//计算原理
//Quaternion q = new Quaternion(Mathf.Sin(30 * Mathf.Deg2Rad), 0, 0, Mathf.Cos(30 * Mathf.Deg2Rad));
//提供的轴角对 初始化 四元数的方法
Quaternion q = Quaternion.AngleAxis(60, Vector3.right);
// 返回沿某轴旋转一定度数之后的单位向量
//创建一个立方体
GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Cube);
obj.transform.rotation = q;
知识点二 四元数和欧拉角转换
//1.欧拉角转四元数
Quaternion q2 = Quaternion.Euler(60, 0, 0);
GameObject obj2 = GameObject.CreatePrimitive(PrimitiveType.Cube);
obj2.transform.rotation = q2;
//2.四元数转欧拉角
print(q2.eulerAngles);
知识点三 四元数弥补的欧拉角缺点
//1.同一旋转的表示不唯一 四元数旋转后 转换后的欧拉角 始终是 -180~180度
//2.万向节死锁 通过四元数旋转对象可以避免万向节死锁
必备知识点 四元数相乘代表旋转四元数 this.transform.rotation *= Quaternion.AngleAxis(1, Vector3.up);
四元数也可以乘以向量,返回值为向量,相当于对向量的旋转
协同程序
多线程
Thread t = new Thread(Func);
t.start();
关闭线程
t.Abort();
t = null;
协程和多线程的区别
新开一个线程是独立的一个管道,和主线程并行执行 新开一个协程是在原线程之上开启,进行逻辑分时分步执行
1.Unity支持多线程,只不过新开的线程中无法访问Unity相关的内容
一般主要用于复杂的逻辑计算或者网络消息的接受等
Tip:Unity中的多线程一定要记住关闭
2.协同程序不是多线程,是将线程中的逻辑分时执行,避免卡顿
3.继承MonoBehavior的类都可以使用协程
4.协程开启
IEnumerator ie = MyCoroutine(1, “123”); Coroutine c1 = StartCoroutine(ie); // 用变量接收协程,方便指定关闭
IEnumerator MyCoroutine(int i,string s) { print(i); // yield break; 使用此语句 后面的操作不会执行 yield return new WaitForSeconds(1.0f); print(s); }
yield return 不同内容的含义
1.下一帧执行 yield return 数字; yield return null; 在Update和LateUpdate之间执行
2.等待指定秒后执行 yield return new WaitForSeconds(秒); 在Update和LateUpdate之间执行
3.等待下一个固定物理帧更新时执行 yield return new WaitForFixedUpdate(); 在FixedUpdate和碰撞检测相关函数之后执行
4.等待摄像机和GUI渲染完成后执行 yield return new WaitForEndOfFrame(); 在LateUpdate之后的渲染相关处理完毕后之后,主要用来截图使用
5.一些特殊类型的对象 比如异步加载相关函数返回的对象 之后讲解 异步加载资源 异步加载场景 网络加载时再讲解 一般在Update和LateUpdate之间执行
6.跳出协程 yield break;
协程关闭
StopAllCoroutines(); StopCoroutine(c1);
协程开启后 组件和物体销毁,协程不执行 物体失活协程不执行,组件失活协程执行
Resources资源动态加载
同步加载
Resources文件夹可以有多个,可以不在Assets文件夹下
用法 :Resources.Load(“object_name”),返回对象为Object,如果使用LoadAll则为Object数组
常用方法为泛型 :Resources.Load<T>(“object_name”),此时返回的对象为T,不需要手动转换
Unity提供得Text类为TextAsset
文件夹中允许存在不同类型的同名文件,在Load的时候传入第二参数Type确定具体文件
异步加载
Resources.LoadAsync<T>(“object_name”)
返回的值为ResourceRequest
rq.completed为参数AsyncOperation的一个事件,需要往该事件里添加操作,表示异步加载完成后要执行的操作,可以把AsyncOperation强转为ResourceRequest再调用asset表示希望得到的对象
T obj = (a as ResourceRequest).asset as T
。当然也可以不在这个事件里得到asset,在外部直接调用,前提是需要判空,因为是异步加载
if(rq != null)
T obj = rq.asset as T
手动卸载缓冲区资源
Resoureces.UnloadAsset(obj) // 卸载指定资源
Resources.UnloadUnusedAssets() // 卸载未使用的资源
通常搭配GC垃圾回收一起使用,GC.Collect()
场景异步加载
SceneManager.LoadSceneAsync(name); // 返回值为AsyncOperation,可以往该事件里加入函数
还可以通过协程配合异步加载场景,这样不仅可以添加结束后的操作,还可以添加加载时的操作,需要注意的时,在删除原本场景的gameObject时不能删除挂载此脚本的物体,这样无法执行结束后的操作,可以通过
DontDestroyOnLoad(this.gameObject)来防止该物体在切换场景时被销毁
LineRendered
常用API:
startWidth,endWidth
pointCount
SetPosition(index,pos) // 必须先设置pointCount才能设置这个
范围检测
Physics.OverlapBox()
Physics.OverlapCapsule()
Physics.OverlapSphere()
返回值都为collider[]
射线检测
创建射线对象:
Ray r = new Ray(position,direction)
Ray r = Camera.main.ScreenPointToRay(Input.mousePosition) // 从摄像机发出射线
执行射线检测:
只检测是否碰撞
Physicals.Raycast(r,maxDis,layer,QueryTriggerInteraction) // QueryTriggerInteraction省略默认为UseGlobal 返回值为bool
得到碰撞物体信息
RaycastHit hitInfo
Physicals.Raycast(r,out hitInfo,maxDis,layer,QueryTriggerInteraction) // 碰撞物体信息存储在hitInfo 返回值依旧是bool 为上面一个方法的重载
hitInfo.point // 碰撞到的点
hitInfo.normal // 碰撞到的法线
hitInfo.distance // 碰撞到的对象与自己的距离
需要得到碰撞多个物体的信息时
RaycastHit[] hits = Physicals.Raycast(r,maxDis,layer,QueryTriggerInteraction)
屏幕坐标相关
为Camera的内置方法
ScreenPoint坐标单位为分辨率
Viewport坐标单位归一化为[0,1]

评论(0)
暂无评论