【unity]学习制作类银河恶魔城游戏-2-

导入新资产


切割新资产


切割完成

修改大小和清晰度

球体已经设置了刚体和碰撞体积,直接应用给人物,改名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;  //脸朝向右边,默认为ture

void 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的代码

完成!跳跃和下降的太慢了,修改一下

posted @   plusu  阅读(41)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示