基础:
1.多个摄像机叠加渲染
深度都要不一样 深度高的要设置渲染层级
2.向量的点乘和叉乘
一些函数
Debug.DrawRay()
Vector3.Dot()
Vector3.Angle()
Mathf.Acos() * Mathf.Rad2Deg
Vector3.Cross()
//画一条射线 参数: 空间位置 方向 颜色
Debug.DrawRay(this.transform.position, this.transform.forward, Color.red);
Debug.DrawRay(this.transform.position, tarttransform.position - this.transform.position, Color.red);
//计算两个向量的点积 参数 :两个向量
float dotres = Vector3.Dot(this.transform.forward, tarttransform.position - this.transform.position);
if (dotres > 0)
{
print("它在我前方");
}
else
{
print("它在我后方");
}
// 单位化向量
float dotres2 = Vector3.Dot(this.transform.forward, (tarttransform.position - this.transform.position).normalized);
//得到角度
print("角度:" + Mathf.Acos(dotres2) * Mathf.Rad2Deg);
//也可以直接使用V3的Angle
print("角度2:" + Vector3.Angle(this.transform.forward, tarttransform.position - this.transform.position));
//两个向量的叉乘 几何意义;得到一条向量垂直于A 也垂直B 是AB平面的法向量
Vector3 c=Vector3.Cross(TransA.position, TransB.position);
//记忆
if (c.y > 0)
{
print("B在A的右边");
}
else
{
print("B在A的左边");
}
四元数
四元数是unity的一个结构体,
初始化四元数:
公式初始化:
轴角对的形式初始化:
四元数相乘:角度叠加
四元数乘以向量:向量旋转
3.面板不显示,考虑Alpha的问题 为0不显示
4.一个类继承了另一个类 里面的方法不使用就删了 不然会覆盖基类的方法,使得原本基类的方法失效(尤其是Start和Update)
5.JSON存储数据时,报错显示空引用,检查数据类是否继承了其他类,比如(MonoBehaviour类)。
6.PlayerPrefs用法 忘了
PlayerPrefs.SetInt(一个字符串,一个值);
就是把值存在一个字符串里面 后面Get的时候存在这个字符串就能找到
7.C#中的Base
base可以完成创建派生类实例时调用其基类构造函数
或者调用基类上已被其他方法重写的方法。
8.里氏转换 访问问题
Data=data;
Data不能直接点出data的元素 要as成data才能正常点出
9.初始化List
步骤没错思路没错的情况下一些其他的问题报错或报空,回头检查下List声明的时候有没有初始化
10.unity的线程和协程
unity是支持多线程的
线程:线程就像独立运行的管道,副线程不能访问unity中的对象,一般在里面执行一些复杂的逻辑处理如A*算法,收发网络消息等。把一些信息返回到一个公共区里,这样主线程就能够去访问副线程处理后的一些信息。
协程:在主线路中执行的一个协程函数,我们可以分时分步(就是执行第一部分后遇到 yiled return的时候就不继续往下执行了,根据return的内容决定什么时候执行下一部分,此时协程函数的其他未执行的部分就处于挂起状态,执行主线程,主线程就是个死循环,等到了再次执行协程函数的时候就会去判断是否满足条件,往下执行。)的执行这个协程函数,不卡住主线程。
11.协程的原理
协程其实就是两个部分:协程本体(MoveNext() 返回一个bool值表示下面是否还有东西能执行、Current 得到当前的返回对象) 本质上就是一个C#迭代器的函数,通过这个迭代器函数实现分布执行和协程调度器实现了分时执行(Unity有一套分时执行的规则)。
案例:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Yield
{
public IEnumerator ie;
public float time;
}
public class twofor : MonoBehaviour
{
public static List<Yield> yieldsList = new List<Yield>();
// Start is called before the first frame update
void Start()
{
}
public static void HandleIE(IEnumerator ie)
{
//List存储协程的time
if (ie.MoveNext())
{
if (ie.Current is int)
{
Yield y = new Yield();
y.ie = ie;
y.time = Time.time + (int)ie.Current;
yieldsList.Add(y);
}
}
}
// Update is called once per frame
void Update()
{
for (int i = yieldsList.Count - 1; i >= 0; i--)
{
if (yieldsList[i].time <= Time.time)
{
//执行保存的ie接口
if (yieldsList[i].ie.MoveNext())
{
if (yieldsList[i].ie.Current is int)
{
yieldsList[i].time = Time.time + (int)yieldsList[i].ie.Current;
}
else
{
yieldsList.RemoveAt(i);
}
}
else
{
yieldsList.RemoveAt(i);
}
}
}
}
}
核心:
1.反向动力学IK(子骨骼影响父骨骼)
在对象的每个部位的最后一个节点创建一个空对象,移动到最低点,在整个父物体对象添加组件
三种IK方式
适用于做瞄准,拾取物品,相应的动画
2.换装
1.同一文件目录下
创建好对象的骨骼和相应的蒙皮之后在相应的要换装的部位上关联Sprite Resolver组件即可可视化换装
2.在不同文件目录下
创建好不同对象的骨骼和相应的蒙皮。
创建数据文件SpriteLibraryAsset,添加相应的换装目录
然后
3动画分层(实现开枪效果)
创建一个空的动画状态做中间件,设置开枪动画执行完之后返回,空动画到开枪动画直接传递。(这里是用触发器Trigger实现)
4.动画目标匹配(实现跳跃上箱子之类的)
动画状态机的函数 MatchTarget
参数依次是 目标位置 目标旋转 匹配的骨骼 位置和旋转的权重 动画开始 动画结束
animator.MatchTarget(trf.position, trf.rotation, AvatarTarget.LeftHand,
new MatchTargetWeightMask(Vector3.one, 1), 0.45f, 0.64f);
注意:1.要把模型的属性打开
2.保证动画已经切换到了目标动画上(因为动画基本都是联系的,在调用的这一时刻可能在执行别的动画或者处于过渡阶段,可以在目标动画的开始时间之后添加事件来解决)
5.角色控制器
坡度 台阶距
注意:使用时最好取消模型自带的移动属性,即仅通过角色控制器控制移动
void Update()
{
//ad控制左右移动
animator.SetInteger("Speed", (int)Input.GetAxisRaw("Horizontal"));
if(cc.isGrounded)
{
print("接触地面");
}
//受重力作用移动 Move不受重力
cc.SimpleMove(this.transform.forward * 380 * Time.deltaTime* Input.GetAxisRaw("Horizontal"));
}
//检测碰撞体
private void OnControllerColliderHit(ControllerColliderHit hit)
{
print(hit.collider.name);
}
}
6.Camera.main.ScreenPointToRay(v3)
Unity 之 ScreenPointToRay() (将点转换成射线的方法)-CSDN博客
7.Quaternion.AngleAxis
.
8.飞机按WD旋转
设置一个目标四元数,Slerp方法
9.打包图集(Sprite Atlas)
打包不了图集?
两个设置
包管理器里面的2D Sprite下载了
设置里面的图集按钮打开
打包图集用来优化性能,降低DrawCall(Unity DrawCall详解_unity drawcall-CSDN博客)。
注意:如果图集元素中间出现了不属于图集的元素,则DC会增加,具体看元素数量,中间不属于的会切断原来的图集批次
10.边界碰撞器和复合碰撞器
11.等距瓦片地形排序
要设置两个地方
设置Unity的默认图层排序 修改TileRenderer的渲染模式为Individual