Untiy2D入门——小狐狸学习笔记01:2D场景角色创建、角色 ...
声明:学习教程来源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(&#34;Horizontal&#34;); // 获取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(&#34;Horizontal&#34;); // 获取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(&#34;Horizontal&#34;); //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(&#34;Horizontal&#34;); // 获取Unity默认Horizontal的值,当按left或者a时,返回值为-1~0;不按时为0;按right或者d时,返回值为0~1
float horizontalFaceDirection = Input.GetAxisRaw(&#34;Horizontal&#34;); //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(&#34;Jump&#34;)) // 若按下默认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(&#34;Horizontal&#34;); // 获取Unity默认Horizontal的值,当按left或者a时,返回值为-1~0;不按时为0;按right或者d时,返回值为0~1
float horizontalFaceDirection = Input.GetAxisRaw(&#34;Horizontal&#34;); //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(&#34;Jump&#34;)) // 若按下默认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(&#34;runningAnimPara&#34;, 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(&#34;Horizontal&#34;); // 获取Unity默认Horizontal的值,当按left或者a时,返回值为-1~0;不按时为0;按right或者d时,返回值为0~1
float horizontalFaceDirection = Input.GetAxisRaw(&#34;Horizontal&#34;); //GetAxisRaw与 GetAxis的区别是,其只会获得-1,0,1
//【判断移动速度】
if (horizontalMovement != 0) // 若角色在移动
{
myRigidbody2D.velocity = new Vector2(horizontalMovement * speed, myRigidbody2D.velocity.y); // 改变刚体x的速度,保持刚体y的速度不变;horizontalMovement控制左右方向
myAnimator.SetFloat(&#34;runningAnimPara&#34;, 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(&#34;Jump&#34;)) // 若按下默认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(&#34;Jump&#34;)) // 若按下默认Axis里的Jump,只会在按下瞬间执行
{
myRigidbody2D.velocity = new Vector2(myRigidbody2D.velocity.x, jumpForce); // 保持x方向的速度不变,改变y方向的速度
myAnimator.SetBool(&#34;jumpingAnimPara_B&#34;, true); // 设置跳跃动画的触发条件
}
//【下落动画触发】
if (myRigidbody2D.velocity.y < 0) // 若刚体的y速度<0
{
myAnimator.SetBool(&#34;droppingAnimPara_B&#34;,true); // 设置下落anim触发Bool
myAnimator.SetBool(&#34;jumpingAnimPara_B&#34;,false); // 设置跳跃anim触发Bool
}10.4 角色落到地面下落动画变为站立
这里建立了Collider2D变量,用于获取角色的碰撞体
还有一个LayerMask变量,用于获取地面物体,这样就可以判断是否碰到了该Layer中的物体(地形)了
核心代码:
public Collider2D myCollider2D; // 2D碰撞体变量,获得碰撞体
public LayerMask ground; // 图层变量:获得该图层的物体,这里将地形Layer传入
//【下落动画停止】
if (myCollider2D.IsTouchingLayers(ground)) // 若该物体的碰撞体接触到地形的Layer
{
myAnimator.SetBool(&#34;droppingAnimPara_B&#34;,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(&#34;Horizontal&#34;); // 获取Unity默认Horizontal的值,当按left或者a时,返回值为-1~0;不按时为0;按right或者d时,返回值为0~1
float horizontalFaceDirection = Input.GetAxisRaw(&#34;Horizontal&#34;); //GetAxisRaw与 GetAxis的区别是,其只会获得-1,0,1
//【判断移动速度】
if (horizontalMovement != 0) // 若角色在移动
{
myRigidbody2D.velocity = new Vector2(horizontalMovement * speed, myRigidbody2D.velocity.y); // 改变刚体x的速度,保持刚体y的速度不变;horizontalMovement控制左右方向
myAnimator.SetFloat(&#34;runningAnimPara_F&#34;, 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(&#34;Jump&#34;)) // 若按下默认Axis里的Jump,只会在按下瞬间执行
{
myRigidbody2D.velocity = new Vector2(myRigidbody2D.velocity.x, jumpForce); // 保持x方向的速度不变,改变y方向的速度
myAnimator.SetBool(&#34;jumpingAnimPara_B&#34;, true); // 设置跳跃动画的触发条件
}
}
//【部分切换动画函数】
void SwitchAnim()
{
//【下落动画触发】
if (myRigidbody2D.velocity.y < 0) // 若刚体的y速度<0
{
myAnimator.SetBool(&#34;droppingAnimPara_B&#34;,true); // 设置下落anim触发Bool
myAnimator.SetBool(&#34;jumpingAnimPara_B&#34;,false); // 设置跳跃anim触发Bool
}
//【下落动画停止】
if (myCollider2D.IsTouchingLayers(ground)) // 若该物体的碰撞体接触到地形的Layer
{
myAnimator.SetBool(&#34;droppingAnimPara_B&#34;,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; // 获得刚体
private Collider2D myCollider2D; // 获得碰撞体
//【接触判断变量】
private bool isGound; // 判断是否在地面上,用于在外部面板显示
// 地面检测
public Transform groundCheck; // 检测地面碰撞
public LayerMask ground; // 获得地面
// Animator
private Animator myAnimator; // 获得Animator
//【移动变量】
public float moveSpeed; // 移动速度
//【跳跃、下落变量】
public float jumpForce; // 跳跃力
private bool isJumpPressed; // 判断是否按下跳跃按键
publicint jumpCount; // 多段跳次数
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(&#34;Horizontal&#34;); // 返回-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(&#34;Jump&#34;))
{
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(&#34;runningAnimPara_F&#34;, Mathf.Abs(myRigidbody2D.velocity.x)); // 设置AnimatorController的Running变量参数,根据左右速度设置
//【跳跃、下落Anim】
//【跳跃Anim】
if (isJump && !isDrop)
{
myAnimator.SetBool(&#34;jumpingAnimPara_B&#34;, true); // 跳跃true
myAnimator.SetBool(&#34;droppingAnimPara_B&#34;, false); // 下落false
}
//【下落Anim】
else if (isDrop && !isJump)
{
myAnimator.SetBool(&#34;droppingAnimPara_B&#34;, true); // 下落true
myAnimator.SetBool(&#34;jumpingAnimPara_B&#34;, false); // 跳跃false
}
//【下落 回归站立Anim】
else if (!isDrop && !isJump)
{
myAnimator.SetBool(&#34;droppingAnimPara_B&#34;, false); // 下落false
myAnimator.SetBool(&#34;jumpingAnimPara_B&#34;, false); // 跳跃false
}
}
}
页:
[1]