unity官网有个unity2D的UFO Game,是让新手学习用的。我将它改造成一个新的、简单的小游戏——《UFO likes Cakes》。枯燥的学习让我感觉很无趣,所以做出一个游戏才会给我注入动力。本想自己从头说起,但是感觉自己用图文结合的博客和unity官网上给的教程差远了,所以我觉得还是只讲自己后续是怎样做的吧。以下是unity官网上给的教程,讲的特别好。
https://unity3d.com/cn/learn/tutorials/s/2d-ufo-tutorial、
一、首界面
把它本身的初始UI给去了,制作一个自己的UI(可能很难看),添加一些游戏说明
首界面我添加了两个功能,一个是让界面上的UFO在这个按钮上来回走动,这样更生动,另一个是添加按钮事件,加载下一场景。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class UFOMove : MonoBehaviour
{
public RectTransform btnImg;
private RectTransform btnUFO;
public GameObject btn;
private float speed = 70;
private float speedRotate = 180;
private bool right = true;
private float center;
void Start()
{
center = transform.position.x;
btnUFO = GetComponent<RectTransform>();
btn.GetComponent<Button>().onClick.AddListener(ChangeScene);
Debug.Log("length:" + btnImg.sizeDelta.x);
}
void Update()
{
gameObject.transform.Rotate(new Vector3(0, 0, -speedRotate * Time.deltaTime));
float widthBtn = btnImg.sizeDelta.x / 2;
float widthUFO = btnUFO.sizeDelta.x / 2;
if (right && transform.position.x + widthUFO - center < widthBtn)
{
gameObject.transform.Translate(new Vector3(Time.deltaTime * speed, 0, 0), Space.World);
}
else if (right && transform.position.x + widthUFO - center > widthBtn)
{
right = false;
}
if (!right && center - (transform.position.x - widthUFO) < widthBtn)
{
gameObject.transform.Translate(new Vector3(-Time.deltaTime * speed, 0, 0), Space.World);
}
else if (!right && center - (transform.position.x - widthUFO) > widthBtn)
{
right = true;
}
}
public void ChangeScene()
{
SceneManager.LoadScene("Main", LoadSceneMode.Single);
}
}
为了更生动,我让UFO在走动的同时转起来。通过Rect Transform组件下的sizeDelta属性,可获取按钮和UFO的宽和高。这样,在开始时记录下UFO的起点位置,就能很容易的控制UFO在指定按钮区域内转动了。
顺便一提,首界面添加一个背景音乐会更赞。
添加背景音乐的方法很简单,首先将一个.mp3文件拖进来,然后在场景中的Main Camera物体上添加一个Audio Listener,再把.mp3文件拖到Audio Source组件下的AudioClip,结果成这样:
根据个人喜好将属性修改。
二、游戏界面
原游戏是吃小黄块,吃玩就没了。我把小黄块设置成障碍物,只能吃蛋糕。并且这些蛋糕都具有不同的能力:右上角蛋糕能让UFO变大,左上角蛋糕能让UFO加速,右下角蛋糕(我怎么看不见?神奇的魔法蛋糕是可以隐藏的!)可以让UFO隐身。只有吃掉所有的蛋糕后才可以获得胜利。
如果认真看了UFO Game教程,你可以很轻松的将小黄块设置为“障碍物”,蛋糕可以被“吃掉”,只要看清是否需要勾选is Trigger即可。
为了增加游戏的逼格,再给它加一个背景音乐吧。
贴一下源码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//控制摄像机追随UFO
public class CameraController : MonoBehaviour {
public GameObject player;
private Vector3 offset;
void Start()
{
offset = transform.position - player.transform.position;
}
//Player move first,than camera follow then Player,so need LateUpdate
void LateUpdate()
{
/*player position will change a offset every frame,so the camera just add the offset.
the offset is meaning the player'position in privious frame and this frame
*/
transform.position = player.transform.position + offset;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//控制Pickup旋转,专门写一个类很伤,应该放到UFO控制类中的
public class RotatePickup : MonoBehaviour
{
void Update()
{
transform.Rotate(new Vector3(0, 0, 45) * Time.deltaTime);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
//UFO控制类
public class PlayerController : MonoBehaviour
{
//获胜后的Next按钮
public GameObject next;
//放大、缩小的速度
private float scaleSpeed = 0.3f;
//是否变大
private bool big = false;
//是否变小
private bool small = false;
//是否隐藏
private bool hide = false;
//是否加速
private bool accelerate = false;
//移动速度
private float speed;
private Rigidbody2D rg2d;
private Vector3 scale;
//给Next点击计数
private int countClick;
//胜利后的时间
private float winTime;
// [HideInInspector]
private int cakes;
void Start()
{
speed = 10;
cakes = 0;
countClick = 0;
winTime = 0;
rg2d = GetComponent<Rigidbody2D>();
scale = transform.localScale;
PlayerPrefs.SetInt("win", 0);
}
void Update()
{
if (big && transform.localScale.x < 1.2f)
{
scale.x += Time.deltaTime * scaleSpeed;
scale.y += Time.deltaTime * scaleSpeed;
transform.localScale = scale;
}
if (small && transform.localScale.x > 0.3f)
{
scale.x -= Time.deltaTime * scaleSpeed;
scale.y -= Time.deltaTime * scaleSpeed;
transform.localScale = scale;
}
if (hide)
{
Hide();
}
if (accelerate)
{
speed *= 20;
accelerate = false;
}
}
void FixedUpdate()
{
//给UFO添加力
float horizontal = Input.GetAxis("Horizontal");
float vertical = Input.GetAxis("Vertical");
Vector2 force = new Vector2(horizontal, vertical);
rg2d.AddForce(force * speed);
//获胜判断
if (cakes == 4 && PlayerPrefs.GetInt("win", 1) == 0)
{
Debug.Log("win");
winTime = Time.realtimeSinceStartup;
cakes = 0;
}
//5秒后出现Next,这是彩蛋
if(winTime != 0 && Time.realtimeSinceStartup - winTime > 5f)
{
Debug.Log("show next");
winTime = 0;
next.GetComponent<Renderer>().enabled = true;
PlayerPrefs.SetInt("win", 1);
}
//添加重力感应,保证再手机和Unity上都能玩
float gravityX = Input.acceleration.x;
float gravityY = Input.acceleration.y;
Vector2 gravity = new Vector2(gravityX, gravityY);
rg2d.AddForce(gravity * speed);
}
void OnTriggerEnter2D(Collider2D other)
{
//碰撞检测,吃蛋糕
if (other.CompareTag("Cake1"))
{
other.gameObject.SetActive(false);
SetState("cake1");
cakes += 1;
Debug.Log("big:" + big);
}
if (other.CompareTag("Cake2"))
{
other.gameObject.SetActive(false);
SetState("cake2");
cakes += 1;
Debug.Log("small:" + small);
}
if (other.CompareTag("Cake3"))
{
other.gameObject.SetActive(false);
SetState("cake3");
cakes += 1;
Debug.Log("hide:" + hide);
}
if (other.CompareTag("Cake4"))
{
other.gameObject.SetActive(false);
SetState("cake4");
cakes += 1;
Debug.Log("accelerate:" + accelerate);
}
}
//通过Renderer组件来设置蛋糕和UFO的隐藏、显示功能
private void Show()
{
gameObject.GetComponent<Renderer>().enabled = true;
}
private void Hide()
{
gameObject.GetComponent<Renderer>().enabled = false;
}
//设置状态,吃到一个蛋糕后,UFO之前的状态先归零,再根据蛋糕的功能获得能力
private void SetState(string cake)
{
if (big && !cake.Equals("cake1"))
{
transform.localScale = new Vector3(0.75f, 0.75f, 1);
}
if (small && !cake.Equals("cake2"))
{
transform.localScale = new Vector3(0.75f, 0.75f, 1);
}
if (hide && !cake.Equals("cake3"))
{
Show();
}
if (!accelerate && !cake.Equals("cake4"))
{
speed = 10;
}
big = false;
small = false;
hide = false;
accelerate = false;
switch (cake)
{
case "cake1":
big = true;
break;
case "cake2":
small = true;
break;
case "cake3":
hide = true;
break;
case "cake4":
accelerate = true;
break;
case "0":
break;
}
}
//加载结束的UI
public void LoadEndUI()
{
Debug.Log("PlayerController.cakes:" + cakes);
countClick++;
if (cakes == 1 && countClick == 4)
{
Debug.Log("load endui");
SceneManager.LoadScene("EndUI", LoadSceneMode.Single);
}
}
}
我加过注释了,应该容易看懂。博主也是一名unity菜鸟
三、结束界面
这个结束界面可以算是彩蛋了。在这个界面,让文字一个一个的显示出来(添加一个Text组件)。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TextController : MonoBehaviour
{
private Text te;
private string words;
void Start()
{
te = gameObject.GetComponent<Text>();
words = "别点了,这样我很尴尬的!为什么没有下一关?是这样的,UFO那边发来邀请,请我去一个距离太阳系4光年外的半人马座α星,等我参观完三体就回来更新,等我......";
StartCoroutine(ShowWords());
}
public IEnumerator ShowWords()
{
foreach(char word in words.ToCharArray())
{
te.text += word;
yield return new WaitForSeconds(0.2f);
}
}
至此,整个游戏就制作完成了。