文章列表

Unity制作RPG小游戏(0)

Champ2025.05.22 00:00访问量0 次阅读
Unity制作RPG小游戏(0)
简易速成版

人物构建

创建empty game object,Animator,加入sprite,将人物素材(图像)赋予sprite,使unity能够识别。 创建另一个game object,Player,加入rigibody2Dcollider2D(椭圆形collider),实现物理效果。 将Animator作为Player的子物体,即为将人物实体物理效果与人物sprite渲染分开处理。 :::note

  • 关于sprite:可以理解为2D版本的Texture,sprite2D可以搭配使用rigibody2D和collider2D使用

  • 关于rigibody2D:2D刚体,模拟2D物理效果(重力,摩擦力,反作用力)

  • 关于collider2D:检测与其他collider2D的碰撞,与rigibody2D配合模拟物理效果,通过“is trigger”变为无物理阻挡的触发区域(用于检测物体进入/离开)。 :::

场景构建

创建square长方体,拉伸组合成一个简单场景,加上collider2D实现墙体与人物的碰撞(不加入rigibody2D,防止场景受重力影响往下掉)

移动检测

xInput = Input.GetAxisRaw("Horizontal");

body.velocity = new Vector2(xInput * moveSpeed, body.velocity.y);

上面的“body”,即为rigibody类的实体名,在函数初始化(start)的时候通过GetComponent函数获得

void Start()
{
    body = GetComponent<Rigidbody2D>();
    ani = GetComponentInChildren<Animator>();
}

跳跃检测

遇到问题:单纯通过键盘输入判定会导致按键冲突,在跳跃的时候无法移动,但实际上有向前跳/向后跳。

常用的方法是通过raycaster射线检测,通过OnDrawGizmos()函数调试射线检测距离

private void OnDrawGizmos()
{
    Gizmos.DrawLine(
    new Vector2(transform.position.x - 0.15f, transform.position.y), 
    new Vector3(transform.position.x - 0.15f, transform.position.y - groundCheckDistance));
    Gizmos.DrawLine(
    new Vector2(transform.position.x + 0.3f, transform.position.y), 
    new Vector3(transform.position.x + 0.3f, transform.position.y - groundCheckDistance));
}
//我这里画两条线当作两只脚对地面的检测,正常一条中线就够了。
//地面检测
[SerializeField] private float groundCheckDistance = 1.17f;
[SerializeField] private LayerMask whatIsGround;//通过SerializeField声明,可以在unity界面中指定whatIsGround对应的Layer,which is ground。去掉SerializeField就报错了,好像这个是必须的。

void Update()
{
		//...code
    isGrounded1 = Physics2D.Raycast(
    new Vector2(transform.position.x - 0.15f,transform.position.y), 
    Vector2.down, 
    groundCheckDistance, 
    whatIsGround
    );
    isGrounded2 = Physics2D.Raycast(
    new Vector2(transform.position.x + 0.3f, transform.position.y), 
    Vector2.down,
     groundCheckDistance, 
     whatIsGround
     );
    isGrounded = isGrounded1 || isGrounded2;//有一只脚接触到地面就算grounded
    //...code
 }

动画创建

选择连续的素材帧,托选到Animation模块中,通过sample rate调整播放速度,左上角加号创建变量,用来判断动画是否播放。点击animator模块中的状态方块,创建连接箭头,表示人物不同动画间的转换,点击箭头可以创建转换的条件,转换的条件通常是前面创建的变量的改变。

:::note

通过settings项,调整动画的duration和exit time,如果想要动画在该播放的时候马上播放,就把duration调成0,exit time也关掉。如果动画播放不流畅连贯,取消勾选”Can Transition To Self”。

:::

动画播放

void Start()
{
    body = GetComponent<Rigidbody2D>();
    ani = GetComponentInChildren<Animator>();
}

这个脚本属于Player,但动画由子物体animator管理,通过GetComponentInChildren()函数获取。

动画的播放通常是某个相关变量状态的改变,这是通过代码判断的。通过上面获得对animator的操作权,即获得Animator的实体ani,如果某个判断条件成立,如检测到移动,“isMoving”改变

//移动动画判断
if (body.velocity.x != 0f) { isMoving = true; }
else isMoving = false;
ani.SetBool("isMoving", isMoving);//代码通过该函数管理Animator的变量的状态

Blend Tree

跳跃检测通常通过player的raycaster是否接触到地面判断,如果跳跃只有一个动画,可以用isGrounded作为动画的激活变量,但是这里跳跃有三个,起跳,下落和中间的过渡动画。则将三个动画融合成一个跳跃动画,再用isGrounded判断,Blend Tree由此而生。

Blend Tree用于平滑地混合多个动画片段(Animation Clips),以实现更自然的角色动画过渡。它自带一个参数Parameter,作为判断一维blend tree中不同动画之间切换的条件,把参数与player y轴上的速度绑定,通过设置Threshold定义不同速度对应的动画。

:::note

关于Threshold:

  • 定义动画的“生效区间”

    当混合参数(如**Velocity**)的值接近某个动画的Threshold时,该动画的权重(影响程度)会增大。

    • 例如:
      • fall 动画的 Threshold = 1
      • jump 动画的 Threshold = 0.25
      • 如果当前参数 Velocity = -0.5,则系统会自动混合 fall 和 jump 两个动画。
  • 动画混合的规则

    • 如果 Velocity 等于某个动画的Threshold,则该动画权重为100%。
    • 如果 Velocity 介于两个Threshold之间,则两个动画按比例混合(如线性插值)。

:::

历史留言 (0)
ICP备案号浙ICP备2026065730号-1公安备案号浙公网安备33019202003213号