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);            }        }    }}



1 0