请选择 进入手机版 | 继续访问电脑版

查看: 16808|回复: 111

[原创] 使用Unity 2D制作简单的UFO游戏

  [复制链接]

845

主题

1484

帖子

1万

贡献

管理员

Rank: 9Rank: 9Rank: 9

积分
19165
QQ
发表于 2016-6-21 02:38:57 | 显示全部楼层 |阅读模式
这篇教程将教大家使用Unity 2D功能制作一个非常简单的UFO游戏,适合Unity初学者以及对Unity 2D不甚熟悉的开发者们。

第一步 新建项目设置场景
首先下载项目所需的资源,或者在Asset Store中下载Unity官方的2D UFO Tutorial。

01.jpg

新建2D项目,在Assets文件夹下新建三个文件夹:Prefabs、Scripts、Scenes。将下载的资源导入项目,会看到Sprites文件夹。将Sprites文件夹下的Background和UFO图片拖拽至层级视图(Hierarchy),将UFO重命名为Player。如下:

02.jpg

依次点击菜单项Edit > Project Settings > Tags and Layers,新建三个Sorting Layer分别命名为Background、Pickups和Players,然后设置各Sprite的Sorting Layer。

03.jpg

将Player的Scale设为(0.75, 0.75, 0),如下:

04.jpg

将Main Camera的Size设为16.5,背景颜色设为RGB(32, 32, 32),如下:

05.jpg

将场景保存到新建的Scenes文件夹下,任意命名即可,本例中命名为Main。

第二步 添加控制主角的脚本
首先为Player游戏对象添加Rigibody 2D组件。然后新建脚本CompletePlayerController
用于控制Player对象,脚本代码如下:

[C#] 纯文本查看 复制代码
using UnityEngine;
using System.Collections;

//Adding this allows us to access members of the UI namespace including Text.
using UnityEngine.UI;

public class CompletePlayerController : MonoBehaviour {

        public float speed;                                //Floating point variable to store the player's movement speed.
        public Text countText;                        //Store a reference to the UI Text component which will display the number of pickups collected.
        public Text winText;                        //Store a reference to the UI Text component which will display the 'You win' message.

        private Rigidbody2D rb2d;                //Store a reference to the Rigidbody2D component required to use 2D Physics.
        private int count;                                //Integer to store the number of pickups collected so far.

        // Use this for initialization
        void Start()
        {
                //Get and store a reference to the Rigidbody2D component so that we can access it.
                rb2d = GetComponent<Rigidbody2D> ();

                //Initialize count to zero.
                count = 0;

                //Initialze winText to a blank string since we haven't won yet at beginning.
                winText.text = "";

                //Call our SetCountText function which will update the text with the current value for count.
                SetCountText ();
        }

        //FixedUpdate is called at a fixed interval and is independent of frame rate. Put physics code here.
        void FixedUpdate()
        {
                //Store the current horizontal input in the float moveHorizontal.
                float moveHorizontal = Input.GetAxis ("Horizontal");

                //Store the current vertical input in the float moveVertical.
                float moveVertical = Input.GetAxis ("Vertical");

                //Use the two store floats to create a new Vector2 variable movement.
                Vector2 movement = new Vector2 (moveHorizontal, moveVertical);

                //Call the AddForce function of our Rigidbody2D rb2d supplying movement multiplied by speed to move our player.
                rb2d.AddForce (movement * speed);
        }

        //OnTriggerEnter2D is called whenever this object overlaps with a trigger collider.
        void OnTriggerEnter2D(Collider2D other) 
        {
                //Check the provided Collider2D parameter other to see if it is tagged "PickUp", if it is...
                if (other.gameObject.CompareTag ("PickUp")) 
                {
                        //... then set the other object we just collided with to inactive.
                        other.gameObject.SetActive(false);
                        
                        //Add one to the current value of our count variable.
                        count = count + 1;
                        
                        //Update the currently displayed count by calling the SetCountText function.
                        SetCountText ();
                }
                

        }

        //This function updates the text displaying the number of objects we've collected and displays our victory message if we've collected all of them.
        void SetCountText()
        {
                //Set the text property of our our countText object to "Count: " followed by the number stored in our count variable.
                countText.text = "Count: " + count.ToString ();

                //Check if we've collected all 12 pickups. If we have...
                if (count >= 12)
                        //... then set the text property of our winText object to "You win!"
                        winText.text = "You win!";
        }
}


依次点击Edit > Project Settings > Input设置控制键,如下:

06.jpg

将Player对象的Rigibody 2D组件的Gravity Scale属性设为0以防止Player向下坠落,并将PlayerController脚本的Speed属性设为10。

第三步 添加碰撞
为Player添加Circle Collider 2D组件并将Radius属性设为2.15,如下:

07.jpg

接下来为背景添加碰撞体,让玩家不要跑出墙壁。为背景边框添加4个Box Collider 2D组件,各组件属性设置如下:

08.jpg


第四步 让摄像机跟随主角
新建脚本CompleteCameraController绑定到Main Camera上,用于控制相机跟随主角移动。脚本代码如下:

[C#] 纯文本查看 复制代码
using UnityEngine;
using System.Collections;

public class CompleteCameraController : MonoBehaviour {

        public GameObject player;                //Public variable to store a reference to the player game object


        private Vector3 offset;                        //Private variable to store the offset distance between the player and camera

        // Use this for initialization
        void Start () 
        {
                //Calculate and store the offset value by getting the distance between the player's position and camera's position.
                offset = transform.position - player.transform.position;
        }
        
        // LateUpdate is called after Update each frame
        void LateUpdate () 
        {
                // Set the position of the camera's transform to be the same as the player's, but offset by the calculated offset distance.
                transform.position = player.transform.position + offset;
        }
}

将Player游戏对象赋给CameraController脚本的player字段。

第五步 设置宝石
将Sprites文件夹下的Pickup图片拖拽至层级视图,将其Sorting Layer设为Pickup并添加Circle Collider 2D组件。然后新建脚本CompleteRotator用于旋转宝石,脚本代码如下:

[C#] 纯文本查看 复制代码
using UnityEngine;
using System.Collections;

public class CompleteRotator : MonoBehaviour {

        //Update is called every frame
        void Update () 
        {
                //Rotate thet transform of the game object this is attached to by 45 degrees, taking into account the time elapsed since last frame.
                transform.Rotate (new Vector3 (0, 0, 45) * Time.deltaTime);
        }
}

将该游戏对象拖拽至项目视图(Project)的Prefabs文件夹下存为预设体,在层级视图复制出11个宝石对象。然后在层级视图新建GameObject命名为Pickups,并将这12个对象均拖至Pickups下,分别设置合适的位置,如下图:

09.jpg

将Pickup预设体的Tag设为PickUp,并将所有Pickup对象的Circle Collider 2D组件的isTrigger属性勾选上:

10.jpg


第六步 添加UI
右键点击层级视图,在弹出菜单中选择UI > Text新建文本,层级视图中除了Text外还会添加Canvas和EventSystem组件。将新建的Text命名为CountText,在检视面板中打开Rect Transform的锚点设置面板后按下Shift+Alt/Option键点选左上角,让Text自动吸附到界面左上角并选择合适的文本颜色,如下图:

15.gif

再次新建Text命名为WinText,将字体大小设为24,对齐位置设为中间并选择合适的颜色,如下图:

12.jpg

最后,将刚才新建的两个Text分别赋给PlayerController脚本的CountText及WinText字段,如下图:

13.jpg

到此就大功告成了,最后运行效果如下:

18.gif

很简单对吧,赶紧下载素材开始自己动手制作吧!(回复该帖下载完整工程案例)

游客,如果您要查看本帖隐藏内容请回复

0

主题

1

帖子

10

贡献

初级UU族—1级

Rank: 1

积分
10
发表于 2016-6-21 10:33:43 | 显示全部楼层
支持你的帖子!!!

0

主题

14

帖子

270

贡献

初级UU族—3级

Rank: 3Rank: 3

积分
270
QQ
发表于 2016-6-21 11:16:09 | 显示全部楼层
学习学习

0

主题

2

帖子

25

贡献

初级UU族—1级

Rank: 1

积分
25
发表于 2016-6-21 14:21:53 | 显示全部楼层
学习学习

0

主题

2

帖子

15

贡献

初级UU族—1级

Rank: 1

积分
15
发表于 2016-6-21 14:53:52 | 显示全部楼层
学习学习

0

主题

27

帖子

305

贡献

初级UU族—3级

Rank: 3Rank: 3

积分
305
发表于 2016-6-22 01:56:10 | 显示全部楼层
学习一下

0

主题

7

帖子

85

贡献

初级UU族—2级

Rank: 2

积分
85
发表于 2016-6-22 05:43:03 | 显示全部楼层
谢谢分享!!!!!

0

主题

3

帖子

40

贡献

初级UU族—1级

Rank: 1

积分
40
发表于 2016-6-23 09:11:08 | 显示全部楼层
下载资源

1

主题

3

帖子

65

贡献

初级UU族—2级

Rank: 2

积分
65
发表于 2016-6-23 14:16:19 | 显示全部楼层
这个非常好啊

0

主题

2

帖子

130

贡献

初级UU族—2级

Rank: 2

积分
130
发表于 2016-6-26 15:35:16 | 显示全部楼层
多谢楼主分享

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表