上一个做的飞碟游戏虽然是功能也齐全,但是我感觉架构不是很好有点紊乱,不利于后期维护以及改进,所以我按照一个完整的架构重新做了一次,思路更清晰,而且还添加了更多的功能。这次的飞碟游戏是两个关卡,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 framevoid 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学习:飞碟游戏进化版相关推荐

  1. Unity3d——打飞碟游戏(终极版)

    前段时间比较忙,囫囵吞枣学了个大概,作业写的也很烂,趁最近有空整理一下,认真写一次打飞碟游戏(主要是总结一下导演场记动作管理这些面向对象设计) 放个UML图 1.SSDirection,导演对象负责 ...

  2. Unity3D学习——射箭游戏(工厂模式)

    成品展示 每两秒会获得一个稳定风速,玩家可以把握住这个瞬间射箭,击中不同环得分不同,不击中不扣分,60s内够100分则获胜 游戏制作 脚本挂载与预制 箭靶子预制 在一个空对象上挂载五个扁平同心圆柱,设 ...

  3. 【Rainbow——强化学习之DQN进化版】

    一. Rainbow 参考链接: https://blog.csdn.net/tianjuewudi/article/details/120580521 https://zhuanlan.zhihu. ...

  4. unity3D学习9 游戏智能

    游戏智能 作业要求 P&D 过河游戏智能帮助实现,程序具体要求: 实现状态图的自动生成 讲解图数据在程序中的表示方法 利用算法实现下一步的计算 参考:P&D 过河游戏智能帮助实现 实现 ...

  5. 【Unity3d学习】使用物理引擎——打飞碟游戏的物理引擎改进与射箭游戏设计

    文章目录 写在前面 HitUFO的物理引擎改进版本 物理引擎的改进版本思路与实现 PhysicsAction PhysicsManager 新接口类IActionManager 动作管理器基类的变化 ...

  6. Unity3D学习:结合Kinect进行游戏开发 | 孤舟博客

    最近需要学习Unity3D和Kinect交互进行开发.查阅网上的资料,一直没有找到详尽而又简单的方案.今天终于摸索出来在Unity3D中使用Kinect的方法,特此做个笔记. 一.Unity和Kine ...

  7. Unity3D 学习笔记4 —— UGUI+uLua游戏框架

    Unity3D 学习笔记4 -- UGUI+uLua游戏框架 使用到的资料下载地址以及基础知识 框架讲解 拓展热更过程 在这里我们使用的是uLua/cstolua技术空间所以提供的UGUI+uLua的 ...

  8. unity3d开发鼠标打飞碟游戏(Hit UFO)

    这次我们用Unity3d开发一个简单的打飞碟游戏 游戏简介 游戏有3个回合,每个回合会发射n中颜色的飞碟,击中飞碟会得到相应的分数,其中,击中黄色飞碟得1分,击中蓝色飞碟得2分,红色飞碟4分,击不中不 ...

  9. Unity3D学习—打飞碟—工厂模式和适配器模式

    类图设计 工厂模式 在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象. 缺点就是每创建一个新的产品就需要创建一个新的工厂实例,会增加系统的复杂性.由于飞碟游戏中只有 ...

最新文章

  1. AR/QCA SPI 启动原理和 ART 地址定位原理
  2. boost::range模块reversed相关的测试程序
  3. java系统系统异常处理,银行系统(Java)异常处理
  4. C++ vector所有操作,你真的掌握vector了吗?两万总结带你干穿vector
  5. python 输入密码加密显示_如何在python中用密码加密文本?
  6. Lintcode 51.上一个排列[Medium]
  7. 48. Be aware of template metaprogramming
  8. IOS开发之页面跳转
  9. 关于wow(mangos模拟器) 的物品生成器---wowItemEdit 1.0
  10. 孙鑫VC学习笔记:第三讲 MFC应用程序框架
  11. linux6.8屏幕黑屏,centos6.8笔记本关盖就黑屏怎样设置不黑屏?
  12. 博弈论(四)——#10246. 「一本通 6.7 练习 3」取石子
  13. matlab coder 安装,MATLAB Coder
  14. java开发购物系统菜单_Java控制台购物系统
  15. 使用echart的小指南
  16. VScode退出全屏
  17. [源码和文档分享]基于JAVA的实现学生卡管理系统
  18. 基于STM32采集CO2(MH-Z19C)传感器数据
  19. 英语学习APP开发解决方案
  20. latex中biblatex参考文献的标点、分隔符、本地化字符串中英文切换

热门文章

  1. 交出2021年进步答卷,挚文集团如何做到稳中求进?
  2. 无线有线统一认证计费管理平台
  3. 李航《统计学习方法》学习日记【1】
  4. java 内置jetty_java内嵌jetty服务器
  5. qq三国单刀赴会服务器找不到,单刀赴会,收武器装备“图纸”,70-120等级,130级按套收,......
  6. 【搬运】射手播放器下载字幕存储位置及修改方法
  7. 计算机专业处理器和显卡,45.显卡篇-处理器显卡和独立显卡哪个好-电脑自学网...
  8. 越千年,是谁负了这情长
  9. bootstrap实战--微金所项目(轮播图1)
  10. 筒仓装车控制系统由哪几部分组成