项目 Project | 视图 View |
游戏对象 GameObject | 刚体 Rigidbody |
组件 Component | 碰撞 Collide |
预制件 Prefab | 材质 Material |
脚本 Script | 资源商店 Asset Store |
调试 Debug | 音频 Audio |
包 Package | 发布 Publish |
导航 Navigation | 用户界面 Toggle |
物理 Physical | 线渲染 Line Renderer |
协程 Coroutine | 数据脚本 Data |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems;//引入事件系统 public class Base : MonoBehaviour { MeshRenderer m_Renderer; Color init_Color; public Color hover_Color; void Start() { m_Renderer = GetComponent<MeshRenderer>(); init_Color = m_Renderer.material.color; } private void OnMouseEnter() { if (!EventSystem.current.IsPointerOverGameObject())//增加判断:不在UI上 { m_Renderer.material.color = hover_Color; } } private void OnMouseExit() { m_Renderer.material.color = init_Color; } }
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; using UnityEngine.UI; public class Mon : MonoBehaviour { public GameObject explosion; public float Hp; public Image HpBar; NavMeshAgent agent; Transform tar; float curHealth; float oriSpeed; void Start() { curHealth = Hp; agent = GetComponent<NavMeshAgent>(); tar = GameObject.FindGameObjectWithTag("target").transform; oriSpeed = agent.speed; } void Update() { agent.SetDestination(tar.position); //请根据实际情况判断距离 if (Vector3.Distance(agent.destination, agent.nextPosition) <= 0.5f) { Destroy(gameObject);//1 //每成功达到终点1个怪物,玩家生命减1;来自脚本GameManager.cs GameManager.lives--; } } //供子弹脚本的碰撞处理使用 public void GetDam(float dam) { curHealth -= dam; HpBar.fillAmount = curHealth / Hp; if (curHealth <= 0) { Destroy(gameObject);//2 //播放死亡时的粒子特效,参见后面[提高]部分 GameObject exp = Instantiate(explosion); Destroy(exp, 1); } } //后期预留减速功能 public void getSlow(float factor) { agent.speed = oriSpeed * (1 - factor); StartCoroutine(clearSlow()); } public void resetSlow() { agent.speed = oriSpeed; } IEnumerator clearSlow() { yield return new WaitForSeconds(2); resetSlow(); } //业务整合或单独写在对象销毁所在的函数内1、2 private void OnDestroy() { Spawn.alive--; } }
using System.Collections; using System.Collections.Generic; using UnityEngine; [System.Serializable] public class Data { public GameObject monPrefab; public int monNum; public int monInter; }
//Spawn.cs using System.Collections; using System.Collections.Generic; using UnityEngine; public class Spawn : MonoBehaviour { public Data[] mons; public float waveInter; public static int alive = 0; public static bool isDone=false; void Start() { isDone = false; StartCoroutine(MonSpawn()); } IEnumerator MonSpawn() { for (int i = 0; i < mons.Length; i++) { for (int j = 0; j < mons[i].monNum; j++) { alive++; GameObject mon = Instantiate(mons[i].monPrefab, transform.position, Quaternion.identity); yield return new WaitForSeconds(mons[i].monInter); } while (alive > 0) { yield return null; } yield return new WaitForSeconds(waveInter); } isDone=true; } }
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems;//引入UI事件系统 public class Build : MonoBehaviour { public GameObject standard, missile, laser; GameObject selected; void Start() { selected = standard; } void Update() { //按下鼠标且不在UI上 if (Input.GetMouseButtonDown(0) && !EventSystem.current.IsPointerOverGameObject()) { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; //和指定层发射碰撞 //如果不指定距离,会放到路面上!!! if (Physics.Raycast(ray, out hit, 1000, LayerMask.GetMask("base"))) { GameObject obj = hit.collider.gameObject; //如果当前对象没有炮塔/子对象;且金钱足够[功能预留] if (obj.transform.childCount == 0) { //动态生成并放置炮塔,成为基座base的子对象 GameObject tower = Instantiate(selected, obj.transform.position, Quaternion.identity); tower.transform.parent = obj.transform; } } } } public void selTowerStandard(bool isON)//选中第1种炮:标准炮 { if (isON) { selected = standard; } } public void selTowerMissile(bool isON)//选中第2种炮:火箭炮 { if (isON) { selected = missile; } } public void selTowerLaser(bool isON)//选中第3种炮:激光炮 { if (isON) { selected = laser; } } }
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit)) { GameObject obj = hit.collider.gameObject; if (obj.tag == "base" && obj.transform.childCount == 0) { GameObject tar = Instantiate(curTower, obj.transform.position, Quaternion.identity); tar.transform.parent = obj.transform; } }
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public class Base : MonoBehaviour { public GameObject towerFab; private void OnMouseDown() { if (transform.childCount == 0 && !EventSystem.current.IsPointerOverGameObject()) { GameObject obj = Instantiate(towerFab, transform.position, Quaternion.identity); obj.transform.parent = transform; } } }
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Bullet : MonoBehaviour { public float damage = 10; public float speed = 20; Transform target = null; void Update() { if (target == null) { Destroy(gameObject); return; } transform.Translate(Vector3.forward * speed * Time.deltaTime); transform.LookAt(target.position); } public void SetTarget(Transform tar) { target = tar; } private void OnTriggerEnter(Collider other) { if (other.tag == "mon") { Destroy(gameObject); target.GetComponent<Mon>().GetDam(damage); //预留:粒子击中特效 } } }
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Standard : MonoBehaviour { public List<GameObject> list = new List<GameObject>(); public GameObject bullet; public Transform firePos; public Transform headRot; Transform target;//也可以声明为GameObj,但是我们仅仅需要的是一个位置 public float attackInter = 1f; float timer = 0; private void Start() { InvokeRepeating("GetTarget", 0, 0.5f); } void Update() { if (target == null) { return; } //创建新的位置信息,主要是控制高度一致,避免后仰前俯;且让炮台始终朝向目标 Vector3 tarPos = target.position; tarPos.y = headRot.position.y; headRot.LookAt(tarPos); timer += Time.deltaTime; if (timer >= attackInter && list.Count > 0) { GameObject bulletObj = Instantiate(bullet, firePos.position, firePos.rotation); bulletObj.GetComponent<Bullet>().SetTarget(target); Destroy(bulletObj.gameObject, 5); timer = 0; } } void GetTarget() { float minDis = Mathf.Infinity; //起始必须赋空值 Transform nearMon = null; //MUST:每次获取前先把可能的空对象移出 list.RemoveAll(item => item == null); foreach (GameObject item in list) { float dis = Vector3.Distance(transform.position, item.transform.position); if (dis < minDis) { minDis = dis; nearMon = item.transform; } } target = nearMon; } private void OnTriggerEnter(Collider other) { if (other.tag == "mon") { list.Add(other.gameObject); } } private void OnTriggerExit(Collider other) { if (other.tag == "mon") { list.Remove(other.gameObject); } } }
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Laser : MonoBehaviour { public List<GameObject> list = new List<GameObject>(); public Transform firePos; public Transform headRot; Transform target; public LineRenderer line; public float damOverTime = 20f; public float slowFactor = 0.6f; private void Start() { InvokeRepeating("GetTarget", 0, 0.5f); } void Update() { if (target == null) { line.enabled = false; return; } Vector3 tarPos = target.position; tarPos.y = headRot.position.y; line.enabled = true; headRot.LookAt(tarPos); line.SetPositions(new Vector3[] { firePos.position,target.position}); target.GetComponent<Mon>().GetDam(damOverTime*Time.deltaTime); target.GetComponent<Mon>().getSlow(slowFactor); //发射音效 } void GetTarget() { float minDis = Mathf.Infinity; Transform nearMon = null; //MUST:每次获取前先把可能的空对象移出 list.RemoveAll(item => item == null); foreach (GameObject item in list) { float dis = Vector3.Distance(transform.position, item.transform.position); if (dis < minDis) { minDis = dis; nearMon = item.transform; } } target = nearMon; } private void OnTriggerEnter(Collider other) { if (other.tag == "mon") { list.Add(other.gameObject); } } private void OnTriggerExit(Collider other) { if (other.tag == "mon") { list.Remove(other.gameObject); } } }
//Menu.cs using System.Collections; using System.Collections.Generic; using Unity.VisualScripting; using UnityEngine; using UnityEngine.SceneManagement; public class Menu : MonoBehaviour { public Animation ani; private void Start() { Time.timeScale = 1; } private void Update() { if (Input.GetKeyDown(KeyCode.Escape)) { Application.Quit(); } } public void LoadScene(string str) { SceneManager.LoadScene(str); } public void Quit() { Application.Quit(); } public void LoadAnim() { ani.Play(); } }
//GameManager.cs using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; public class GameManager : MonoBehaviour { public static int lives = 3; public GameObject failEnding; public GameObject winEnding; public GameObject pauseEnding; bool isPause=false; private void Start() { lives = 3; Time.timeScale = 1; failEnding.SetActive(false); winEnding.SetActive(false); pauseEnding.SetActive(false); } private void Update() { //失败 if (lives <= 0) { failEnding.SetActive(true); Time.timeScale = 0; } //胜利 if (lives > 0 && Spawn.isDone) { StartCoroutine(dis()); } //按下Escape if (Input.GetKeyDown(KeyCode.Escape)) { if (isPause) { isPause = false; Time.timeScale = 1; pauseEnding.SetActive(false); } else { isPause = true; Time.timeScale = 0; pauseEnding.SetActive(true); } } } public void backToGame() { Time.timeScale = 1; pauseEnding.SetActive(false); isPause = false; } public void LoadScene(string str) { SceneManager.LoadScene(str); } public void Quit() { Application.Quit(); } //暂停1秒后显示winEnding IEnumerator dis() { yield return new WaitForSeconds(1); winEnding.SetActive(true); } }
public AudioSource player; public AudioClip clip; // player.PlayOneShot(clip);
public AudioSource player; public AudioClip clip; //如果没有播放就播放,否则什么也不做 if (player.isPlaying) { } else { player.PlayOneShot(clip); }
using System.Collections; using System.Collections.Generic; using UnityEngine; public class AudioCtrl : MonoBehaviour { public static AudioCtrl instance; AudioSource player; private void Awake() { if (instance == null) { instance = this; } else if (instance != this) { Destroy(gameObject); } DontDestroyOnLoad(gameObject); } void Start() { player = GetComponent<AudioSource>(); } public void playAudio(AudioClip clip) { player.PlayOneShot(clip); } }
using System.Collections; using System.Collections.Generic; using UnityEngine; public class xxx : MonoBehaviour { public AudioClip clip; private void OnTriggerEnter(Collider other) { if (other.gameObject.tag == "mon") { //其它业务略 AudioCtrl.instance.playAudio(clip); } } }