2D渲染
Camera
相机设置
Projection
(投影方式):修改为Orthographic
(正交)
Size
:改变相机的视野大小
Sprite
“精灵图”一词首次作为图形术语出现,是在德州仪器的9918(A)视频显示处理器上。使用“精灵图”作为术语,是因为精灵图并不是帧缓冲中位图数据的一部分,而是“悬浮”于帧缓冲中数据之上,不影响其中数据,就像精灵飘在上面一样。
在Unity中:png / jpg等常规图片,一般不在Unity中直接使用,而是转为Sprite
SpriteRender
顾名思义,用来渲染Sprite的渲染器
属性 | 功能 |
---|---|
Sprite | 定义该组件应渲染的精灵纹理。单击右侧的小圆点可打开对象选择器窗口,然后从可用精灵资源列表中进行选择。 |
Color | 定义精灵的顶点颜色,用于对精灵的图像进行着色或重新着色。使用拾色器设置渲染的精灵纹理的顶点颜色。请参阅此表下方的颜色部分以查看示例。 |
Flip | 沿选定的轴翻转精灵纹理。这不会翻转游戏对象的变换位置。 |
Sorting Layer | 设置精灵的排序图层(Sorting Layer),此图层用于控制渲染期间的精灵优先级。从下拉框中选择现有的排序图层,或创建新的排序图层。 |
Order In Layer | 设置精灵在其排序图层中的渲染优先级。首先渲染编号较低的精灵,编号较高的精灵叠加在前者之上。 |
Sprite Sort Point | 在计算精灵和摄像机之间的距离时,在精灵中心(Center)或其轴心点(Pivot Point)之间进行选择。 |
Unity输入系统
这里调用的Input
类是由命名空间UnityEngine
提供的,如果有using Input = UnityEngine.Windows.Input;
的话将会导致这里的Input
不能直接调用
监听键盘输入
键盘输入有三种状态:
- 按下的瞬间
- 持续按下中
- 弹起的瞬间
下方三个函数返回都是bool类型,参数都是KeyCode枚举类型
Input.GetKeyDown(KeyCode.A);
Input.GetKey(KeyCode.A);
Input.GetKeyUp(KeyCode.A);
监听键盘输入
和键盘差不多,不过0是鼠标左键、1是鼠标右键、2是鼠标中键
Input.GetMouseButtonDown(0);
Input.GetMouseButton(0);
Input.GetMouseButtonUp(0);
Input Manager
Unity提供了一种常见且方便的使用方式:
大多数游戏中使用键盘A和D来控制玩家在水平方向上的移动,这里提供一个函数:
按下A,函数的返回值会偏向-1;按下D,函数的返回值会偏向1;如果不按A或D则偏向0(使用“偏向”是因为会缓动效果,例如按下A后,数值会慢慢减到-1,按下D后,数值会慢慢加到1,不按会慢慢回到0,可以模拟出启动、惯性的效果)
Input.GetAxis("Horizontal");
Input.GetAxisRaw("Horizontal");//不进行缓动,只有三种结果:-1,0,1
Horizontal
是水平方向轴(X轴),Vertical
是纵向方向轴(Y轴)
他们都在Unity界面中的Edit -> Project Settings -> Input Manager
中配置
Unity2D动画概览
Unity的2D动画和3D动画在操作层面上用的是同一个组件,操作方式也类似,但是相关知识点有所不同,所以不能武断地认为2D动画等于3D动画
Animator
:动画组件(组件)
用来持有AnimatorController
的组件,注意可以多个Aniamtor持有一份AnimatorController
AnimatorController
:动画控制器(文件)
动画控制器相当于是一个配置文件,配置的是一个角色有哪些动画,动画和动画之间如何跳转
状态:当前角色处于的状态,状态会持有具体的AnimationClip
条件:动画之间的切换基于什么条件
参数:条件基于参数来判断是否满足,满足则切换
int
、float
、bool
和代码中的类似Trigger
:触发一次,bool相当于是一种状态,但是Trigger是一个一次性使用的条件
AnimationClip
:动画片段(文件)
动画片段,就是动画文件,记录了每一帧的信息。Unity内可以制作动画,但是从其他建模类软件导入的情况也比较多(尤其是3D动画)
2D动画也分为帧动画和骨骼动画
-
帧动画就是通过切换图片形成动画
-
而骨骼是通过旋转、缩放、移动关节点进行变化的动画
动画切换
Unity动画组件本质上是引用了一个“动画状态机”(AnimationController
)的配置文件
- 状态:当前角色处于的状态,状态会持有具体的
AnimationClip
- 条件:参数在“发生何等变化”时会进行状态切换
Has Exit Time:即使条件满足也需要等待当前状态的播放完毕才能进行切换(后摇) - 参数:提供给脚本去访问、修改的“值”,这些值变化则状态变化,则动画发生改变
无视参数、条件的动画播放
CrossFadenInFixedTime
:此函数
//参数1:状态名称
//参数2:过度时间(秒)
animator.CrossFadenInFixedTime("Move", 0.25f);
角色移动动画
想要角色移动,就要搞定三个基本点:
- 角色待机与移动动画的切换
- 角色向不同方向移动时的贴图方向
- 角色实现物理位移
要解决第一个问题,就要在Animator
中选中两个动画直接的切换连线,添加判断变量(Parameters
)和合适的条件(Conditions
)(因为是角色移动所以这里设置的是bool变量和真假判断)
然后在脚本中获取Animator
组件并为变量Move
判断赋值
第二个问题直接在脚本中调用localScale
,并根据不同方向将X轴的数值置正数或负数即可实现
第三个问题前面有提
脚本如下:
public class TestAnimator : MonoBehaviour
{
// Start is called before the first frame update
public float moveSpace = 5;
public Animator animator;
void Start()
{
}
// Update is called once per frame
void Update()
{
float inputX = UnityEngine.Input.GetAxis("Horizontal");
float inputY = UnityEngine.Input.GetAxis("Vertical");
//动画切换
bool isMoving = (inputX!= 0 || inputY!= 0);
animator.SetBool("Move", isMoving);
//移动方向
if (inputX > 0) transform.localScale = new Vector3(10, 10, 1);
else if (inputX < 0) transform.localScale = new Vector3(-10, 10, 1);
//角色移动
Vector3 moveDirection = new Vector3(inputX, inputY, 0);
transform.Translate(moveDirection * moveSpace * Time.deltaTime);
}
}
动画事件
可以在动画中的某一帧插入一个事件来执行想要的效果(如落地时播放音效)
动画事件可以调用脚本中的函数或方法来执行效果
2D物理系统
碰撞体(Collider
)
决定物理单位作为物体碰撞时的形状,可以是矩形、圆形亦或是自定义的多边形
参数解释
Edit Collider
:编辑碰撞体大小Material
:物理材质,决定物体的碰撞特性Is Trigger
:是否为触发器Auto Tiling
:碰撞体大小自动贴合物理单位边框
刚体(Rigidbody 2D
)
物理单位的物理特性,也就是定义物理单位怎样受到物理的控制,如重力等
参数解释
-
Body Type
:
Dynamic
:动力学体。默认选项,受物理引擎影响,会主动响应重力、碰撞和其他外力。用于需要物理交互和自然运动的物体(玩家、敌人或可以被推动的物体)
Kinematic
:运动体。运动体不会主动受到外力的影响,但可以通过代码控制其位置和旋转。这意味着你可以手动设置其速度和方向,但它不会响应重力或碰撞力。运动体可以推动其他动力学刚体,但自身不会因碰撞而移动。
Static
:静态体。当设置为静态体时,物体不会受到物理力的影响,它不会移动或旋转,除非通过代码直接改变其位置或旋转。这通常用于不需要物理交互的物体,例如背景元素或固定结构。如果你想要一个物体能够自然地掉落并在碰撞时反弹,你会选择
Dynamic
。如果你想要一个物体保持固定位置,但仍然能够通过代码进行移动,你会选择Kinematic
。如果你完全不希望物体参与物理计算,你会选择Static
。 -
Material
:物理材质,决定物体的碰撞特性
Friction
:摩擦力
Bounciness
:弹力
-
Simulated
:模拟效果(编辑时展示模拟效果) -
Mass
:质量,影响着物体的惯性和加速度 -
Gravity Scale
:重力,影响重力加速度(0 = 无重力,1 = 标准重力,2 = 两倍标准重力) -
Linear Drag
:线性阻力,影响位置移动时的阻力参数 -
Angular Drag
:角阻力,影响旋转运动时的阻力参数 -
Collider Detection
:碰撞检测,用于确定物体是否互相碰撞的一个关键机制
Discrete
:离散,计算成本较低。在离散碰撞检测中,物理引擎会在固定的时间步长(通常是FixedUpdate
周期)检查物体的位置并确定他们是否发生碰撞。如果物体移动的速度过快将会穿越应该与之碰撞的物体,俗称“隧穿”。
Continuous
:连续,计算成本较高。连续碰撞检测适用于处理快速移动的物体,以免出现“隧穿”问题。在连续碰撞检测中,物理引擎会考虑物体在时间步长内的运动,并尝试找到第一个接触点。这种检测方式比离散碰撞检测消耗更多的CPU资源,因此通常只对那些需要它的物体使用。 -
constraints
:定义对 2D 刚体运动的任何限制。
Freeze Position
:选择性地阻止2D刚体沿世界X和Y轴移动。这不会阻止刚体的旋转,但会锁定其在特定轴上的平移运动 。
Freeze Rotation
:选择性地阻止2D刚体围绕Z轴旋转。刚体仍然可以自由移动,但旋转将被限制
事件
碰撞事件
当两个物理单位相撞时会调用的逻辑
前提条件:双方都有碰撞体,其中一个有刚体
//发生碰撞
private void OnCollisionEnter2D(Collision2D collision)
{
Debug.Log("发生碰撞");
if(cllision.gameObject.name == "S1")
{
Destory(gameObject);
}
}
//持续碰撞
private void OnCollisionStay(Collision collision)
{
Debug.Log("持续碰撞");
}
//结束碰撞
private void OnCollisionExit2D(Collision2D collision)
{
Debug.Log("结束碰撞");
}
触发事件
当两个物理单位其中一个碰撞体设置为触发器时调用的逻辑
前提条件:双方都有碰撞体,一方为触发器,另一方有刚体
//发生触发
private void OnTriggerEnter2D(Collider2D collision)
{
Debug.Log("发生触发");
}
//持续触发
private void OnTriggerStay2DStay(Collision collision)
{
Debug.Log("持续触发");
}
//结束触发
private void OnTriggerExit2D(Collision2D collision)
{
Debug.Log("结束触发");
}
碰撞事件与触发事件的区别
- 碰撞事件和触发事件不能同时发生
碰撞事件
:会导致物理力的计算和应用,例如动量转移和碰撞响应。触发事件
:不会导致物理力的计算,它们仅作为检测机制,用于检测物体是否进入或离开特定区域。碰撞事件
:因为涉及到物理计算,可能会对性能有更高的要求。触发事件
:通常用于优化,因为它们避免了物理力的计算,特别是在需要频繁检测物体是否穿过区域的场景中。碰撞事件
:适用于需要物理交互和响应的场景,如球撞击地面或车辆碰撞。触发事件
:适用于不需要物理力但需要检测物体进入特定区域的场景,如触发门的开关、检测玩家进入特定区域等。