撰写了文章 更新于 2017-08-18 11:01:21
[Unity2D] 横版2D游戏开发实例二
第二部分主要涉及到游戏主场景的构建,人物的静态及动态动画的切换部分。
由于个人对动画的理解还不够深入,现在Unity的动画部分用Dotween插件的比较多,但实际上自带的动画组件已能满足基本需求,这部分暂时就先熟悉一下吧
游戏场景构建
主要包括三个图层,分别是BG背景图层,Character人物图层,Block BG前置图层
背景创建过程和初始载入界面一致,略过不表。新增Block物件,挂载BoxCollider2D
重头戏,添加我们的主人公Unity酱。这里需要注意一下,为了防止人物的动画与实际的Render在位移过程中发生错位,故使用创建空物件,下挂载人物图像的方式进行。动画、脚本、刚体及碰撞均挂载在空物件上。
Animation添加
分别创建静态的Idle动作,跑动动作以及跳跃动作
Idle及跑动不多说,只需要注意开头第一帧和最后一帧保持人物动态一致即可
跳跃的话则需要分解为JumpUp、JumpTop、JumpDown这三段,并在后续的Animator中做组合拼接
人物平行移动
在人物的根物件下添加MoveController脚本,其中左右的移动需要通过Scale的变形来实现人物朝向的不同,代码如下:
void Move(){
float speed=Input.GetAxis("Horizontal")*runSpeed;
body.velocity=new Vector2(speed,body.vlocity.y);//不添加该句则无法将速度传递到刚体物件上
if(speed!=0){
Vector3 scale=sprite.transform.localScale;
scale.x=Mathf.Sign(body.velocity.x)==1f?1f:-1f;//返回物件移动的速度,如果为正则为1,为负则为-1,并传递给等号后面的判断,若为1,则返回1,不为1,则返回-1
sprite.transform.localScale=scale;
}
}
Transform.localScale 局部缩放
Vector3 localScale;
Description
The scale of the transform relative to the parent.
Mathf.Sign
static float Sign(float f);Description
Returns the sign of f.
Return value is 1 when f is positive or zero, -1 when f is negative.
人物静态与移动动画状态切换
在Animator窗口中为Run及Idle动画添加Transition
New Parameters→float Speed,并设置条件,当速度大于0.1及小于0.1时分别做动画状态的切换。注意将Has Exit Time及Fixed Duration 取消,对应时间改为0。对应在MoveController脚本的StateMachine()
添加人物跳跃动画
新增三段Clip,对应JumpUp\JumpTop\JumpDown
Animator面板,右键Create State,重命名为JumpingState,双击进入
如图所示构建动画逻辑。并添加Boolean值Jumping及Ground。当Ground为false,由Idle或Run状态进入JumpingState,当Speed小于0.1或大于0.1时,分别对应从JumpingState切回人物站立不动及跑动状态。
进入JumpState中,DefaultState默认连接JumpUp,Up→Top→Down这三者切换为无缝衔接,ExitTime 0.9,TransitionDuration 0.09,Down→Exit则时间间隔均为0。当Jumping为false时,Entry直接进入JumpDown。
进入MoveController脚本进行编辑,代码如下
bool isJumping=false;
bool isGround=true;
Rigidbody2D body;
void Awake(){
body=GetComponent();
}
void Jump(){
if(Mathf.abs(body.velocity.y)>0.05f){return;}//若是已处于跳跃状态,则按键无效
if(Input.GetButtonDown("Vertical")){
body.AddForce(Vector3.up*jumpHeight);
}
}
//当角色上升时,isGound切换进入JumpState,并进入JumpUp状态。之后播放完Up动画后,自动切换isJumping状态,并执行Top及Down的动画。
void SetJumpState(){
if(body.velocity>0.05f){
isJumping=true;
isGround=false;
}else if(isJumping){
isJumping=false;
}
}
void StateMachine(){
animator.SetFloat("speed",Mathf.Abs(body.velocity.x));
animator.SetBool("Jumping",isJumping);
animator.SetBool("Ground",isGround);
}
//当与地面或者砖块接触时,退出JumpState
void OnCollisionEnter2D(Collision2D col){
if(col.GameObject.tag=="Ground"&&col.contacts[0].normal==Vector2.up){
isGround=true;
}
}
Collision.contacts 接触点
C# ⇒ public ContactPoint[] contacts;Description 描述
The contact points generated by the physics engine.
Every contact contains a contact point, normal and the two colliders that collided (see ContactPoint). From inside OnCollisionStay or OnCollisionEnter you can always be sure that contacts has at least one element.
简单来说,col.contacts[0].normal指的是碰撞体与物件接触的那个点的法线方向。当Unity酱与地面解除,则足部与地面的点的垂直射线方向向上。
注意,Input.GetButtonDown只响应一帧,可用来作为子弹发射或者弹跳的功能,而GetAxis则因为返回的是-1到1的浮点数,可模拟物件移动到停止的缓冲阶段,若要保证随按随停,则可以使用GetAxisRaw。
注意2:若一个动画有Conditions建议取消Has Exit Time,会出现无法及时触发的问题。Has Exit Time就是必须过度的时间,处于这个时间时,是不允许任何对动画的操作的。在JumpTop及JumpDown的Transition中,则需要打开Has Exit Time。
目录
ZombleKingdom 1年前
万有引力之虹 [作者] 1年前
wsedr 1年前
发布
OwenTsai 1年前
betta 1年前
OwenTsai 1年前
万有引力之虹 [作者] 1年前
OwenTsai 1年前
万有引力之虹 [作者] 1年前
发布
xp 1年前
个人觉得可以Ctrl + A, Ctrl + K, Ctrl + F
发布