找回密码
 立即注册
查看: 286|回复: 0

[简易教程] Untiy2D入门——小狐狸学习笔记01:2D场景角色创建、角色 ...

[复制链接]
发表于 2022-3-8 10:39 | 显示全部楼层 |阅读模式
声明:

学习教程来源M_Studio老师,本文章只是我本人的学习笔记
<hr/>一、2D场景搭建

1.导入背景图

Pixels Per Unit——场景的每一个单元中分配多少个该图片像素,越小,该图在场景中显示越大


导入背景素材至Scene:

  • 直接将背景图片(设置为Sprite后)拖入Scene,会生成一个2D Object
  • 或者在Hierarchy面板右键:2D Object,将其 Sprite 属性改为 背景图片


2.搭建(图画)关卡地形

2.1 将一张素材图拆分成多个Sprites
一般导入的素材图是由许多分开的图形组成(如下图)


我们需要提取里面的每个元素,需要将此图拆分成多个Sprites
拆分方法:

  • Sprite Mode ——改为Multiple
  • 点击Sprite Editor
  • 点击Slice,Type可以是自动Automatic,但是一般情况下选择手动Grid by Cell Size(根据单元占像素量分)
  • 因为我们在外面设置了改图的Pixels Per Unit属性为16,所以我们将Pixel Size 设置为16x16,这样拆分出来的每个Sprite刚好对应Scene的每个Unit
  • 点击Slice拆分


https://www.zhihu.com/video/1481727451331563520
2.2 创建Tilemap:Hierarchy面板右键: 2D Object -> Tilemap -> Rectangular,会出现一个父物体Grid和子物体Tilemap

  • 父物体Grid用于控制网格的形状和尺寸
  • 子物体Tilemap用于渲染每个Unit的内容
2.3 开启Tile Palette 面板:Tile Palette 相当于一个画板,可以将许多素材导入,方便快速绘制这些素材至场景

  • 方法一,选中Grid,点击Scene右下角 “Open Tile Palette“ 图标
  • 方法二,Window->2D->Tile Palette


2.4 使用Tile Palette

  • 新建一个Tile Palette画板(一个Prefab):将其存放到自己的Assets里
  • 将刚才拆分好多个Sprites的图片拖入到Tile Palette中,存在一个路径中,建议靠近Palette的路径
  • 之后就可以用 Tile Palette 快速绘制地形了,绘制的地形在 Tilemap物体中


https://www.zhihu.com/video/1481727461952491520
<hr/>关于Sprite的图层Layer先后顺序


  • 先看 Sorting Layer——选择图层,越往下,越在前,可以手动添加Layer
  • 当选择同一个Sorting Layer时,则看 Order in Layer,数字越大,越在前
(当选择2个都一样时,则根据Postion的 Z 值判断)


<hr/>二、加入Player角色

加入Player角色:2D角色若要有动画,其是有许多个不同姿势的Sprites组成,我们将站立的Sprite拖入到场景中。(若出现拖入无法看见,可能是被其他Layer挡住了,调节Layer即可)
<hr/>三、添加刚体组件:使角色有重力...

选择Player物体,点击Add Component ,添加2D刚体组件:Rigidbody 2D
添加刚体后:物体会收到力的作用,如重力、阻力......(与角色的移动相关)


<hr/>四、添加碰撞体组件:分别给角色和地形添加

1. 给角色添加碰撞:这里给角色添加的是”方形碰撞体“:Box Collider 2D,添加完后,可以调整其大小,是碰撞体贴合角色


2.给Tilemap添加碰撞:因为地形是Tilemap刷的,Unity里面内置了专门为Tilemap的碰撞体组件:Tilemap Collider 2D,其可以快速为Tilemap里面的每个单元添加碰撞体


<hr/>五、角色移动01

1.Unity默认的Horizontal 移动按键:
Unity有一个默认的input参数是用于设置角色移动方向的
查看默认的Horizontal 移动按键:在 Edit -> Project Settings -> Input Manager->右边Axes->Horizontal ,里面的左右移动键默认为 left、a及right、d
(此次角色移动我们有Horizontal设置的移动按键来操控)


2.为Player添加C#脚本(组件)
核心代码:
Input.GetAxis("Horizontal");    // 获取Unity默认Horizontal的值,当按left或者a时,返回值为-1~0;不按时为0;按right或者d时,返回值为0~1
当按left或者a时,返回值为-1 ~ 0;不按时为0;按right或者d时,返回值为0 ~ 1
返回值的常用于控制移动速度,只需乘一个可控speed来改变物体X的值即可
总的移动C#脚本代码01:(下节继续更新)
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public Rigidbody2D myRigidbody2D;   // 2D刚体变量,获得角色的刚体组件
    public float speed = 1.0f;                 // 浮点变量,控制移动时的速度              
   
   
   
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame  //每一帧运行
    void Update()
    {
        PlayerMovement();           // 每一帧执行移动函数
    }

    // 移动函数
    void PlayerMovement()      
    {
        float horizontalMovement;     // 用于控制角色的移动速度
        horizontalMovement = Input.GetAxis("Horizontal");       // 获取Unity默认Horizontal的值
                                                                // 当按left或者a时,返回值为-1~0;不按时为0;按right或者d时,返回值为0~1
        //【判单移动速度】
        if (horizontalMovement != 0)        // 若角色在移动,
        {
            myRigidbody2D.velocity = new Vector2(horizontalMovement * speed, myRigidbody2D.velocity.y);     // 改变刚体x的速度,保持刚体y的速度不变;horizontalMovement控制左右方向
        }
        

    }
   
}
3.角色控制:写好脚本后,将其拖入Player中,并将Player的Rigidbody 2D 组件拖入公共变量中,设置Speed,点击播放,即可控制角色移动
问题:若出现角色旋转的问题,是因为刚体的Angular Drag(旋转摩擦)太小,导致瞬时速度太快,可能会导致其旋转
解决办法:将Angular Drag调大,或者将Constraints 里的 Freeze Rotation Z打勾


测试变量的Tips:当在运行时改变参数时,需要将其Cope后,结束运行时 Paste Component Values(如下视频)


https://www.zhihu.com/video/1481727560531283968
<hr/>六、角色移动02

实现角色左右转向改变:调节Transfrom的Scale的X为正负1
核心代码:
float horizontalFaceDirection = Input.GetAxisRaw("Horizontal");     //GetAxisRaw与 GetAxis的区别是,其只会获得-1,0,1
//【判断面部朝向】
if (horizontalFaceDirection != 0)   // 若按下了左右,使得朝向更新
{
    this.transform.localScale = new Vector3(horizontalFaceDirection, 1, 1);    // 更新当前物体的Scale.x的值,yz值不变
}
FixedUpdate函数:因为不同的机器性能不同,每1s执行的帧数也不同,为了保持各个机器相同,我们将Update函数改为FixedUpdate函数:其使每0.02s执行一次
// FixedUpdate与Updata不同,其不是每一帧执行,而是每0.02s执行
void FixedUpdate()      
{
    PlayerMovement();           // 执行移动函数
}
总的移动C#脚本代码02:(下节继续更新)
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public Rigidbody2D myRigidbody2D;   // 2D刚体变量,获得角色的刚体组件
    public float speed = 1.0f;                 // 浮点变量,控制移动时的速度              
   
   
   
    // Start is called before the first frame update
    void Start()
    {
        
    }
    // FixedUpdate与Updata不同,其不是每一帧执行,而是每0.02s执行
    void FixedUpdate()      
    {
        PlayerMovement();           // 每一帧执行移动函数
    }

    // 移动函数
    void PlayerMovement()      
    {
        float horizontalMovement = Input.GetAxis("Horizontal");       // 获取Unity默认Horizontal的值,当按left或者a时,返回值为-1~0;不按时为0;按right或者d时,返回值为0~1
        float horizontalFaceDirection = Input.GetAxisRaw("Horizontal");     //GetAxisRaw与 GetAxis的区别是,其只会获得-1,0,1
        //【判单移动速度】
        if (horizontalMovement != 0)        // 若角色在移动
        {
            myRigidbody2D.velocity = new Vector2(horizontalMovement * speed, myRigidbody2D.velocity.y);     // 改变刚体x的速度,保持刚体y的速度不变;horizontalMovement控制左右方向
        }
        //【判断面部朝向】
        if (horizontalFaceDirection != 0)   // 若按下了左右,使得朝向更新
        {
            this.transform.localScale = new Vector3(horizontalFaceDirection, 1, 1);    // 更新当前物体的Scale.x的值,yz值不变
        }

    }   
}
<hr/>七、角色跳跃

”Jump“和”Horizontal“一样,也是可以在Unity中设置的,我这里设置为了w


核心代码:
public float jumpForce;     // 控制跳跃时的力
//【判断是否跳跃】
if (Input.GetButtonDown("Jump"))   // 若按下默认Axis里的Jump,只会在按下瞬间执行
{
    myRigidbody2D.velocity = new Vector2(myRigidbody2D.velocity.x, jumpForce);      // 保持x方向的速度不变,改变y方向的速度
}// 控制跳跃的力总的移动C#脚本代码03:(下节继续更新)
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public Rigidbody2D myRigidbody2D;   // 2D刚体变量,获得角色的刚体组件
    public float speed = 1.0f;                 // 浮点变量,控制移动时的速度              
    public float jumpForce;             // 控制跳跃的力
   
   
   
    // Start is called before the first frame update
    void Start()
    {
        
    }
    // FixedUpdate与Updata不同,其不是每一帧执行,而是每0.02s执行
    void FixedUpdate()      
    {
        PlayerMovement();           // 执行移动函数
    }

    // 移动函数
    void PlayerMovement()      
    {
        float horizontalMovement = Input.GetAxis("Horizontal");       // 获取Unity默认Horizontal的值,当按left或者a时,返回值为-1~0;不按时为0;按right或者d时,返回值为0~1
        float horizontalFaceDirection = Input.GetAxisRaw("Horizontal");     //GetAxisRaw与 GetAxis的区别是,其只会获得-1,0,1
        //【判单移动速度】
        if (horizontalMovement != 0)        // 若角色在移动
        {
            myRigidbody2D.velocity = new Vector2(horizontalMovement * speed, myRigidbody2D.velocity.y);     // 改变刚体x的速度,保持刚体y的速度不变;horizontalMovement控制左右方向
        }
        //【判断面部朝向】
        if (horizontalFaceDirection != 0)   // 若按下了左右,使得朝向更新
        {
            this.transform.localScale = new Vector3(horizontalFaceDirection, 1, 1);    // 更新当前物体的Scale.x的值,yz值不变
        }
        //【判断是否跳跃】
        if (Input.GetButtonDown("Jump"))   // 若按下默认Axis里的Jump,只会在按下顺键执行
        {
            myRigidbody2D.velocity = new Vector2(myRigidbody2D.velocity.x, jumpForce);      // 保持x方向的速度不变,改变y方向的速度
        }
    }
}<hr/>八、添加动画

8.1 为角色添加Animator组件:Animator组件是需要AnimatorController来控制动画播放的
8.2 新建角色的AnimatorController:在Assets中右键新建一个AnimatorController,将其拖到刚才创建的Animator组件中
8.3 添加角色动画:

  • Window->Animation->Animation开启动画面板
  • 选择角色Create New Clip 添加新动画,选择动画的存储路径,下面演示添加站立时的动画
(注意:若8.2没有拖到Animator组件中,直接进行8.3,会自动给角色创建一个Animator组件和Controller)
添加Animation视频演示:含中途不小心删掉AnimatorController的解决办法


https://www.zhihu.com/video/1481727617007542272
若出现Animation无法循环播放时:查看anim文件,需要勾选Loop Time
<hr/>九、控制不同动画的切换01:跑

9.1 开启Window->Animation->Animator 面板(这里是此Animator组件的内部Animation切换面板)
9.2 添加新动画,这里添加了run动画(参考8.3第二点),文件名为run_anim


默认动画是Entry黄色箭头连的动画,若需要修改默认动画,则需要将anmi的Motion参数修改,同时改掉其名字(因为黄色箭头是改不了的,只能修改指向的动画属性)


9.3 建立动画联系:选择动画按钮,右键Make Transition,产生箭头,指向另一个动画

  • 箭头的设置:【达到迅速切换】


9.4 为Animator添加变量,且为箭头添加条件:箭头运行的条件与此变量有关,这些变量可以被脚本引用,达到控制动画间的切换
注:为什么设置为0.1而非0,是为了后面在脚本中方便切回站立动画


9.5 在C#脚本中控制动画的切换变量
核心代码:
public Animator myAnimator;         // Animator变量,获取Animator组件
//【判断移动速度】
if (horizontalMovement != 0)        // 若角色在移动
{
    myRigidbody2D.velocity = new Vector2(horizontalMovement * speed, myRigidbody2D.velocity.y);     // 改变刚体x的速度,保持刚体y的速度不变;horizontalMovement控制左右方向
    myAnimator.SetFloat("runningAnimPara", Mathf.Abs(horizontalFaceDirection));           // 设置AnimatorController的Running变量参数,用于切换至Running动画Animation,之前设置箭头判断条件为0.1而非0,就是为了可以返回站立动画
}
总的移动C#脚本代码04:(下节继续更新)
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public Rigidbody2D myRigidbody2D;   // 2D刚体变量,获得角色的刚体组件
    public Animator myAnimator;         // Animator变量,获取Animator组件
    public float speed = 1.0f;          // 浮点变量,控制移动时的速度              
    public float jumpForce;             // 控制跳跃的力
   
   
   
    // Start is called before the first frame update
    void Start()
    {
        
    }
    // FixedUpdate与Updata不同,其不是每一帧执行,而是每0.02s执行
    void FixedUpdate()      
    {
        PlayerMovement();           // 执行移动函数
    }

    // 移动函数
    void PlayerMovement()      
    {
        float horizontalMovement = Input.GetAxis("Horizontal");       // 获取Unity默认Horizontal的值,当按left或者a时,返回值为-1~0;不按时为0;按right或者d时,返回值为0~1
        float horizontalFaceDirection = Input.GetAxisRaw("Horizontal");     //GetAxisRaw与 GetAxis的区别是,其只会获得-1,0,1
        //【判断移动速度】
        if (horizontalMovement != 0)        // 若角色在移动
        {
            myRigidbody2D.velocity = new Vector2(horizontalMovement * speed, myRigidbody2D.velocity.y);     // 改变刚体x的速度,保持刚体y的速度不变;horizontalMovement控制左右方向
            myAnimator.SetFloat("runningAnimPara", Mathf.Abs(horizontalFaceDirection));           // 设置AnimatorController的Running变量参数,用于切换至Running动画Animation,之前设置箭头判断条件为0.1而非0,就是为了可以返回站立动画
        }
        //【判断面部朝向】
        if (horizontalFaceDirection != 0)   // 若按下了左右,使得朝向更新
        {
            this.transform.localScale = new Vector3(horizontalFaceDirection, 1, 1);    // 更新当前物体的Scale.x的值,yz值不变
        }
        //【判断是否跳跃】
        if (Input.GetButtonDown("Jump"))   // 若按下默认Axis里的Jump,只会在按下瞬间执行
        {
            myRigidbody2D.velocity = new Vector2(myRigidbody2D.velocity.x, jumpForce);      // 保持x方向的速度不变,改变y方向的速度
        }
    }
}
<hr/>十、控制不同动画的切换:跳跃、下落

10.1 准备动画:分别添加跳跃和下落的动画,并在Animator中连上箭头,设置箭头的时间参数【达到迅速切换】
10.2 在Animator中添加3个Bool变量、箭头的触发条件:用于控制是否进行跳跃jump和下落drop动画,以及从drop回归idle的动画


箭头的判断参数设置:


https://www.zhihu.com/video/1481727657025441792
10.3 从跳跃到下落的动画:
//【判断是否跳跃】
if (Input.GetButtonDown("Jump"))   // 若按下默认Axis里的Jump,只会在按下瞬间执行
{
myRigidbody2D.velocity = new Vector2(myRigidbody2D.velocity.x, jumpForce);      // 保持x方向的速度不变,改变y方向的速度
myAnimator.SetBool("jumpingAnimPara_B", true);                          // 设置跳跃动画的触发条件
}

//【下落动画触发】
if (myRigidbody2D.velocity.y < 0)       // 若刚体的y速度<0
{
    myAnimator.SetBool("droppingAnimPara_B",true);      // 设置下落anim触发Bool
    myAnimator.SetBool("jumpingAnimPara_B",false);      // 设置跳跃anim触发Bool
}10.4 角色落到地面下落动画变为站立
这里建立了Collider2D变量,用于获取角色的碰撞体
还有一个LayerMask变量,用于获取地面物体,这样就可以判断是否碰到了该Layer中的物体(地形)了


核心代码:
public Collider2D myCollider2D;     // 2D碰撞体变量,获得碰撞体
public LayerMask ground;            // 图层变量:获得该图层的物体,这里将地形Layer传入

//【下落动画停止】
if (myCollider2D.IsTouchingLayers(ground))      // 若该物体的碰撞体接触到地形的Layer
{
myAnimator.SetBool("droppingAnimPara_B",false);      // 设置下落anim停止
}总的移动C#脚本代码05:(下节继续更新)
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public Rigidbody2D myRigidbody2D;   // 2D刚体变量,获得角色的刚体组件
    public Animator myAnimator;         // Animator变量,获取Animator组件
    public Collider2D myCollider2D;     // 2D盆碰撞体变量,获得碰撞体
    public float speed = 1.0f;          // 浮点变量,控制移动时的速度              
    public float jumpForce;             // 控制跳跃的力
    public LayerMask ground;            // 图层变量:获得该图层的物体,这里将地形Layer传入




    // Start is called before the first frame update
    void Start()
    {
        
    }
    // FixedUpdate与Updata不同,其不是每一帧执行,而是每0.02s执行
    void FixedUpdate()      
    {
        PlayerMovement();           // 执行移动函数
        SwitchAnim();               // 执行部分切换动画函数
    }

    //【移动函数】
    void PlayerMovement()      
    {
        float horizontalMovement = Input.GetAxis("Horizontal");       // 获取Unity默认Horizontal的值,当按left或者a时,返回值为-1~0;不按时为0;按right或者d时,返回值为0~1
        float horizontalFaceDirection = Input.GetAxisRaw("Horizontal");     //GetAxisRaw与 GetAxis的区别是,其只会获得-1,0,1
        //【判断移动速度】
        if (horizontalMovement != 0)        // 若角色在移动
        {
            myRigidbody2D.velocity = new Vector2(horizontalMovement * speed, myRigidbody2D.velocity.y);     // 改变刚体x的速度,保持刚体y的速度不变;horizontalMovement控制左右方向
            myAnimator.SetFloat("runningAnimPara_F", Mathf.Abs(horizontalFaceDirection));           // 设置AnimatorController的Running变量参数,用于切换至Running动画Animation,之前设置箭头判断条件为0.1而非0,就是为了可以返回站立动画
        }
        //【判断面部朝向】
        if (horizontalFaceDirection != 0)   // 若按下了左右,使得朝向更新
        {
            this.transform.localScale = new Vector3(horizontalFaceDirection, 1, 1);    // 更新当前物体的Scale.x的值,yz值不变
        }
        //【判断是否跳跃】
        if (Input.GetButtonDown("Jump"))   // 若按下默认Axis里的Jump,只会在按下瞬间执行
        {
            myRigidbody2D.velocity = new Vector2(myRigidbody2D.velocity.x, jumpForce);      // 保持x方向的速度不变,改变y方向的速度
            myAnimator.SetBool("jumpingAnimPara_B", true);                          // 设置跳跃动画的触发条件
        }
    }
   
    //【部分切换动画函数】
    void SwitchAnim()
    {
        //【下落动画触发】
        if (myRigidbody2D.velocity.y < 0)       // 若刚体的y速度<0
        {
            myAnimator.SetBool("droppingAnimPara_B",true);      // 设置下落anim触发Bool
            myAnimator.SetBool("jumpingAnimPara_B",false);      // 设置跳跃anim触发Bool
        }
        //【下落动画停止】
        if (myCollider2D.IsTouchingLayers(ground))      // 若该物体的碰撞体接触到地形的Layer
        {
            myAnimator.SetBool("droppingAnimPara_B",false);      // 设置下落anim停止
        }
    }
}<hr/>十一、角色移动总结 + 代码优化+BUG修复!!!

之前可能存在的BUG:

  • 角色在地面左右移动时,可能突然卡住
    原因:方向碰撞体之间可能会突然卡住,当刚体组件Rigid body 2D不勾选 Freeze Rotation Z时,它会旋转,当勾选时,它会卡住
    解决办法:制作2个碰撞体
  • 角色跳跃键不灵敏
    原因:按跳跃键是在每一帧触发
    解决办法:将FixedUpdate()函数 改为 Update()函数
  • 角色卡在空中墙壁上
    原因:角色碰撞体和墙壁碰撞体之间有摩擦
    解决办法:创建物理材质:Physics Material 2D,将其摩擦力设置为0,拖入角色的Box Collider 2D组件中
  • 角色在左右移动时可能动画切换
    原因:角色在移动时,碰撞体有时可能不会接触,角色的y值可能会变
    解决办法:在角色底部创建Empty物体,通过Empty与地面的接触判断是否在地面上,而不是用Collider box 判断
代码优化:

  • 加入了多段跳:通过jumpCount变量控制可跳跃次数
  • 有些变量设置为了Private,在Start()函数里通过GetComponent<...>() 进行赋值
  • 将移动函数和动画函数分开,条理更加清晰


https://www.zhihu.com/video/1481727700998504448

补充优化——只用1个方形BOX!!!

  • 可以不用圆形的Box,只用方形Box也可以解决bug,只需给Box 添加无摩擦力的物理材质 Physics Material 2D
  • 为什么不用2个Box,因为在后面写吃东西逻辑时,2个box会使得1个物品被吃2次(这是个BUG)
总移动代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class MyPlayerController : MonoBehaviour
{

    //【参数变量】
    private Rigidbody2D myRigidbody2D;           // 获得刚体
    [SerializeField]private Collider2D myCollider2D;             // 获得碰撞体
    //【接触判断变量】
    [SerializeField] private bool isGound;      // 判断是否在地面上,[SerializeField]用于在外部面板显示
    // 地面检测
    public Transform groundCheck;               // 检测地面碰撞
    public LayerMask ground;                    // 获得地面
    // Animator
    private Animator myAnimator;                // 获得Animator
   
    //【移动变量】
    public float moveSpeed;                       // 移动速度
    //【跳跃、下落变量】
    public float jumpForce;                       // 跳跃力
    private bool isJumpPressed;                   // 判断是否按下跳跃按键
    public  int jumpCount;                        // 多段跳次数
    [SerializeField]private int currentJumpCount; // 当前可跳跃次数
    private bool isJump;                          // 判断是否在跳跃
    private bool isDrop;                          // 判断是否在下落
    private bool isAlreadyJump = false;           // 判断是否跳过
   
    ////-------------------------------------Start
    // Start函数
    void Start()
    {
        Initialization();       // 初始化
    }
   
        //【初始化函数】
        void Initialization()
        {
            myRigidbody2D = this.GetComponent<Rigidbody2D>();        // 刚体赋值:该物体的刚体
            myCollider2D = this.GetComponent<BoxCollider2D>();          // 碰撞体赋值:只能获取第一个碰撞体组件
            myAnimator = this.GetComponent<Animator>();              // Animator赋值
            EmptyPosFun();                                           // 设置空物体的初始位置
        }
            //【设置 空物体的位置:和CollideBox匹配】
            void EmptyPosFun()
            {
                groundCheck.localPosition = new Vector3(-myCollider2D.offset.x, -1.0f, 0.0f);       // 设置底部空物体的位置: x为碰撞体的-x,y为-1.0
            }
   
    ////--------------------------------------------------------Update
    // Update函数
    void Update()
    {
        MoveAllFunction();      // 总移动函数
        AnimatorAllFunction();  // 总动画函数
    }

        //【移动总函数】
        void MoveAllFunction()
        {
            isGound = Physics2D.OverlapBox(groundCheck.position, new Vector2(myCollider2D.bounds.size.x, 0.3f),0.0f, ground);      // 在空物体周围生成一个空box,其x宽度与碰撞体一样
            GoundMoveFun();        // 地面移动
            SkipDropFun();         // 跳跃、下落
        }
   
            //【地面移动】
            void GoundMoveFun()
            {   
                // 左右移动
                float horizontalMove = Input.GetAxisRaw("Horizontal");      // 返回-1,0,1
                myRigidbody2D.velocity = new Vector2(horizontalMove * moveSpeed, myRigidbody2D.velocity.y);     // x方向移动
                // 左右翻转
                if (horizontalMove != 0)    // 若不是静止
                {
                    this.transform.localScale = new Vector3(horizontalMove, 1, 1);      // x方向翻转
                }
            }
            
            //【跳跃、下落】
            void SkipDropFun()
            {
               
                //【判断是否按下Jump按键】
                if (Input.GetButtonDown("Jump"))
                {
                    if (currentJumpCount > 0)          // 只有在可跳跃时,才算按下,否则此次按下无效
                    {
                        isJumpPressed = true;
                    }
                }

                //【执行跳跃】
                if (isJumpPressed && currentJumpCount > 0)       // 执行Jump:若按下Jump键,且可跳跃次数不为0
                {
                    isJump = true;      // 在跳跃
                    myRigidbody2D.velocity = new Vector2(myRigidbody2D.velocity.x, jumpForce);      // y方向获得瞬时速度
                    currentJumpCount--;        // 跳跃次数减1
                    isAlreadyJump = true;   // 进行过跳跃
                    isJumpPressed = false;  // 使其停止,防止一直按着jump键,导致一直进入该if
                }
               
                //【跳跃过程判断】
                if (myRigidbody2D.velocity.y > 0 && !isGound)   // !isGound是防止在平地上因误差而产生的Bug
                {
                    isDrop = false;
                    isJump = true;
                }
                    
                //【下落过程判断】
                if (myRigidbody2D.velocity.y < 0 && !isGound)   // !isGound是防止在平地上因误差而产生的Bug
                {
                    isDrop = true;
                    isJump = false;
                    //【因走路掉落使跳跃次数-1】
                    if (!isAlreadyJump)         // 若之前没跳过,即是走路而引起的掉落
                    {
                        currentJumpCount--;     // 当前可跳跃次数-1
                        isAlreadyJump = true;   // 算进行过跳跃
                    }
                }
               
               
                //【到达地面,跳跃次数恢复】
                if (isGound)
                {
                    isJump = false;     // 到地面时不在跳跃
                    isDrop = false;     // 到地面时不在下落
                    isAlreadyJump = false; // 刷新:未进行跳跃

                    if (!isJump)    // !isJump一定要判断,因为否则起跳时,会与Ground接触导致触发跳跃次数恢复,会多跳一次
                    {
                        currentJumpCount = jumpCount;   // 可跳跃次数更新
                    }
                }
            }
               
            
         
        //【Animator总函数】
        void AnimatorAllFunction()
        {
            //【左右移动Anim】
            myAnimator.SetFloat("runningAnimPara_F", Mathf.Abs(myRigidbody2D.velocity.x));           // 设置AnimatorController的Running变量参数,根据左右速度设置
            
            //【跳跃、下落Anim】
                //【跳跃Anim】
                if (isJump && !isDrop)
                {
                    myAnimator.SetBool("jumpingAnimPara_B", true);          // 跳跃true
                    myAnimator.SetBool("droppingAnimPara_B", false);        // 下落false
                }
                //【下落Anim】
                else if (isDrop && !isJump)
                {
                    myAnimator.SetBool("droppingAnimPara_B", true);         // 下落true
                    myAnimator.SetBool("jumpingAnimPara_B", false);         // 跳跃false
                }
                //【下落 回归站立Anim】
                else if (!isDrop && !isJump)
                {
                    myAnimator.SetBool("droppingAnimPara_B", false);         // 下落false
                    myAnimator.SetBool("jumpingAnimPara_B", false);         // 跳跃false
                }
            
        }
            
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-5-8 02:28 , Processed in 0.103159 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表