Unity2DAnimation动画案例Unity 2D Animation 案例
Animator Controller
在project⾯板中右键 > create > Animator Controller创建动画控制器并将动画控制器绑定到Player上。
Animation制作
1. Windows > Animation > Animation打开动画编辑器,选中Player后点击Create创建.anim
2. 将Sprites添加到帧动画中。可以依次添加crouch,idle,jump,run动画
注:原素材的Pixels Per Unit的值为100,可以修改为16
动画控制脚本
run状态
1. 建⽴player_idle与player_run的联系
在Parameters⾯板添加float变量
单击连线在inspector⾯板的
①去除动画退出时间
②Conditi添加条件变量
player_idle → player_run
player_run → player_idle
float up2. 变量控制(脚本)
using UnityEngine;
public class PlayerMoveController : MonoBehaviour {
private CharacterController2D cc;
private Animator animator;
[SerializeField]
private float runSpeed = 40;
private float move = 0f;
private bool jump = false;
private bool crouch = false;
private void Awake() {
cc = GetComponent<CharacterController2D>();
animator = GetComponent<Animator>();
}
// Update is called once per frame
void Update() {
move = Input.GetAxisRaw("Horizontal");
/
/取move的绝对值(即只存在1与0两个值),再结合Conditions判断即可切换idle与run之间的状态  animator.SetFloat("move", Mathf.Abs(move));
if (Input.GetButtonDown("Jump")) {
jump = true;
}
if (Input.GetButtonDown("Crouch")) {
crouch = true;
} else if (Input.GetButtonUp("Crouch")) {
crouch = false;
}
}
private void FixedUpdate() {
cc.Move(move * runSpeed * Time.fixedDeltaTime, crouch, jump);
jump = false;
}
}
其他状态
其他状态与run状态相似,这⾥仅给出思路,供读者参考。
1. jump (判断条件)
Any State → jump (isJumping = true)
jump → idle (isJumping = false; move < 1)
jump → run(isJumping = false; move > 0)
2. crouch (判断条件)
crouch→ idle (isCrouching = true)
crouch→ run(isCrouching = true)
idle → crouch(isCrouching = false)
run→ crouch(isCrouching = false)
完整代码如下:
CharacterController2D.cs
using UnityEngine;
using UnityEngine.Events;
public class CharacterController2D : MonoBehaviour {
[SerializeField] private float m_JumpForce = 400f;                          // Amount of force added when the player jumps.
[Range(0, 1)] [SerializeField] private float m_CrouchSpeed = .36f;          // Amount of maxSpeed applied to crouching movement. 1 = 100% [Range(0, .3f)] [SerializeField] private float m_MovementSmoothing = .05f;  // How much to smooth out the movement
[SerializeField] private bool m_AirControl = false;                        // Whether or not a player can steer while jumping;
[SerializeField] private LayerMask m_WhatIsGround;                          // A mask determining what is ground to the character
[SerializeField] private Transform m_GroundCheck;                          // A position marking where to check if the player is grounded.
[SerializeField] private Transform m_CeilingCheck;                          // A position marking where to check for ceilings
[SerializeField] private Collider2D m_CrouchDisableCollider;                // A collider that will be disabled when crouching
const float k_GroundedRadius = .2f; // Radius of the overlap circle to determine if grounded
private bool m_Grounded;            // Whether or not the player is grounded.
const float k_CeilingRadius = .2f; // Radius of the overlap circle to determine if the player can stand up
private Rigidbody2D m_Rigidbody2D;
private bool m_FacingRight = true;  // For determining which way the player is currently facing.
private Vector3 velocity = ;
public bool m_wasCrouching = false;
private PlayerMoveController mPlayerMoveController;
private void Awake() {
m_Rigidbody2D = GetComponent<Rigidbody2D>();
mPlayerMoveController = GetComponent<PlayerMoveController>();
}
private void FixedUpdate() {
bool wasGrounded = m_Grounded;
m_Grounded = false;
//ground检测
Collider2D[] colliders = Physics2D.OverlapCircleAll(m_GroundCheck.position, k_GroundedRadius, m_WhatIsGround);
for (int i = 0; i < colliders.Length; i++) {
if (colliders[i].gameObject != gameObject) {
m_Grounded = true;
if (!wasGrounded)
//OnLandEvent.Invoke();
mPlayerMoveController.OnLanding();
}
}
}
public void Move(float move, bool crouch, bool jump) {
//对Crouch⾏为的检测,如果Crouch键未触发却处于必须Crouch的环境中,那么需要保持Crouch=true;
if (!crouch) {
if (Physics2D.OverlapCircle(m_CeilingCheck.position, k_CeilingRadius, m_WhatIsGround)) {
crouch = true;
Debug.Log(m_wasCrouching);
}
}
if (m_Grounded || m_AirControl) {
if (crouch) {
if (!m_wasCrouching) {
m_wasCrouching = true;
mPlayerMoveController.OnCrouching(true);
}
// 减速
move *= m_CrouchSpeed;
if (m_CrouchDisableCollider != null)
abled = false;
} else {
if (m_CrouchDisableCollider != null)
abled = true;
if (m_wasCrouching) {
m_wasCrouching = false;
mPlayerMoveController.OnCrouching(false);
}
}
// Move the character by finding the target velocity
Vector3 targetVelocity = new Vector2(move * 10f, m_Rigidbody2D.velocity.y);
m_Rigidbody2D.velocity = Vector3.SmoothDamp(m_Rigidbody2D.velocity, targetVelocity, ref velocity, m_MovementSmoothing);  // 转向
if (move > 0 && !m_FacingRight) {
Flip();
}
else if (move < 0 && m_FacingRight) {
Flip();
}
}
//跳跃
if (m_Grounded && jump) {
m_Grounded = false;
m_Rigidbody2D.AddForce(new Vector2(0f, m_JumpForce));
}
}
private void Flip() {
m_FacingRight = !m_FacingRight;
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
private void OnDrawGizmos() {
Gizmos.DrawWireSphere(m_GroundCheck.position, k_GroundedRadius);
}
}
PlayerMoveController.cs
using UnityEngine;
public class PlayerMoveController : MonoBehaviour {
private CharacterController2D cc;
private Animator animator;
[SerializeField]
private float runSpeed = 40;
private float move = 0f;
private bool jump = false;
private bool crouch = false;
private Rigidbody2D rb2;
private void Awake() {
cc = GetComponent<CharacterController2D>();
animator = GetComponent<Animator>();
rb2 = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update() {
move = Input.GetAxisRaw("Horizontal");
animator.SetFloat("move", Mathf.Abs(move));
if (Input.GetButtonDown("Jump")) {
jump = true;
animator.SetBool("isJump", true);
}
if (Input.GetButtonDown("Crouch")) {
crouch = true;
} else if (Input.GetButtonUp("Crouch")) {
crouch = false;
}
}
private void FixedUpdate() {
cc.Move(move * runSpeed * Time.fixedDeltaTime, crouch, jump);
jump = false;
}
public void OnLanding() {
animator.SetBool("isJump", false);
}
public void OnCrouching(bool wasCrouching) {
Debug.Log(wasCrouching);
animator.SetBool("isCrouching", wasCrouching);
}
}
演⽰
补充
部分问题
有可能你的⼈物会遇到卡在碰撞盒边缘的问题
可能是因为Tile Collider的多个碰撞盒拼接,如果锁住⼈物z轴,由于unity的浮点计算问题,导致collider之间并不是绝对⽔平的。解决办法:为Tile map添加Composite Collider 2D同时将Rigidbody.BodyType设为Static,
TileCollider2D.UsedByComposite设为true

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。