unity基础学习笔记<下>
画线功能
1.LineRenderer是什么
LineRenderer是Unity提供的一个用于画线的组件,使用它我们可以在场景中绘制线段
一般可以用于 1绘制攻击范围 2武器红外线 3辅助功能 4其它画线功能
2.LineRender代码相关
//动态添加一个线段
GameObject line = new GameObject();
line.name = “Line”;
LineRenderer lineRenderer = line.AddComponent();
//首尾相连
lineRenderer.loop = true;
//开始结束宽
lineRenderer.startWidth = 0.02f;
lineRenderer.endWidth = 0.02f;
//开始结束颜色
lineRenderer.startColor = Color.white;
lineRenderer.endColor = Color.red;
//设置材质
m = Resources.Load(“M”);
lineRenderer.material = m;
//设置点
//一定注意 设置点 要 先设置点的个数
lineRenderer.positionCount = 4;
//接着就设置 对应每个点的位置
lineRenderer.SetPositions(new Vector3[] { new Vector3(0,0,0),
new Vector3(0,0,5),
new Vector3(5,0,5)});
lineRenderer.SetPosition(3, new Vector3(5, 0, 0));
//是否使用世界坐标系
//决定了 是否随对象移动而移动
lineRenderer.useWorldSpace = false;
//让线段受光影响 会接受光数据 进行着色器计算
lineRenderer.generateLightingData = true;
物理系统:
一.什么是范围检测:游戏中瞬时的攻击范围判断一般会使用范围检测
在指定位置 进行 范围判断 我们可以得到处于指定范围内的 对象。目的是对 对象进行处理。比如 受伤 减血等等
二.如何进行范围检测
必备条件:想要被范围检测到的对象 必须具备碰撞器
注意点:1.范围检测相关API 只有当执行该句代码时 进行一次范围检测 它是瞬时的
2.范围检测相关API 并不会真正产生一个碰撞器 只是碰撞判断计算而已
三.范围检测API
1.盒状范围检测
参数一:立方体中心点。参数二:立方体三边大小。参数三:立方体角度。参数四:检测指定层级(不填检测所有层)。参数五:是否忽略触发器 UseGlobal-使用全局设置 Collide-检测触发器 Ignore-忽略触发器 不填使用UseGlobal。返回值:在该范围内的触发器(得到了对象触发器就可以得到对象的所有信息)
print(LayerMask.NameToLayer(“UI”));
Collider[] colliders = Physics.OverlapBox( Vector3.zero, Vector3.one, Quaternion.AngleAxis(45, Vector3.up),
1 << LayerMask.NameToLayer(“UI”) |
1 << LayerMask.NameToLayer(“Default”), QueryTriggerInteraction.UseGlobal);
关于层级
通过名字得到层级编号 LayerMask.NameToLayer。我们需要通过编号左移构建二进制数。这样每一个编号的层级 都是 对应位为1的2进制数。我们通过 位运算 可以选择想要检测层级。好处:一个int 就可以表示所有想要检测的层级信息
2.球形范围检测
参数一:中心点,参数二:球半径,参数三:检测指定层级(不填检测所有层)。参数四:是否忽略触发器 UseGlobal-使用全局设置 Collide-检测触发器 Ignore-忽略触发器 不填使用UseGlobal。返回值:在该范围内的触发器(得到了对象触发器就可以得到对象的所有信息)
colliders = Physics.OverlapSphere(Vector3.zero, 5, 1 << LayerMask.NameToLayer(“Default”));
3.胶囊范围检测
参数一:半圆一中心点,参数二:半圆二中心点,参数三:半圆半径,参数四:检测指定层级(不填检测所有层),参数五:是否忽略触发器 UseGlobal-使用全局设置 Collide-检测触发器 Ignore-忽略触发器 不填使用UseGlobal,返回值:在该范围内的触发器(得到了对象触发器就可以得到对象的所有信息)
colliders = Physics.OverlapCapsule(Vector3.zero, Vector3.up, 1, 1 << LayerMask.NameToLayer(“UI”), QueryTriggerInteraction.UseGlobal);
射线检测
什么是射线检测
物理系统中目前我们学习的物体相交判断
1.碰撞检测—1刚体2碰撞器.。2.范围检测—碰撞器
如果想要做这样的碰撞检测呢?
1.鼠标选择场景上一物体。2.FPS射击游戏(无弹道-不产生实际的子弹对象进行移动)。等等 需要判断一条线和物体的碰撞情况。
总而言之:射线检测 就是来解决这些问题的。它可以在指定点发射一个指定方向的射线。判断该射线与哪些碰撞器相交,得到对应对象就是射线对象
1.3D世界中的射线
假设有一条起点为坐标(1,0,0)方向为世界坐标Z轴正方向的射线
注意:理解参数含义参数一:起点。参数二:方向(一定记住 不是两点决定射线方向,第二个参数 直接就代表方向向量)
目前只是申明了一个射线对象 对于我们来说 没有任何的用处
Ray r = new Ray(Vector3.right, Vector3.forward);
Ray中的参数
print(r.origin);//起点
print(r.direction);//方向
2.摄像机发射出的射线
得到一条从屏幕位置作为起点。摄像机视口方向为 方向的射线
Ray r2 = Camera.main.ScreenPointToRay(Input.mousePosition);
注意:单独的射线对于我们来说没有实际的意义。我们需要用它结合物理系统进行射线碰撞判断
碰撞检测函数
Physics类中提供了很多进行射线检测的静态函数
他们有很多种重载类型 我们只需要掌握核心的几个函数 其它函数自然就明白什么意思了
注意:射线检测也是瞬时的,执行代码时进行一次射线检测。
1.最原始的射线检测
准备一条射线
Ray r3 = new Ray(Vector3.zero, Vector3.forward);
进行射线检测 如果碰撞到对象 返回true。参数一:射线。参数二: 检测的最大距离 超出这个距离不检测。参数三:检测指定层级(不填检测所有层)。参数四:是否忽略触发器 UseGlobal-使用全局设置 Collide-检测触发器 Ignore-忽略触发器 不填使用UseGlobal。返回值:bool 当碰撞到对象时 返回 true 没有 返回false
if (Physics.Raycast(r3, 1000, 1 << LayerMask.NameToLayer(“Monster”), QueryTriggerInteraction.UseGlobal))
{print(“碰撞到了对象”);}
2.获取相交的单个物体信息
物体信息类 RaycastHit
RaycastHit hitInfo;
参数一:射线参数二:RaycastHit是结构体 是值类型 Unity会通过out 关键在 在函数内部处理后 得到碰撞数据后返回到该参数中。参数三:距离。参数四:检测指定层级(不填检测所有层)。参数五:是否忽略触发器 UseGlobal-使用全局设置 Collide-检测触发器 Ignore-忽略触发器 不填使用UseGlobal
if( Physics.Raycast(r3, out hitInfo, 1000, 1<<LayerMask.NameToLayer(“Monster”), QueryTriggerInteraction.UseGlobal) )
{print(“碰撞到了物体 得到了信息”);
碰撞器信息print(“碰撞到物体的名字” + hitInfo.collider.gameObject.name);
碰撞到的点print(hitInfo.point);
法线信息print(hitInfo.normal);
得到碰撞到对象的位置print(hitInfo.transform.position);
得到碰撞到对象 离自己的距离print(hitInfo.distance);
RaycastHit 该类 对于我们的意义它不仅可以得到我们碰撞到的对象信息还可以得到一些 碰撞的点 距离 法线等等的信息}
3.获取相交的多个物体
可以得到碰撞到的多个对象,如果没有 就是容量为0的数组
参数一:射线。参数二:距离。参数三:检测指定层级(不填检测所有层)。参数四:是否忽略触发器 UseGlobal-使用全局设置 Collide-检测触发器 Ignore-忽略触发器 不填使用UseGlobal
RaycastHit[] hits = Physics.RaycastAll(r3, 1000, 1 << LayerMask.NameToLayer(“Monster”), QueryTriggerInteraction.UseGlobal);
for (int i = 0; i < hits.Length; i++)
{print(“碰到的所有物体 名字分别是” + hits[i].collider.gameObject.name);}