Unity3D学习:飞碟游戏进化版
来源:互联网 发布:数据库脱敏系统 编辑:程序博客网 时间:2024/05/07 19:12
上一个做的飞碟游戏虽然是功能也齐全,但是我感觉架构不是很好有点紊乱,不利于后期维护以及改进,所以我按照一个完整的架构重新做了一次,思路更清晰,而且还添加了更多的功能。这次的飞碟游戏是两个关卡,50分上第二关,100分通第二关,而且可以任意切换模式(运动学非刚体模式和物理刚体模式,前者没有刚体组件,后者加刚体组件)
讲讲规则先:一开始就是第一关,默认模式为运动学非刚体模式,还是按空格发射飞碟(一次一个),一个发射期间不能发射第二个,一个飞碟如果没打中会在一定时间内消失,飞碟消失才能发射下一个飞碟,鼠标左键射击子弹,按数字键2切换模式为物理刚体模式,按数字键1切换到运动学非刚体模式。
上个效果图(由于比较难射中,所以我把飞碟大小弄大一些,分数显示被遮住了):
接下来讲一下设计思路,游戏架构如下
DiskModule类挂在飞碟预设上,用来处理触发器事件(飞碟碰到子弹或者地板时触发)
DiskFactory类专门生产飞碟,所有生产飞碟的细节都在这里实现,会根据每个关卡生产不同大小以及颜色的飞碟,并且回收飞碟以便再次加以利用
Recorder类只负责记录分数或者重置分数
Userface类处理用户界面逻辑
CCActionManager类实现运动学的动作,比如运动学非刚体的飞碟发射
PhysicsActionManager类实现物理刚体学动作,比如子弹的发射以及刚体飞碟的发射
SceneController类加载场景以及调用各个其他类来实现功能,比如Userface调用子弹或者飞碟射击要通过SceneController根据不同模式以及关卡来调用相应的动作管理器
具体代码如下,(注释已经把代码思想写的很清楚):
using System.Collections;using System.Collections.Generic;using UnityEngine;public class Director : System.Object{ private static Director _instance; public SceneController _Controller { get; set; } public static Director getinstance() { if (_instance == null) { _instance = new Director(); } return _instance; } public int getFPS() { return Application.targetFrameRate; } public void setFPS(int fps) { Application.targetFrameRate = fps; }}
using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.UI;public class Userface : MonoBehaviour { private SceneController _Controller; public Camera _camera; public Text Score;//显示分数 public Text Round;//显示关卡 public Text Mode;//显示模式 void Start () { _Controller = (SceneController)FindObjectOfType(typeof(SceneController)); } // Update is called once per frame void Update () { if(Input.GetKeyDown("1"))//按下1切换到运动学模式 { if(!_Controller.isFlying) { Debug.Log("NonPhy mode"); _Controller._mode = false; } } if(Input.GetKeyDown("2"))//按下2切换到物理刚体模式 { if (!_Controller.isFlying) { Debug.Log("Phy mode"); _Controller._mode = true; } } if(Input.GetKeyDown("space"))//按下空格发射飞碟 { _Controller.ShootDisk(); } if (Input.GetMouseButtonDown(0)&&!_Controller.isShooting)//按下左键发射子弹 { Ray mouseRay = _camera.ScreenPointToRay(Input.mousePosition); _Controller.ShootBullet(mouseRay.direction); } Score.text = "Score:" + _Controller.getRecorder().getScore(); Round.text = "Round:" + _Controller.getRound(); if (_Controller._mode == false) Mode.text = "Mode:CCAction"; else Mode.text = "Mode:PhysicsAction"; }}
using System.Collections;using System.Collections.Generic;using UnityEngine;public class Recorder : MonoBehaviour { private int _score = 0;public void AddScore(string name)//根据碰撞物名称加减分 { if (name == "Plane") _score -= 10; else if (name == "bullet(Clone)") _score += 10; } public int getScore() { return _score; } public void reset() { _score = 0; }}
using System.Collections;using System.Collections.Generic;using UnityEngine;public class DiskFactory : MonoBehaviour { public List<GameObject> Using; //储存正在使用的 public List<GameObject> Used; //储存空闲的 private SceneController _Controller; public GameObject DiskPrefab; void Start () { Using = new List<GameObject>(); Used = new List<GameObject>(); _Controller = (SceneController)FindObjectOfType(typeof(SceneController)); } public GameObject getDisk(bool isPhy,int _Round) { GameObject t; if (Used.Count == 0) { t = GameObject.Instantiate(DiskPrefab) as GameObject; } else { t = Used[0]; Used.Remove(t); } t.GetComponent<MeshCollider>().isTrigger = true; t.SetActive(true); if (isPhy)//物理学模式加刚体组件 { if (t.GetComponent<Rigidbody>() == null) t.AddComponent<Rigidbody>(); } else if (!isPhy)//运动学模式去除刚体组件 { if (t.GetComponent<Rigidbody>()) Destroy(t.GetComponent<Rigidbody>()); } Using.Add(t); if(_Round==1)//第一关的飞碟形式 { t.transform.localScale *= 2; t.GetComponent<Renderer>().material.color = Color.green; }//第二关为初始大小以及红色 return t; } private void freeDisk(int round)//把场景中inactive的飞碟回收 { for (int i = 0; i < Using.Count; i++) { GameObject t = Using[i]; if (!t.activeInHierarchy) { Using.RemoveAt(i); Used.Add(t); Destroy(t.GetComponent<Rigidbody>()); if (round==1) t.transform.localScale /= 2; t.GetComponent<Renderer>().material.color = Color.red; } } } void Update () { freeDisk(_Controller.getRound());}}
using System.Collections;using System.Collections.Generic;using UnityEngine;public class DiskModule : MonoBehaviour { private string _sth = ""; private float _time = 8f; private SceneController _Controller; void Start () { _Controller = (SceneController)FindObjectOfType(typeof(SceneController)); } void OnTriggerEnter(Collider other)//触发器事件 { if(_sth=="") { _sth = other.gameObject.name; Debug.Log(_sth); if (_sth == "bullet(Clone)") { this._time = 0;//直接回收 _Controller._explosion.GetComponent<Renderer>().material.color = this.GetComponent<Renderer>().material.color; _Controller._explosion.transform.position = this.transform.position; _Controller._explosion.Play();//播放爆炸粒子 } _Controller.getRecorder().AddScore(_sth); _Controller.isShooting = false; } } void Update () { if (_Controller.isFlying) { if (_time > 0) _time -= Time.deltaTime; else if (_time <= 0)//回收飞碟 { GetComponent<MeshCollider>().isTrigger = false; this.gameObject.SetActive(false); _time = 8f; _sth = ""; _Controller.isFlying = false; } } }}
using System.Collections;using System.Collections.Generic;using UnityEngine;public class SceneController : MonoBehaviour { private CCActionManager _CCAM; private PhysicsActionManager _PhyAM; private DiskFactory _Factory; private Recorder _Recorder; private int _Round = 1; public GameObject _bullet;//子弹 public ParticleSystem _explosion;//爆炸粒子 public bool _mode = false;//标记模式 public bool isShooting = false;//判断子弹是否正在飞 public bool isFlying = false;//判断飞碟是否正在飞 private float _time = 1f;void Start () { _bullet = GameObject.Instantiate(_bullet) as GameObject; _explosion = GameObject.Instantiate(_explosion) as ParticleSystem; Director _director = Director.getinstance(); _director._Controller = this; _CCAM = (CCActionManager)FindObjectOfType(typeof(CCActionManager)); _PhyAM = (PhysicsActionManager)FindObjectOfType(typeof(PhysicsActionManager)); _Recorder = (Recorder)FindObjectOfType(typeof(Recorder)); _Factory = (DiskFactory)FindObjectOfType(typeof(DiskFactory)); _director.setFPS(60); _director._Controller = this; } public DiskFactory getFactory() { return _Factory; } public int getRound() { return _Round; } public Recorder getRecorder() { return _Recorder; } public CCActionManager getCCActionManager() { return _CCAM; } public PhysicsActionManager getPhysicsActionManager() { return _PhyAM; } public void ShootDisk() { if(!isFlying) { GameObject _disk = _Factory.getDisk(_mode, _Round);//根据不同关卡以及不同模式生产不同的飞碟 if (!_mode) _CCAM.ShootDisks(_disk);//根据不同模式调用不同动作管理器的动作函数 else _PhyAM.ShootDisks(_disk); isFlying = true; } } public void ShootBullet(Vector3 _dir)//调用动作管理器的射击子弹函数 { isShooting = true; _PhyAM.ShootBullets(_bullet, _dir); } private void AddRound()//判断是否通关 { if (_Recorder.getScore() >= 50&&_Round == 1) { _Round++; } else if (_Recorder.getScore() > 100&& _Round == 2) { _Round = 1; _Recorder.reset(); } } void Update () { AddRound();if(isShooting) { if(_time>0) { _time -= Time.deltaTime; if(_time<=0) { isShooting = false; _time = 1f; } } }}}
using System.Collections;using System.Collections.Generic;using UnityEngine;public class PhysicsActionManager : MonoBehaviour { private SceneController _Controller; void Start () { _Controller = (SceneController)FindObjectOfType(typeof(SceneController)); }public void ShootBullets(GameObject _bullet, Vector3 _dir)//发射子弹 { _bullet.transform.position = new Vector3(0, 2, 0); _bullet.GetComponent<Rigidbody>().velocity = Vector3.zero; // 子弹刚体速度重置 _bullet.GetComponent<Rigidbody>().AddForce(_dir * 500f, ForceMode.Impulse); } public void ShootDisks(GameObject _disk)//发射飞碟 { _disk.transform.position = new Vector3(0, 2, 2); float _dx = Random.Range(-20f, 20f); Vector3 _dir = new Vector3(_dx, 30, 20); _disk.transform.up = _dir; if (_Controller.getRound() == 1) { _disk.GetComponent<Rigidbody>().AddForce(_dir*20f, ForceMode.Force); } else if(_Controller.getRound() == 2) { _disk.GetComponent<Rigidbody>().AddForce(_dir*30f, ForceMode.Force); } } void Update () {}}
using System.Collections;using System.Collections.Generic;using UnityEngine;public class CCActionManager : MonoBehaviour { private SceneController _Controller; private GameObject temp; void Start () { _Controller = (SceneController)FindObjectOfType(typeof(SceneController)); } public void ShootDisks(GameObject _disk)//发射飞碟 { _disk.transform.position = new Vector3(Random.Range(-1f, 1f), 2f, 2f); temp = _disk; } void Update () { if(_Controller.isFlying&&!_Controller._mode) { if (_Controller.getRound() == 1) { temp.transform.position = Vector3.MoveTowards(temp.transform.position, new Vector3(0, 2, 100), 0.1f); } else if (_Controller.getRound() == 2) { temp.transform.position = Vector3.MoveTowards(temp.transform.position, new Vector3(0, 2, 100), 0.2f); } } }}
- Unity3D学习:飞碟游戏进化版
- Unity3D学习笔记(6)-- 打飞碟游戏改进版
- Unity3D学习之打飞碟游戏
- Unity3D学习(三)打飞碟游戏
- Unity3D学习(5)之工厂回收利用的3D版飞碟游戏
- Unity3D学习笔记(6)—— 飞碟射击游戏
- Unity3D学习——射飞碟游戏(工厂模式)
- Unity3D学习(6)——简易飞碟游戏
- Unity3D学习:射击小游戏——飞碟世界
- 飞碟游戏-序列化
- 简单打飞碟游戏
- 打飞碟游戏
- Unity3D作业六项目一——优化打飞碟游戏
- Unity3D 重力下打飞碟
- Unity笔记-打飞碟游戏
- [Unity3D课堂作业] 打飞碟 PlayDarts
- 飞碟
- 简单c语言飞碟射击游戏
- init.rc语法介绍
- Android ListView 滑到最后一条自动加载
- 函数内联
- C#宾馆管理系统
- truncate table 与delete table区别
- Unity3D学习:飞碟游戏进化版
- Python 实现pywinauto自动化测试操作软件(C/S结构)
- iOS上传图片到服务器后自动旋转90度解决办法
- SICP 1.28费马检查与Miller-Rabin检查的思考
- 大数据平台Docker应用之路
- 实例分析init.rc的语法
- bzoj1033: [ZJOI2008]杀蚂蚁antbuster
- linux软连接多个文件 批量
- Java Collection