Unity3D_(游戏)2D简单游戏制作过程:捕获高空掉落保龄球

 

 

游戏介绍:通过鼠标的左右移动,可以控制帽子的移动,当帽子接到下落的保龄球时,会出现火花效果。没有接到保龄球时,保龄球落到草地上,过10S后会自动消失。

 

实现效果:

 

 

素材+Unity3D源代码:传送门 

 

 

 

实现过程:

 

一、搭建基本场景

 

  创建工程时选择2D正交视角,此时只有一个名为Main Camera的摄像机对象

 

  为了使得游戏对象在场景中的层次不会错乱,可以创建不同的工作层次来管理游戏对象,使2D游戏场景的层次更加分明,游戏对象之间的操作也更加方便

选择菜单栏中的Edit->Project Settings->Tags and Layout命令(或者直接单选编辑器右上方的Layout->Edit Layout),在Inspector视图中,单机Sorting Layouts下的按钮,讲Layer ID 1命名为Background,再次单价Sorting Layout下的按钮,讲Layer ID 2命名为Foreground

 

 

Unity支持所有资源都可以通过以下三种方法进行导入:
1、直接将资源复制到项目文件夹下面的Assets文件中
2、直接将资源拖动到Project视图的Assets文件夹中
3、依次打开菜单栏中的Assets->Import New Asset...进行导入
Unity3D导入资源方法

 

(1)天空

  创建一片天空,用来当做游戏背景的一部分。在场景中创建一个Sprite,依次选择菜单栏中的GameObject->2D Object->Sprite命令,重命名为sky

  设置天空Sprite的纹理、工作层的顺序。在Inspector中将Sprite图片背景改为skySprite,并将Sorting Layout属性值设置为Baclground,Order in Layout属性值设置为0,设置参数如下

 

·Sprite:Sprite的图片信息。
·Color:Sprite的颜色
·Material:Sprite的材质。
·Sorting Layer:Sprite的分类层。单机右侧下拉按钮可以选择或者添加新的分层,层级越靠前,优先级越高,相同情况下后被渲染。
·Order in Layer:Sprite所在层中的顺序。数值越大,优先级越高,相同情况下后被渲染。
Inspector视图中对象Sprite Renderer组件各属性的含义

 

(2)草地

  依次选择菜单栏中的GameObject->2D Object->Sprite命令,在场景中创建一个Sprite,重命名为grass(草地Sprite在工作层顺序要比天空高,这样能将草地显示在前面)

  设置草地Sprite的纹理,工作层的顺序。在Inspector中将Sprite图片背景改为GrassSprite,并将Sorting Layout属性值设置为Baclground,Order in Layout属性值设置为1,设置参数如下

 

 

  此时图片不能填充满地面背景,可以选择多复制些草丛,并依次拖动Sprite,将sky下方背景被草地填充满

  (有必要换可以创建一个空对象来管理游戏背景,依次选择菜单栏中GameObject->Create Empty命令,创建一个空对象,将其命名为Background,将sky和grass对象拖动到Background中,与Background建立父子关系)

 

 

 

二、添加角色和控制

(1)创建Sprite动画

  Unity3D能自动切割Sprite,将一张多纹理的图片切割成多个Sprite,并且这些Sprite将保持在同一个图片文件中,在Project视图中,选中切割图片,在图片的Inspector视图中,将Sprite Mode设置为Multiple,然后单击下面的Sprite Editor按钮,在弹出的Sprite Editor对话框左上角的Slice按钮中单击另一个同名的Slice按钮,最后单击Apple俺就,Sprite图片就会自动切割完成

 

 

  自动切割完成后,Sprite动画就被切割成8长小图,接下来要制作天鹅飞行的动画

  依次选择菜单栏中的GameObject->2D Object->Sprite命令,创建一个Sprite,并改名为swan,在Select Sprite对话框中选择swan_sheet_0,在Inspector视图中将Sorting Layout属性值设置为Background,Order in Layout属性值设置为1,

 

 

  给天鹅Sprite创建一个煽动翅膀的动画

  选中swan,依次选择菜单栏中的Window->Animation命令,在演出的Animation对话框中,单选左侧的按钮,选择Create New Clip,然后在弹出的Create New Aniamtion对话框中选择Assets下方的Animation文件夹,将文件命名为swan,保存

  在Project视图中的Animation文件夹中,会创建出2个swan文件,其中一个是swan动画片段,另一个是swan动画控制器

  以Sprite的变化作为动画帧,在Hierarchy视图中选中swan,依次选择菜单栏中的Window ->Animation命令,在打开的Animation视图中,将Sampke属性值设置为10,然后单击Add Property按钮,在弹出的选择列表中单击Sprite Renderer左侧的播放按钮(必须先将Sampke属性值设置为10)

  将末尾处无用的关键帧删除。在Animation视图中,选中1:00选的关键正右击关闭,在弹出快捷菜单每0.01s创建一个一个帧动画(改变帧动画只需要修改一帧的Inspector下的Animator下的Controller,最后面有参考书籍,这里出问题了可以按照课本上多O(∩_∩)O~)

 

最终预览效果:

 

 

  添加脚本,实现天鹅飞行的效果

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SwanMove : MonoBehaviour {

    //swan的移动速度
    private float moveSpeed = 4;

    // Use this for initialization
    void Start () {
        //设置天鹅的初始位置
        transform.position = new Vector3(22, 3, 0);
    }
    
    // Update is called once per frame
    void Update () {
        if(transform.position.x>-22){
            //天鹅移动
            transform.Translate(Vector3.right * -moveSpeed * Time.deltaTime);
        } else{
            transform.position = new Vector3(22, 3, 0);
        }
    }
}
天鹅飞行脚本:SwanMove

 

  将脚本绑定到天鹅上,播放按钮实现天鹅从左侧飞向右侧

 

 

三、帽子对象

  (1)将HatBackSprite图片拖动到Hierarchy视图中,将其命名为Hat,为了使帽子显示在所有背景的前方,将Sorting Layout属性值设置为Foreground,Order in Layout的属性值为0,

  (2)在Project视图中的Sprite文件夹中,将Hierarchy拖动到Hat上,建立父子关系,将Sorting Layout属性值设置为Foreground,Order in Layout属性值为2,将帽子后半部分的Order in Layer属性值为0,前半部分的Order in Layer属性值为2,前半部分的Order in Layer属性值设置为2,目的是使得保龄球Sprite的优先级在两者之间,实现保龄球在被帽子接住候达到进入帽子的视觉效果

 

 

  (3)创建保龄球Sprite,改名为BowlingBall,在BowlingBall的Inspector视图中,将Sorting Layout值设置为Foreground,Order in Layout的值设置为1

  (4)为保龄球Sprite添加刚体,使其有自由下落的效果,并添加碰撞刚体,使其与别的碰撞体之间有碰撞的效果。

在Hierarchy视图中选中BallingBall,依次选择菜单栏中的Component->Physics 2D->Rigidbody 2D(2D刚体)命令,给BowlingBall添加一个Rigidbody 2D组件。再一次选择菜单栏中的Compent->Physics 2D->Collider 2D(2D圆形碰撞体命令),给BowlingBall添加一个Circle Collider 2D组件

 

 

(5)添加脚本,实现保龄球自由下落

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameController : MonoBehaviour {

    //BowlingBall
    public GameObject ball;
    private float maxWidth;
    private float time = 2;
    private GameObject newball;

    // Use this for initialization
    void Start () {
        //将屏幕的宽度转换成世界坐标
        Vector3 screenPos = new Vector3(Screen.width, 0, 0);
        Vector3 moveWidth = Camera.main.ScreenToWorldPoint(screenPos);
        //获取保龄球自身的宽度
        float ballWidth = ball.GetComponent<Renderer>().bounds.extents.x;
        //计算保龄球实例化位置的宽度
        maxWidth = moveWidth.x - ballWidth;
    }
    
    // Update is called once per frame
    void FixedUpdate () {
        time -= Time.deltaTime;
        if(time<0)
        {
            //产生一个随机数,代表实例化下一个保龄球所需要的时间
            time = Random.Range(1.6f,1.8f);
            //在保龄球实例化位置的宽度内产生一个随机数,来控制实例化保龄球的位置
            float posX = Random.Range(-maxWidth, maxWidth);
            Vector3 spawnPosition = new Vector3(posX,transform.position.y,0);
            //实例化保龄球,10秒后销毁
            newball = (GameObject)Instantiate(ball, spawnPosition, Quaternion.identity);
            Destroy(newball,10);
        }
    }
}
实现保龄球自由下落

 

(6)将脚本绑定到保龄球上

 

 

(7)创建一个C#脚本,用来控制帽子的移动

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class HatController : MonoBehaviour {

    public GameObject effect;
    private Vector3 rawPosition;
    private Vector3 hatPosition;
    private float maxWidth;

    // Use this for initialization
    void Start () {
        //将屏幕的宽度转换成世界坐标
        Vector3 screenPos = new Vector3(Screen.width, 0, 0);
        Vector3 moveWidth = Camera.main.ScreenToWorldPoint(screenPos);
        //计算帽子的宽度
        float hatWidth = GetComponent<Renderer>().bounds.extents.x;
        //获得帽子的初始位置
        hatPosition = transform.position;
        //计算帽子的移动速度
        maxWidth = moveWidth.x - hatWidth;
    }
    
    // Update is called once per frame
    void FixedUpdate () {
        //将鼠标的屏幕位置转换成世界坐标
        rawPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        //设置帽子将要移动的位置,帽子移动范围控制
        hatPosition = new Vector3(rawPosition.x, hatPosition.y, 0);
        hatPosition.x = Mathf.Clamp(hatPosition.x,-maxWidth,maxWidth);
        //帽子移动
        GetComponent<Rigidbody2D>().MovePosition(hatPosition);
    }

 
}

(这个脚本挺好用的,不采用折叠)

 

  为帽子添加刚体并开启is Kinematic(是否运动学,开启的话 游戏对象不会受到物理引擎的影响只能通过Transfrom(几何变化组件)属性来对其操作)

在Hierarchy视图中选中Hat,依次选择菜单栏中的Component->Physics2D Rigidbody 2D命令,然后在Hat的Inspector视图中,将Gravity Scale设置为0(防止Hat下落),并选中Fixed Angle属性复选框

 

  创建2D物理阻挡

  给帽子添加碰撞体,使其与保龄球可以发生碰撞。在Hierarchy视图中选种Hat下的HatForntSprite,依次选择菜单栏中的Component->Physics 2D->EdgeCollider 2D(2D边缘碰撞)命令,为HatFrontSprite添加一个Edge Collider 2D组件,然后在Inspector视图中单击Edit Collider左侧按钮,在Scene视图中编辑Edge Collider 2D,使得Edge Collider 2D组件包裹住Hat

(当小球碰撞到这些绿色的线条就会被弹开)

 

 

  给帽子添加触发器,用来判断保龄球是否进入帽子,按照上一步步骤,给Hat添加一个Edge Collider 2D主键,使得Edge Collider 2D在Hat底部呈一条直线

 

 

 添加保龄球进入触发器后删除保龄球的代码,这样帽子可以持续接取保龄球

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class HatController : MonoBehaviour {

    public GameObject effect;
    private Vector3 rawPosition;
    private Vector3 hatPosition;
    private float maxWidth;

    // Use this for initialization
    void Start () {
        //将屏幕的宽度转换成世界坐标
        Vector3 screenPos = new Vector3(Screen.width, 0, 0);
        Vector3 moveWidth = Camera.main.ScreenToWorldPoint(screenPos);
        //计算帽子的宽度
        float hatWidth = GetComponent<Renderer>().bounds.extents.x;
        //获得帽子的初始位置
        hatPosition = transform.position;
        //计算帽子的移动速度
        maxWidth = moveWidth.x - hatWidth;
    }
    
    // Update is called once per frame
    void FixedUpdate () {
        //将鼠标的屏幕位置转换成世界坐标
        rawPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        //设置帽子将要移动的位置,帽子移动范围控制
        hatPosition = new Vector3(rawPosition.x, hatPosition.y, 0);
        hatPosition.x = Mathf.Clamp(hatPosition.x,-maxWidth,maxWidth);
        //帽子移动
        GetComponent<Rigidbody2D>().MovePosition(hatPosition);
    }

    //有碰撞物体进入触发器时触发
    private void OnTriggerEnter2D(Collider2D col)
    {
        GameObject neweffect = (GameObject)Instantiate(effect, transform.position, effect.transform.rotation);
        neweffect.transform.parent = transform;
        Destroy(col.gameObject);
        //删除该碰撞的物体
        Destroy(col.gameObject,1.0f);
    }
}
接取保龄球:HatController

 

  在草地下方添加一个碰撞体,用来阻挡保龄球继续下落。

  依次选择菜单栏中的GameObject->Create Empty命令,创建一个空对象,将其命名为ground,选中ground,依次选择菜单栏中的Component->Physics 2D->Box Collider 2D命令,最后在ground的Inspector视图中,调整ground的Offset和Size属性值

 

 

  当没有接住保龄球,保龄球在草地上停留10S后会自动消失

 

到此时就已经实现游戏基本功能

 

 

四、添加2D游戏效果

 

  为了鼓励玩家操作,让玩家更有参与感,可以给当玩家接收到天空落下的求就会出现火花的粒子特效,下面来实现最终游戏的效果

 

  首先导入火花粒子资源包

  依次选择菜单栏中的Asset->Import Package->Custom Package命令,导入Effect,unitypackage资源包进入到工程中,选中Effect文件夹下的Effect粒子预设体,将Particle System组件中的Renderer属性值下的Sorting Layout设置为Foreground,Order in Layout设置为1

 

 

  点击Hat Controller(Script)组件下的Effect按钮,在弹出的Select GameObject对话框中选择Effects

 

 

  此时点击播放按钮,就可以实现通过鼠标的左右移动,可以控制Hat的移动,当Hat接到下落的保龄球时,会出现火花效果

 

  End! 

 

 

 

 

 

参考书籍《Unity 5.X从入门到精通》

posted @ 2018-07-15 22:35  Cynical丶Gary  阅读(6004)  评论(0编辑  收藏  举报