Untiy2D入门——小狐狸学习笔记01:2D场景角色创建、角色移动、角色动画 - 知乎 (zhihu.com)
Untiy2D入门——小狐狸学习笔记02:镜头追踪、UI、AI敌人、父类控制子类脚本 以及 类的调用 - 知乎 (zhihu.com)
前期懒得写了,摘录知乎上笔记。
自己挑几个point记录一下,回顾用
添加物理:刚体组件 碰撞体组件
创建player记得Add Component,Rigidbody 2D,Box Collider 2D
地图:Tilemap Collider 2D
角色移动
左右
Unity有默认的Horizontal 移动按键
代码
Input.GetAxis("Horizontal"); // 获取Unity默认Horizontal的值,当按left或者a时,返回值为-1~0;不按时为0;按right或者d时,返回值为0~1
返回值的常用于控制移动速度,只需乘一个可控speed来改变物体X的值即可
写好脚本后,将其拖入Player中,并将Player的Rigidbody 2D 组件拖入公共变量中,设置Speed
实现角色左右转向改变:调节Transfrom的Scale的X为正负1
跳跃
public float jumpForce; // 控制跳跃时的力
//【判断是否跳跃】
if (Input.GetButtonDown("Jump")) // 若按下默认Axis里的Jump,只会在按下瞬间执行
{
myRigidbody2D.velocity = new Vector2(myRigidbody2D.velocity.x, jumpForce); // 保持x方向的速度不变,改变y方向的速度
}// 控制跳跃的力
动画
组件:Animator,加上AnimatorController控制动画播放
新建AnimatorController:在Assets中右键新建一个AnimatorController,将其拖到刚才创建的Animator组件中
切换:Animator组件的内部Animation切换面板
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,就是为了可以返回站立动画
}
控制不同动画的切换:跳跃、下落
在Animator中添加3个Bool变量、箭头的触发条件:用于控制是否进行跳跃jump和下落drop动画,以及从drop回归idle的动画
//【判断是否跳跃】
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
}
角色落到地面下落动画变为站立
建立Collider2D变量,用于获取角色的碰撞体
LayerMask变量,用于获取地面物体,这样就可以判断是否碰到了该Layer中的物体(地形)
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
}
}
}
镜头跟踪
Cinemachine,在Hierarchy面板里新建Cinemachine
使镜头固定在一个范围
物品收集
新建2D Object,将Sprite属性改为物品的初始图片
为物品添加动画
为物品添加碰撞体,且勾选 Is Trigger,作为触发器
设置物品的Tag,Tag一般用于在脚本中判断具体的碰撞体
物品收集脚本代码 事件触发函数