Простая 2D-игра на Unity 5. Часть 4

Добавлено: 05/07/2016 04:36 |  Обновлено: 18/03/2018 08:36 |  Добавил: nick |  Просмотры: 2905 Комментарии: 1
Вводная часть
Если вы знакомы с предыдущими частями, то знаете, что, на этом этапе, когда собраны все кристаллы, выводится сообщение, что игрок выиграл, и чтобы начать игру сначала нужно перезапускать ее в редакторе Unity. Но в реальной игре, конечно же, всегда есть кнопка перезапуска в самой игре. В этом материале реализуем такую возможность.
Десктопная версия игры, основанная на этом материале.
Android-версия игры ×
Во-первых, добавим на холст (Canvas) новую кнопку. Для этого во вкладке Hierarchy нужно нажать правой кнопкой мыши по строке Canvas и в контекстном меню выбрать Button. Если у вас во вкладке Scene отображается игровое поле, как на рисунке выше, то нужно перевести фокус на холст, для этого нужно щелкнуть по нему два раза левой кнопкой мыши во вкладке Hierarchy и увеличить масштаб колесиком мыши. В результате вы увидите на холсте новую кнопку. После чего поменяем название кнопки с «Button» на «Новая игра». Для этого на вкладке Hierarchy нужно раскрыть Button и выбрать подпункт Text. Затем во вкладке Inspector нужно поменять Text «Button» на «Новая игра». Ответственным за перезагрузку игры у нас будет скрипт GameController.cs, который привязан к объекту Game Controller в сцене. Нам нужно привязать этот объект к объекту тарелки. За тарелку отвечает скрипт CompletePlayerController.cs. Поэтому откроем его и в область объявления переменных добавим строку: public GameObject gameController; В конце я приведу полный текст скриптов, чтобы была возможность сверить изменения.

После добавления строки во вкладке Inspector, в разделе Complete Player Controller появится пункт Game Controller, нужно перенести в него объект Game Controller с вкладки Hierarchy. Далее нам нужно создать для кнопки какое-то действие, в нашем случае, кликая по ней, мы будем перезапускать игру. Для этого, во вкладке Hierarchy выберем пункт Button, после чего вкладка Inspector изменит свое содержимое: Нас интересует раздел On Click (). Сюда можно добавить функцию, вызываемую по нажатию кнопки. Нажмем на плюсик в этом разделе. После чего этот раздел примет следующий вид: Далее в скрипт GameController.cs нужно добавить функцию для перезапуска игры. Назовем ее restartGame().
public void restartGame() {
	// Загружаем главную сцену заново
	SceneManager.LoadScene("Main");
}
Класс SceneManager находится в пространстве имен UnityEngine, поэтому добавим вначале две строчки:
using UnityEngine.UI; // для работы с кнопкой
using UnityEngine.SceneManagement;
Вернемся к редактору Unity. В разделе On Click () Runtime Only можно оставить как есть. Ниже вы видите поле для добавления объекта к этой кнопке. Нам нужно привязать объект Game Controller, так как функцию для кнопки мы будем брать из него. Переносим из вкладки Hierarchy объект Game Controller в это поле. После чего для пункта No Function нужно выбрать функцию из перенесенного объекта. Это функция, которую мы добавили ранее – restartGame(). После чего раздел On Click () будет выглядеть следующим образом: Далее, проверьте, есть ли во вкладке Hierarchy, в пункте Canvas подпункт EventSystem, если нет, то его нужно добавить, так же как и кнопку. EventSystem нужен для того, чтобы кнопка реагировала на клики мышью.

На данном этапе, если вы запустите игру, то кнопка сразу же появится на экране, нам это не нужно. Изначально кнопка должна быть скрыта, а появляться она должна после того как тарелка соберет все кристаллы. Поэтому в скрипте GameController.cs добавим еще одну функцию для управления видимостью кнопки.
// Для переключения видимости кнопки
void activateRestartButton(bool toggle) {
	restartButton.SetActive (toggle);
}
Не забудьте вначале скрипта добавить переменную restartButton и подключить к ней объект кнопки с вкладки Hierarchy.
public GameObject restartButton;
Добавим вызов функции activateRestartButton(), с параметром false в функцию Start(), для того чтобы при запуске игры скрыть кнопку:
void Start () {
	activateRestartButton(false);
	SpawnPickups ();
}
Теперь осталось только добавить код появления кнопки после того как все кристаллы собраны. Для этого в скрипте CompletePlayerController.cs в функции SetCountText() нужно добавить строчку gameController.SendMessage("activateRestartButton", true); в тело условия:
if (count >= 12) {
	gameController.SendMessage("activateRestartButton", true);
	//... then set the text property of our winText object to "You win!"
	winText.text = "Вы выиграли!";
}
Таким образом мы вызовем функцию activateRestartButton() с параметром true из класса GameController и покажем кнопку перезагрузки игры на экране.

GameController.cs
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

using UnityEngine.UI; // для работы с кнопкой
using UnityEngine.SceneManagement;

public class GameController : MonoBehaviour {

	public GameObject pickup;
	public int pickupCount;

	public GameObject restartButton;

	public List nodeList = new List();
	private GameObject node = null;

	// Use this for initialization
	void Start () {
		activateRestartButton(false);
		SpawnPickups ();
	}
	
	void SpawnPickups() {
		for (int i = 1; i <= pickupCount; i++) {
			node = nodeList[ Random.Range(0,nodeList.Count) ];
			Vector3 spawnPosition = node.transform.position;
			Quaternion spawnRotation = Quaternion.identity;
			Instantiate (pickup, spawnPosition, spawnRotation);
		}
	}

	// Для переключения видимости кнопки
	void activateRestartButton(bool toggle) {
		restartButton.SetActive (toggle);
	}

	public void restartGame() {
		// Загружаем главную сцену заново
		SceneManager.LoadScene("Main");
	}

	// Update is called once per frame
	/*void Update () {
	
	}*/
}
CompletePlayerController.cs
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.

	public GameObject gameController;

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

		//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.ToString ();

		//Check if we've collected all 12 pickups. If we have...
		if (count >= 12) {
			gameController.SendMessage("activateRestartButton", true);
			//... then set the text property of our winText object to "You win!"
			winText.text = "Вы выиграли!";
		}
	}
}

Оставьте свой комментарий

Комментарии

  • Алексей  07/07/2017 07:30

    Для того, чтобы скрипты заработали пришлось передать скрипту Game Controller ссылку на Button в качестве Restart Button + сохранить сцену под именем Main.

    Ссылка
    • Ответить