using System.Collections;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class BuildManager : MonoBehaviour
{
public TurretData laserTurretData;
public TurretData missileTurretData;
public TurretData standardTurretData;
//表示当前选择的炮台(要建造的炮台)
private TurretData selectedTurretData;
//表示当前选择的炮台(场景中的游戏物体)
private MapCube selectedMapCube;
public Text moneyText;
public Animator moneyAnimator;
private int money = 1000;
public GameObject upgradeCanvas;
private Animator upgradeCanvasAnimator;
public Button buttonUpgrade;
void ChangeMoney(int change = 0)
{
money += change;
moneyText.text = "¥" + money;
}
void Start()
{
upgradeCanvasAnimator = upgradeCanvas.GetComponent<Animator>();
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
if (EventSystem.current.IsPointerOverGameObject() == false)
{
//开发炮台的建造
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
bool isCollider = Physics.Raycast(ray, out hit, 1000, LayerMask.GetMask("MapCube"));
if (isCollider)
{
MapCube mapCube = hit.collider.GetComponent<MapCube>();
if (selectedTurretData != null && mapCube.turretGo == null)
{
//可以创建
if (money > selectedTurretData.cost)
{
ChangeMoney(-selectedTurretData.cost);
mapCube.BuildTurret(selectedTurretData);
}
else
{
//提示钱不够
moneyAnimator.SetTrigger("Flicker");
}
}
else if (mapCube.turretGo != null)
{
// 升级处理
//if (mapCube.isUpgraded)
//{
// ShowUpgradeUI(mapCube.transform.position, true);
//}
//else
//{
// ShowUpgradeUI(mapCube.transform.position, false);
//}
if (mapCube == selectedMapCube && upgradeCanvas.activeInHierarchy)
{
StartCoroutine(HideUpgradeUI());
}
else
{
ShowUpgradeUI(mapCube.transform.position, mapCube.isUpgraded);
}
selectedMapCube = mapCube;
}
}
}
}
}
public void OnLaserSelected(bool isOn)
{
if (isOn)
{
selectedTurretData = laserTurretData;
}
}
public void OnMissileSelected(bool isOn)
{
if (isOn)
{
selectedTurretData = missileTurretData;
}
}
public void OnStandardSelected(bool isOn)
{
if (isOn)
{
selectedTurretData = standardTurretData;
}
}
void ShowUpgradeUI(Vector3 pos, bool isDisableUpgrade = false)
{
StopCoroutine("HideUpgradeUI");
upgradeCanvas.SetActive(false);
upgradeCanvas.SetActive(true);
upgradeCanvas.transform.position = pos;
buttonUpgrade.interactable = !isDisableUpgrade;
}
IEnumerator HideUpgradeUI()
{
upgradeCanvasAnimator.SetTrigger("Hide");
//upgradeCanvas.SetActive(false);
yield return new WaitForSeconds(0.8f);
upgradeCanvas.SetActive(false);
}
public void OnUpgradeButtonDown()
{
if (money >= selectedMapCube.turretData.costUpgraded)
{
ChangeMoney(-selectedMapCube.turretData.costUpgraded);
selectedMapCube.UpgradeTurret();
}
else
{
moneyAnimator.SetTrigger("Flicker");
}
StartCoroutine(HideUpgradeUI());
}
public void OnDestroyButtonDown()
{
selectedMapCube.DestroyTurret();
StartCoroutine(HideUpgradeUI());
}
}
2.Bullet
using UnityEngine;
public class Bullet : MonoBehaviour
{
public int damage = 50;
public float speed = 20;
public GameObject explosionEffectPrefab;
private float distanceArriveTarget = 1.2f;
private Transform target;
public void SetTarget(Transform _target)
{
this.target = _target;
}
void Update()
{
if (target == null)
{
Die();
return;
}
transform.LookAt(target.position);
transform.Translate(Vector3.forward * speed * Time.deltaTime);
Vector3 dir = target.position - transform.position;
if (dir.magnitude < distanceArriveTarget)
{
target.GetComponent<Enemy>().TakeDamage(damage);
Die();
}
}
void Die()
{
GameObject effect = Instantiate(explosionEffectPrefab, transform.position, transform.rotation);
Destroy(effect, 1);
Destroy(this.gameObject);
}
}
3.Enemy
using UnityEngine;
using UnityEngine.UI;
public class Enemy : MonoBehaviour
{
public float speed = 10;
public float hp = 150;
private float totalHp;
public GameObject explosionEffect;
private Slider hpSlider;
private Transform[] positions;
private int index = 0;
// Use this for initialization
void Start()
{
positions = Waypoints.positions;
totalHp = hp;
hpSlider = GetComponentInChildren<Slider>();
}
// Update is called once per frame
void Update()
{
Move();
}
void Move()
{
if (index > positions.Length - 1) return;
transform.Translate((positions[index].position - transform.position).normalized * Time.deltaTime * speed);
if (Vector3.Distance(positions[index].position, transform.position) < 0.2f)
{
index++;
}
if (index > positions.Length - 1)
{
ReachDestination();
}
}
//达到终点
void ReachDestination()
{
GameManager.Instance.Failed();
Destroy(this.gameObject);
}
void OnDestroy()
{
EnemySpawner.CountEnemyAlive--;
}
public void TakeDamage(float damage)
{
if (hp <= 0) return;
hp -= damage;
hpSlider.value = (float) hp / totalHp;
if (hp <= 0)
{
Die();
}
}
void Die()
{
GameObject effect = Instantiate(explosionEffect, transform.position, transform.rotation);
Destroy(effect, 1.5f);
Destroy(this.gameObject);
}
}
4.EnemySpawner
using System.Collections;
using UnityEngine;
public class EnemySpawner : MonoBehaviour
{
public static int CountEnemyAlive = 0;
public Wave[] waves;
public Transform START;
public float waveRate = 0.2f;
private Coroutine coroutine;
void Start()
{
coroutine = StartCoroutine(SpawnEnemy());
}
public void Stop()
{
StopCoroutine(coroutine);
}
IEnumerator SpawnEnemy()
{
foreach (Wave wave in waves)
{
for (int i = 0; i < wave.count; i++)
{
Instantiate(wave.enemyPrefab, START.position, Quaternion.identity);
CountEnemyAlive++;
if (i != wave.count - 1)
yield return new WaitForSeconds(wave.rate);
}
while (CountEnemyAlive > 0)
{
yield return 0;
}
yield return new WaitForSeconds(waveRate);
}
while (CountEnemyAlive > 0)
{
yield return 0;
}
GameManager.Instance.Win();
}
}
5.GameManager
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
public GameObject endUI;
public Text endMessage;
public static GameManager Instance;
private EnemySpawner enemySpawner;
void Awake()
{
Instance = this;
enemySpawner = GetComponent<EnemySpawner>();
}
public void Win()
{
endUI.SetActive(true);
endMessage.text = "胜 利";
}
public void Failed()
{
enemySpawner.Stop();
endUI.SetActive(true);
endMessage.text = "失 败";
}
public void OnButtonRetry()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
public void OnButtonMenu()
{
SceneManager.LoadScene(0);
}
}
6.GameMenu
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameMenu : MonoBehaviour
{
public void OnStartGame()
{
SceneManager.LoadScene(1);
}
public void OnExitGame()
{
#if UNITY_EDITOR
EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
}
}
using System.Collections.Generic;
using UnityEngine;
public class Turret : MonoBehaviour
{
private List<GameObject> enemys = new List<GameObject>();
void OnTriggerEnter(Collider col)
{
if (col.tag == "Enemy")
{
enemys.Add(col.gameObject);
}
}
void OnTriggerExit(Collider col)
{
if (col.tag == "Enemy")
{
enemys.Remove(col.gameObject);
}
}
public float attackRateTime = 1; //多少秒攻击一次
private float timer = 0;
public GameObject bulletPrefab; //子弹
public Transform firePosition;
public Transform head;
public bool useLaser = false;
public float damageRate = 70;
public LineRenderer laserRenderer;
public GameObject laserEffect;
void Start()
{
timer = attackRateTime;
}
void Update()
{
if (enemys.Count > 0 && enemys[0] != null)
{
Vector3 targetPosition = enemys[0].transform.position;
targetPosition.y = head.position.y;
head.LookAt(targetPosition);
}
if (useLaser == false)
{
timer += Time.deltaTime;
if (enemys.Count > 0 && timer >= attackRateTime)
{
timer = 0;
Attack();
}
}
else if (enemys.Count > 0)
{
if (laserRenderer.enabled == false)
laserRenderer.enabled = true;
laserEffect.SetActive(true);
if (enemys[0] == null)
{
UpdateEnemys();
}
if (enemys.Count > 0)
{
laserRenderer.SetPositions(new Vector3[] {firePosition.position, enemys[0].transform.position});
enemys[0].GetComponent<Enemy>().TakeDamage(damageRate * Time.deltaTime);
laserEffect.transform.position = enemys[0].transform.position;
Vector3 pos = transform.position;
pos.y = enemys[0].transform.position.y;
laserEffect.transform.LookAt(pos);
}
}
else
{
laserEffect.SetActive(false);
laserRenderer.enabled = false;
}
}
void Attack()
{
if (enemys[0] == null)
{
UpdateEnemys();
}
if (enemys.Count > 0)
{
GameObject bullet = Instantiate(bulletPrefab, firePosition.position, firePosition.rotation);
bullet.GetComponent<Bullet>().SetTarget(enemys[0].transform);
}
else
{
timer = attackRateTime;
}
}
void UpdateEnemys()
{
//enemys.RemoveAll(null);
List<int> emptyIndex = new List<int>();
for (int index = 0; index < enemys.Count; index++)
{
if (enemys[index] == null)
{
emptyIndex.Add(index);
}
}
for (int i = 0; i < emptyIndex.Count; i++)
{
enemys.RemoveAt(emptyIndex[i] - i);
}
}
}
9.TurretData
using System;
using UnityEngine;
[Serializable]
public class TurretData
{
public GameObject turretPrefab;
public int cost;
public GameObject turretUpgradedPrefab;
public int costUpgraded;
public TurretType type;
}
public enum TurretType
{
LaserTurret,
MissileTurret,
StandardTurret
}
10.ViewController
using UnityEngine;
public class ViewController : MonoBehaviour
{
public float speed = 1;
public float mouseSpeed = 60;
// Update is called once per frame
void Update()
{
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
float mouse = Input.GetAxis("Mouse ScrollWheel");
transform.Translate(new Vector3(h * speed, mouse * mouseSpeed, v * speed) * Time.deltaTime, Space.World);
}
}
11.Wave
using System;
using UnityEngine;
//保存每一波敌人生成所需要的属性
[Serializable]
public class Wave
{
public GameObject enemyPrefab;
public int count;
public float rate;
}
12.Waypoints
using UnityEngine;
public class Waypoints : MonoBehaviour
{
public static Transform[] positions;
void Awake()
{
positions = new Transform[transform.childCount];
for (int i = 0; i < positions.Length; i++)
{
positions[i] = transform.GetChild(i);
}
}
}