导入新资产
切割新资产
切割完成
修改大小和清晰度
球体已经设置了刚体和碰撞体积,直接应用给人物,改名circle为player
中心点问题
因为切割的原因,碰撞模型的中心点和人物的中心点不相吻合
解决:在子路径下渲染人物图片,将二者的中心点手动对齐
手动对齐
保存更改
更改碰撞体模型
运行后角色会歪倒
更改下列选项
Collision Detection(碰撞检测)
Collision Detection用于确定游戏对象在物理场景中的碰撞情况。在Rigidbody 2D中,碰撞检测有两种主要模式:
Discrete(离散碰撞检测):默认碰撞检测模式,它在每个物理帧结束时检查碰撞。这种模式对于大多数情况都足够有效,但如果对象移动速度非常快或存在穿透现象,可能会导致碰撞检测的不准确。
Continuous(连续碰撞检测):当对象移动速度非常快时,离散碰撞检测可能无法准确捕捉到碰撞。此时,可以使用连续碰撞检测模式,它会持续监控对象的移动路径,以确保在移动过程中检测到所有碰撞。有助于防止对象以高速穿过其他对象,但会增加计算成本
Interpolate(插值)
Interpolate用于平滑刚体的运动,以减少由于物理计算中的离散性而产生的抖动现象。插值项有三个选项:
None(无):表示不平滑,运动正常时使用。
Interpolate(插值):表示根据刚体上一帧的运动来添加平滑效果。
Extrapolate(外推):表示根据预测刚体下一帧的运动来添加平滑效果。
通过选择合适的插值选项,可以显著改善刚体运动的平滑度和视觉效果。
Freeze Rotation(冻结旋转)
Freeze Rotation用于锁定刚体在特定轴上的旋转
让人物活起来
添加Animator和Animation窗口
在Unity中,Animator和Animation窗口是动画系统的核心组成部分,它们共同提供了强大的动画编辑和管理功能。
Animator窗口主要用于管理和控制动画状态机(Animation State Machine),它允许开发者创建、组织和切换不同的动画状态。
Animation窗口则用于创建和编辑单个动画片段(Animation Clip),它提供了丰富的工具来定义游戏对象在不同时间点的属性变化。
创建播放器的动画控制器player animator controller
把player_ac添加到子路径Animator下
创建Animation,静止动画playeridle,注意要选中player的子路径Animator
shift + 鼠标 选中图片拖拽到Animation窗口(松开键盘托,不然拖不进去)
速度太快,修改采样率
点击播放,小人活了!
创建移动动画
创建新的播放器
同理重复playeridle的步骤
将移动动画和静止动画联系起来
进入Animator窗口
添加动画转换条件(参数)IsMoving
编辑代码
anim = GetComponentInChildren<Animator>();
它的作用是从当前游戏对象player及其所有子对象中查找一个名为Animator的组件,并将找到的第一个该类型组件的引用赋值给变量anim。(在player中,用anim控制Animator的Animator组件)
相当于public然后手动拖拽
anim.SetBool("IsMoving", IsMoving);
用于设置Animator组件中的一个布尔参数的值,SetBool
是Animator组件的一个方法,用于设置动画状态机中定义的布尔参数的值。"IsMoving":这是一个字符串参数,表示要设置的布尔参数的名称。IsMoving:这是一个布尔变量(true或false),其值将被赋给"IsMoving"参数。
也就是说通过判断改变了代码中IsMoving的值,再用setbool方法将IsMoving的值带入到unity之中
启动后发现按下键盘后会有一定的延迟再播放移动动画
取消退出时间
将中间过渡删掉
重构代码和项目
封装一个函数
选中然后 alt + ↓ 将代码移进函数中
在update中调用该函数
提取方法 alt + enter ,如果要定位该方法就ctrl然后鼠标点一下
不断重构优化...
重构整理收纳一下文件
人物的反转
使其在左移动时看向左边,右移动时看向右边
点击查看代码
private int facingDir = 1; //脸的朝向,默认为1
private bool facingRight = true; //脸朝向右边,默认为turevoid Update()
{FlipController();
}
private void Flip(){facingDir = facingDir * -1; //使用反转函数时,该变量变号,用于后续方向的使用facingRight = !facingRight; //使用反转函数时,该变量“是变否否变是”,用于判断当前朝向transform.Rotate(0,180,0);}
private void FlipController()
{if (rb.velocity.x > 0 && !facingRight) //如果速度向右,但面朝左,就反转{Flip();}else if (rb.velocity.x < 0 && facingRight) //如果速度向左,但面朝右,就反转{Flip();}
}
解决跳跃
修复"不停按空格,跳跃可以一直跳下去"的问题
点击查看代码
private bool isGround; //判断是否在地面上
[SerializeField] private float groundCheckDistance; //地面检查距离
[SerializeField] private LayerMask whatIsGround;void Update()
{isGround = Physics2D.Raycast(transform.position, Vector2.down, groundCheckDistance, whatIsGround);
}private void OnDrawGizmos(){Gizmos.DrawLine(transform.position, new Vector3(transform.position.x,transform.position.y - groundCheckDistance));//Gizmos.DrawLine(起点, 终点),绘制一条从起点到终点的直线//transform.position:表示当前物体在世界空间中的位置//从当前物体的位置绘制一条直线到其下方的一个点,这个点的Y坐标是当前物体Y坐标减去groundCheckDistance的值}
添加一个地面图层Ground
给平台应用Ground图层
给player的whatIsGround变量指定Ground图层
给jump代码加上判断
成功!现在小人在地上才能跳跃了!
重构一下update里的代码封装成方法
整理控制面板
现在的player控制器面板上已经有4个变量了,随着进程的推进,面板上的变量会越来越多,整理归类就变得必须
只需添加一个代码
也可以用中文
这样对于变量的作用就清晰易懂,方便后期的记忆
跳跃上升动画
创建Animation
添加素材,修改速率
进入Animator,跳跃这个动作应该是在某些状态(any state)下才运行,即不在地面上(isGround = False)就是跳跃的动作
同理在地面上时执行静止动作
避免延迟感将过度时间都取消/设置为0
取消勾选 can Transition To self:再次“转换”到同一状态。相当于已经在跳跃状态了,如果在转换到跳跃状态,就会在跳跃这个状态的第一帧循环,导致后续的跳跃动作无法执行
编辑代码,使代码中的isGround控制状态树的isGround
跳跃下降动画
同上,创建Animator,添加素材,修改速率
因为按一下空格是有跳跃和下降两个过程,所以为了使角色的动画更加自然流畅,避免了生硬的动画切换,从而提高游戏或动画项目的真实感和沉浸感,引入混合树的功能(blender tree)
双击混合树,添加两个动作
取消自动阈值,手动设置阈值(红线),大于阈值执行jump,小于阈值执行fall
将判断变量名改为yVelocity
选中Animator和混合树,打开混合树动画窗口
手动调节参数的值可以看到动画的变换状态
退出混合树,添加混合树和其他状态的判断,记得修改过渡时间
添加控制yVelocity的代码
完成!跳跃和下降的太慢了,修改一下