Unity 2D Movement 物体移动案例
导入工程
可通过Unity Asset Store导入或者自行下载导入Sunny Land
绘制地图
-
制作Tile Palette
通过Window > 2D > Tile Palette调整面板
新建Palette -
导入素材:将Sunnyland/artwork/Environment/titleset-sliced拖入Tile Palette面板
最后导入效果如图,如其他画板功能类似,左键单击(长按)选取,然后绘制。
注:如果导入素材后绘制像素过小,请检查素材Pixels Per Unit值的大小(本工程为16)
-
开始绘制
在场景中添加TileMap(右键2D Object > Tilemap),即可利用Tile palette中的功能在场景中进行绘制。
注:如果有多个Tilemap,可以通过在Tile palette中激活需要操作的TileMap。
在绘制完后我们可通过组件Tilemap Collider 2D快速地添加碰撞盒
前景:草、植物等
ground层:地面等
背景:墙、柱子等(通过改变Transform.Position.Z的值来改变前后关系)
ground层
人物制作
首先简单地导入Sunnyland\artwork\Sprites\player\idle\player-idle-1.png到场景中
为Player添加刚体及碰撞盒
Character Controller
包含Object受力、速度、状态判断的变量
函数:
-
Move(float move, bool crouch, bool jump)
move:横向移动量
-
Flip() —— 人物转向
using UnityEngine;
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 = Vector3.zero;
private void Awake() {
m_Rigidbody2D = GetComponent<Rigidbody2D>();
}
private void FixedUpdate() {
m_Grounded = false;
// The player is grounded if a circlecast to the groundcheck position hits anything designated as ground
// This can be done using layers instead but Sample Assets will not overwrite your project settings.
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;
}
}
public void Move(float move, bool crouch, bool jump) {
// If crouching, check to see if the character can stand up
if (!crouch) {
// If the character has a ceiling preventing them from standing up, keep them crouching
if (Physics2D.OverlapCircle(m_CeilingCheck.position, k_CeilingRadius, m_WhatIsGround)) {
crouch = true;
}
}
//only control the player if grounded or airControl is turned on
if (m_Grounded || m_AirControl) {
// If crouching
if (crouch) {
// Reduce the speed by the crouchSpeed multiplier
move *= m_CrouchSpeed;
// Disable one of the colliders when crouching
if (m_CrouchDisableCollider != null)
m_CrouchDisableCollider.enabled = false;
} else {
// Enable the collider when not crouching
if (m_CrouchDisableCollider != null)
m_CrouchDisableCollider.enabled = true;
}
// Move the character by finding the target velocity
Vector3 targetVelocity = new Vector2(move * 10f, m_Rigidbody2D.velocity.y);
// And then smoothing it out and applying it to the character
m_Rigidbody2D.velocity = Vector3.SmoothDamp(m_Rigidbody2D.velocity, targetVelocity, ref velocity, m_MovementSmoothing);
// If the input is moving the player right and the player is facing left...
if (move > 0 && !m_FacingRight) {
// ... flip the player.
Flip();
}
// Otherwise if the input is moving the player left and the player is facing right...
else if (move < 0 && m_FacingRight) {
// ... flip the player.
Flip();
}
}
// If the player should jump...
if (m_Grounded && jump) {
// Add a vertical force to the player.
m_Grounded = false;
m_Rigidbody2D.AddForce(new Vector2(0f, m_JumpForce));
}
}
private void Flip() {
// Switch the way the player is labelled as facing.
m_FacingRight = !m_FacingRight;
// Multiply the player's x local scale by -1.
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}
Player Move Controller
Input.GetAxisRaw("Horizontal") —— 获取横向移动量,x的正方向移动为1,x的负方向移动-1,站立不动为0
Input.GetButtonDown("Jump") —— 判断按下"Jump"的指令
Edit > Project Settings > Input Manager设定Input系统
例如:Jump通过space键触发
我们需要添加Crouch判定,触发爬行行为
using UnityEngine;
public class PlayerMoveController : MonoBehaviour {
private CharacterController2D cc;
private float move = 0f;
private bool jump = false;
private bool crouch = false;
private void Awake() {
cc = GetComponent<CharacterController2D>();
}
// Update is called once per frame
void Update() {
move = Input.GetAxisRaw("Horizontal");
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, crouch, jump);
jump = false;
}
}
其他设置
- Player脚本相关设置
也可以通过Rigidbody调整物体的重力因素等,如Gravity Scale()、Collision Detection(刚体的碰撞检测模式)。
-
设置Collider的Material(减少摩擦)
在project面板中右键 > Create > Physics Material 2D,将Friction参数设置为0。
拖动该material到collider上。