目录

Sunny Land | 2D Characters | Unity Asset Store

传送门:
Unity笔记(2):游戏场景搭建_代码骑士的博客-CSDN博客

传送门:
Unity笔记(4):控制角色移动_代码骑士的博客-CSDN博客

打开animation组件

新建动画文件
选择idle连帧图片批量拖拽进动画编译器中

调节适当的频率
接下来,点击动画组件创建更多动画

如下:

打开动画控制器

如下,可以看到我们所创建的所有动画

目前可以看到动画控制器中,进入动画默认指向Player_idle,打开进入游戏,发现无论如何移动角色,都只执行,play_idle动画,因此,我们需要动画控制器设置不同动画之间的转换。
右键选择make Transition添加转换箭头

点击箭头可以查看转换条件
点击左侧栏Parameter添加可控制动画转换的变量:
这里添加float类型的speed变量,通过速度来控制idle和run动画之间的转换。

点击箭头右侧栏设置转换条件:速度大于0.01时为run状态

取消动画的过渡时间,实现迅速转换

反过来设置run到idle的转换和条件

执行游戏,当参数变化时,动画也会变化

接下来,我们通过脚本,用代码实现如何控制动画的speed变量。
我们知道实现角色移动的两个脚本中

第一个是实现角色移动的基础,也就是常用的套路代码。有这个脚本才能实现角色移动。
第二个是我们自己写的角色移动逻辑,通过这个脚本调用基础脚本中的方法,实现角色移动。
接下来,我们要修改第二个脚本中的代码实现动画转换的逻辑。
添加动画控制器组件:

将动画器组件拖入栏中

将玩家当前速度传给动画器中的速度,从而进行动画转换的判断
为了保证动画任何位置都能工作,我们要给移动速度加上绝对值
animator.SetFloat("Speed", Mathf.Abs(move));
设置跳跃动画
无论是跑还是站立,角色都可以转换成跳跃动画

也就是任何状态都可以跳跃, 那么unity的Animator提供了一个很好的状态,就是any state

再设置转换条件
设置布尔类型的jumping参数,当jumping为真时,开始播放跳跃动画
但是这样还不行,因为播放完跳跃后无法回到其他状态,所以还要增加两个转换
jump->idle

jump->run

然后修改代码:
普通写法:
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class PlayerMovement : MonoBehaviour
- {
- public CharacterController2D cc;//角色控制器组件
-
- public Animator animator;//动画控制器组件
-
- public float speed = 5f;//速度
-
- float move;//水平移动方向
-
- bool jump;//是否跳跃
-
- // Update is called once per frame
- void Update()
- {
- move = Input.GetAxis("Horizontal")*speed;//获取角色水平移动速度
- animator.SetFloat("Speed", Mathf.Abs(move));//将玩家当前速度传给动画器的speed参数
- jump = Input.GetButton("Jump");
- animator.SetBool("Jumping", jump);
- }
-
- void FixedUpdate()
- {
- cc.Move(move, jump);
- }
- }
高级写法:
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class PlayerMovement : MonoBehaviour
- {
- public CharacterController2D cc;//角色控制器组件
-
- public Animator animator;//动画控制器组件
-
- public float speed = 5f;//速度
-
- float move;//水平移动方向
-
- bool jump;//是否跳跃
-
- // Update is called once per frame
- void Update()
- {
- move = Input.GetAxis("Horizontal")*speed;//获取角色水平移动速度
- animator.SetFloat("Speed", Mathf.Abs(move));//将玩家当前速度传给动画器的speed参数
- if (Input.GetButtonDown("Jump"))//判断什么时候播放跳跃动画
- {
- jump = true;
- animator.SetBool("Jumping", true);
- }
- }
- //结合CharacterController2D脚本,检测是否在地面
- public void OnLanding()
- {
- jump = false;
- animator.SetBool("Jumping", false);//判断何时停止跳跃
- }
-
- void FixedUpdate()
- {
- cc.Move(move, jump);
- }
- }
结合CharacterController2D组件写一个Onlanding函数判断停止跳跃动画

动画只能播放一半
取消下面勾选,播放完整跳跃动画

同理添加Crouch动画

注意:
在crouch动画转回run或者idle时,不能取消时间的勾选,因为crouch时间太短了,需要勾选并自己手动增加动画时间。

角色爬行代码:
-
- if (Input.GetKey(KeyCode.S))//判断什么时候播放爬行动画
- {
- crouch = true;
- }else
- {
- crouch = false;
- }
- animator.SetBool("Crouching", crouch);
最后放上完整的代码:
CharacterController2D :
- using UnityEngine;
- using UnityEngine.Events;
-
- public class CharacterController2D : MonoBehaviour
- {
- public float jumpForce = 400f; // 弹跳力
- public bool canAirControl = false; // 在空中时,是否能控制
- public LayerMask groundMask; // 定义哪一个Layer是地面
- public Transform m_GroundCheck; // 用于判定地面的空物体
-
- const float k_GroundedRadius = .1f; // 用于检测地面的小圆形的半径
- private bool m_Grounded; // 当前是否在地面上
- private bool m_FacingRight = true; // 玩家是否面朝右边
- private Vector3 m_Velocity = Vector3.zero;
-
- const float m_NextGroundCheckLag = 0.1f; // 起跳后的一小段时间,不能再次起跳。防止连跳的一种解决方案
- float m_NextGroundCheckTime; // 过了这个时间才可能落地、才能再次起跳
-
- // 这个角色控制器,是依靠刚体驱动的
- private Rigidbody2D m_Rigidbody2D;
-
- [Header("Events")]
- [Space]
-
- public UnityEvent OnLandEvent;
- public UnityEvent OnAirEvent;
-
- [System.Serializable]
- public class BoolEvent : UnityEvent<bool> { }
-
- private void Awake()
- {
- m_Rigidbody2D = GetComponent
(); -
- if (OnLandEvent == null)
- OnLandEvent = new UnityEvent();
- if (OnAirEvent == null)
- OnAirEvent = new UnityEvent();
- }
-
- private void FixedUpdate()
- {
- bool wasGrounded = m_Grounded;
- m_Grounded = false;
-
- // 检测与地面的碰撞
- if (Time.time > m_NextGroundCheckTime)
- {
- Collider2D[] colliders = Physics2D.OverlapCircleAll(m_GroundCheck.position, k_GroundedRadius, groundMask);
- for (int i = 0; i < colliders.Length; i++)
- {
- if (colliders[i].gameObject != gameObject)
- {
- m_Grounded = true;
- if (!wasGrounded)
- OnLandEvent.Invoke();
- }
- }
- }
-
- if (wasGrounded && !m_Grounded)
- {
- OnAirEvent.Invoke();
- }
- }
-
-
- public void Move(float move, bool jump)
- {
- // 玩家在地面时,或者可以空中控制时,才能移动
- if (m_Grounded || canAirControl)
- {
- // 输入变量move决定横向速度
- m_Rigidbody2D.velocity = new Vector2(move, m_Rigidbody2D.velocity.y);
-
- // 面朝右时按左键,或面朝左时按右键,都会让角色水平翻转
- if (move > 0 && !m_FacingRight)
- {
- Flip();
- }
- else if (move < 0 && m_FacingRight)
- {
- Flip();
- }
- }
-
- // 在地面时按下跳跃键,就会跳跃
- if (m_Grounded && jump)
- {
- OnAirEvent.Invoke();
- m_Grounded = false;
- // 施加弹跳力
- m_Rigidbody2D.AddForce(new Vector2(0f, jumpForce));
- m_NextGroundCheckTime = Time.time + m_NextGroundCheckLag;
- }
- }
-
-
- private void Flip()
- {
- // true变false,false变true
- m_FacingRight = !m_FacingRight;
-
- // 缩放的x轴乘以-1,图片就水平翻转了
- transform.localScale = Vector3.Scale(transform.localScale, new Vector3(-1, 1, 1));
- }
- }
PlayerMovement :
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class PlayerMovement : MonoBehaviour
- {
- public CharacterController2D cc;//角色控制器组件
-
- public Animator animator;//动画控制器组件
-
- public float speed = 5f;//速度
-
- float move;//水平移动方向
-
- bool jump;//是否跳跃
-
- bool crouch;//是否爬行
-
- // Update is called once per frame
- void Update()
- {
- move = Input.GetAxis("Horizontal")*speed;//获取角色水平移动速度
- animator.SetFloat("Speed", Mathf.Abs(move));//将玩家当前速度传给动画器的speed参数
- if (Input.GetButtonDown("Jump"))//判断什么时候播放跳跃动画
- {
- jump = true;
- animator.SetBool("Jumping", true);
- }
- if (Input.GetKey(KeyCode.S))//判断什么时候播放爬行动画
- {
- crouch = true;
- }else
- {
- crouch = false;
- }
- animator.SetBool("Crouching", crouch);
- }
- //结合CharacterController2D脚本,检测是否在地面
- public void OnLanding()
- {
- jump = false;
- animator.SetBool("Jumping", false);//判断何时停止跳跃
- }
-
- void FixedUpdate()
- {
- cc.Move(move, jump);
- }
- }
参考视频链接: