Своя Tower Defense на Unity 5. Часть 4. + Видео

logo Уроки

Создание Tower Defense на игровом движке Unity 5.

Часть 1

Часть 2

Часть 3

Это заключительная часть урока по созданию Tower Defense на Unity 5 и в этой части мы реализуем все то, что будет связанно с деньгами или очками в нашей игре — добавление денег от уничтожения противников, покупка башен и отнимание денег при прохождении противника через конечную точку.

Первым делом создадим один общий скрипт, в котором будем хранить наши префабы башен и их цену, назовем его TurretBlueprint.

using UnityEngine;
using System.Collections;

[System.Serializable]
public class TurretBlueprint {

    public GameObject prefab; // префаб башни
    public int cost; // цена

}

Этот скрипт ни куда «вешать» не нужно он останется в таком виде у нас в проекте. Далее создадим еще один скрипт , где будем хранить начальное количество денег при старте сцены/ игры, назовем его PlayerStats.

using UnityEngine;
using System.Collections;

public class PlayerStats : MonoBehaviour {

    public static int Money;
    public int startMoney = 400;// стартовое количество денег
	
	void Start () {
        Money = startMoney;
	}	
}

Поместим этот скрипт на объект Start. Ну и на основании этих скриптов изменяем наши созданные ранее скрипты, для того чтобы реализовать возможность покупки башен. Откройте скрипт Shop, теперь он будет выглядеть так.

using UnityEngine;


public class Shop : MonoBehaviour {

    BuildManager buildManager;
    public TurretBlueprint standartTurret;
    public TurretBlueprint missileLaumcher;



    void Start() {
        buildManager = BuildManager.instance;
    }

    public void SelectStandartTurret() {
        buildManager.SelectedTurretToBuild(standartTurret);
    }

    public void SelectMissileTurret()
    {
        buildManager.SelectedTurretToBuild(missileLaumcher);
    }

}

Следующий скрипт Node:

using UnityEngine;
using UnityEngine.EventSystems;
using System.Collections;

public class Node : MonoBehaviour {

    public Color hoverColor;
    public Color notEnoughMoneyColor; //добавим цвет при недостатке денег
    private Renderer rend;
    private Color startColor;
    public GameObject turret;
    public Vector3 positionOffset;
    BuildManager buildManager;


    void Start() {
        rend = GetComponent();
        startColor = rend.material.color;

        buildManager = BuildManager.instance;
    }
    public Vector3 GetBuildPosition() {
        return transform.position + positionOffset;
    }

    void OnMouseEnter() {
        if (EventSystem.current.IsPointerOverGameObject())
            return;

        if (!buildManager.CanBuild)
            return;
        if (buildManager.HasMoney)
        {
            rend.material.color = hoverColor;
        }
        else {
            rend.material.color = notEnoughMoneyColor;
        }
    }
    void OnMouseDown() {
        if (EventSystem.current.IsPointerOverGameObject())
            return;
        if (!buildManager.CanBuild)
            return;

        if (turret != null) {
            
            return;
        }
        buildManager.BuildTurretOn(this);
    }

    void OnMouseExit() {
        rend.material.color = startColor;
    }
}

И скрипт BuildManager:

using UnityEngine;




public class BuildManager : MonoBehaviour {

    public static BuildManager instance;
    private TurretBlueprint TurretToBuilt;
    public bool CanBuild { get { return TurretToBuilt != null; } }
    public bool HasMoney { get { return PlayerStats.Money >= TurretToBuilt.cost; } }

    void Awake() {
        if (instance != null) {
            Debug.LogError("More than one BuiltManager in scene!");
            return;
        }
        instance = this;
    }
    public GameObject standartTurretPrefab;
    public GameObject anotherTurretPrefab;

    public void BuildTurretOn(Node node) {
        if (PlayerStats.Money < TurretToBuilt.cost) {
            return;
        }
        PlayerStats.Money -= TurretToBuilt.cost; // отнимаем стоимость башни при покупке

        GameObject turret = (GameObject) Instantiate(TurretToBuilt.prefab, node.GetBuildPosition(),Quaternion.identity);
        node.turret = turret;
    }

    public void SelectedTurretToBuild(TurretBlueprint turret) {
        TurretToBuilt = turret;
    }
}

/*Будьте внимательны! В скриптах изменены названия некоторых функций, поэтому на кнопках в обработчике OnClick следует так же их изменить (иначе кнопки не сработают)*/

button

В объекте Shop добавим наши префабы башен и укажем их цену.

shop

На префабе платформы укажем второй цвет, этот цвет будет принимать платформа в том случае, когда не будет хватать денег на покупку башни.

node

Сохраним сцену и проверим работоспособность игры.

Перейдем к оформлению сцены. Добавим новый элемент Canvas на сцену. В этом элементе будут отображаться наше количество денег. Я настрою его примерно так:

canvasnew

К Канвасу добавим элемент Text (назовем Money) и тоже его настроим.

canvastext

Создадим новый скрипт MonyUI и переместим его на компонент Money.

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class MonyUI : MonoBehaviour {
    public Text moneyText;

    void Update() {
        moneyText.text = PlayerStats.Money.ToString();// текст будет равен значению денег
    }

}

Следующий наш шаг, добавление стоимости башни. Вернемся в компонент Canvas, где находится наш Shop, и к компоненту Button добавим Panel.

castbg

К  Panel добавим Text.

cast

И изменим скрипт Bullet, сделаем так чтобы добавлялись деньги при уничтожении противника.

using UnityEngine;
using System.Collections;



public class Bullet : MonoBehaviour {
	private Transform target;
	public float speed = 70f;
    public GameObject bulletEffect;
    public float explosionRadius = 0f;
    public int plusMoney = 1; //количество денег при уничтожении противника
    

    public void Seek (Transform _target) {
		target = _target;
	}
	
	void Update () {
		if (target == null) {
			Destroy (gameObject);
            return;
		}
		Vector3 dir = target.position - transform.position;
		float distanceThisFrame = speed * Time.deltaTime;

		if (dir.magnitude <= distanceThisFrame) { HitTarget (); return; } transform.Translate (dir.normalized * distanceThisFrame, Space.World); transform.LookAt(target); } void HitTarget (){ GameObject effectIns= (GameObject) Instantiate(bulletEffect, transform.position, transform. rotation); Destroy(effectIns, 5f); if (explosionRadius > 0f)
        {
            Explode();
        }
        else {
            Damage(target);
        }
		Destroy(gameObject);
    }
    void Explode() {
        Collider[] colliders = Physics.OverlapSphere(transform.position, explosionRadius);
        foreach (Collider collider in colliders) {
            if (collider.tag == "Enemy") {
                Damage(collider.transform);
            }
        }
    }

    void Damage(Transform enemy) {
        Destroy(enemy.gameObject);
        PlayerStats.Money = PlayerStats.Money + plusMoney; // добавляем деньги при уничтожении
    }

    void OnDrawGizmosSelected() {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(transform.position, explosionRadius);
    }
}

Скрипт Enemy, здесь можно реализовать два варианта: первый при достижении противника конечной точки игра заканчивается и второй, при достижении противника конечной точки будут уменьшаться деньги, я сделаю именно так.

using UnityEngine;
using System.Collections;

public class Enemy : MonoBehaviour {

	public float speed = 10f;
	private Transform target;
	private int wavepointIndex =0;
    public int minusMoney = 10; // количество при достижении противника конечной точки

    void Start (){
		target = weapoints.points [0];
	}

	void Update(){
		Vector3 dir = target.position - transform.position;

		transform.Translate (dir.normalized * speed * Time.deltaTime, Space.World);  

		if (Vector3.Distance (transform.position, target.position) <= 0.3f) { GetNextWaypoint (); } } void GetNextWaypoint () { if (wavepointIndex >= weapoints.points.Length - 1)
        { 

            Destroy (gameObject); 
            PlayerStats.Money = PlayerStats.Money - minusMoney; // отнимаем деньги при достижении конечной точки
            return; 
		}
		wavepointIndex++; 
		target = weapoints.points [wavepointIndex]; 
	}
	}

Проверяем игру.

game

Видим что теперь появилась цена башни, добавляются деньги при уничтожении противника и уменьшаются при достижении противника контрольной точки.

На этом серию уроком я думаю можно окончить, дальнейшая разработка игры и оформление будет зависеть только от ваших способностей и фантазии, можно добавить звуки выстрелов, уничтожения, оформить немного сцену визуально, добавить полноценное меню, первоначальную сцену и сцену завершения игры, вообщем все в ваших силах. Удачных проектов!

Данная серия уроков была переведена (канал Brackeys) и немного изменена.

Скачать проект с игрой можно здесь.

После небольших доработок получается примерно так:

Видео

Поделиться или сохранить к себе:
Технологичная помощь
Добавить комментарий

Нажимая на кнопку "Отправить комментарий", я даю согласие на обработку персональных данных, принимаю Политику конфиденциальности и условия Пользовательского соглашения.

  1. Дмитрий

    Спасибо Вам за такие подробные уроки!

    Ответить