3D游戏设计第五次作业——打飞碟

3D游戏设计第五次作业——打飞碟 1代码架构
本次打飞碟游戏的代码架构是根据这几次课件构建的,主要涉及是mvc架构,动作管理器和工厂模式,代码文件如下:
UML图如下:
2 代码文件 2.1单实例类.cs
在整个项目中,有些类仅需要一个实例,如飞碟工厂、动作管理器、用户GUI,通过单实例类就可以实现获取这些实例 。
using System.Collections;using System.Collections.Generic;using UnityEngine;public class Singleton: MonoBehaviour where T:MonoBehaviour{protected static T instance;public static T Instance{get{if(instance==null){instance = (T)FindObjectOfType(typeof(T));if(instance == null){Debug.LogError("An instance of "+typeof(T) + " is needed in the scene,but there is none.");}}return instance;}}}
2.2 飞碟属性disk.cs
飞碟的大小、颜色、速度、运动方向各不相同,将这些属性都写在disk类中,之后作为飞碟的组件 。
【3D游戏设计第五次作业——打飞碟】using System.Collections;using System.Collections.Generic;using UnityEngine;public class disk :MonoBehaviour{// 颜色下标0-2public int color;// 大小下标0-2public int size;// 速度下标0-2public int speed;// 运动方向public Vector3 dir;// 初始位置public Vector3 pos;}
2.3飞碟工厂.cs
飞碟工厂完成获取飞碟和释放飞碟的功能 , 在Start方法中首先进行获取飞碟预制 , 然后再之后根据需要实例化 。
using System.Collections;using System.Collections.Generic;using UnityEngine;public class DiskFactory : MonoBehaviour{private List free = new List();private List used = new List();Color[] colors =new Color[3] {Color.cyan,Color.gray,Color.red};float []sizes = new float[3]{1.5F,1.0F,0.5F};GameObject pre;public GameObject getDisk(){GameObject obj;if(free.Count>0){obj = free[0].gameObject;free.RemoveAt(0);}else{obj = Instantiate(pre);obj.AddComponent();}// 颜色obj.GetComponent().color = Random.Range(0,3);obj.GetComponent().material.color = colors[obj.GetComponent().color];//大小obj.GetComponent().size = Random.Range(0,3);int t = obj.GetComponent().size;obj.transform.localScale = new Vector3(sizes[t],sizes[t],sizes[t]);//速度obj.GetComponent().speed = Random.Range(1,4);//方向obj.GetComponent().dir = new Vector3(Random.Range(2,4),Random.Range(0,2),0);//初始位置obj.GetComponent().pos = new Vector3(-6,0,0);obj.transform.position = obj.GetComponent().pos;used.Add(obj.GetComponent());return obj;}// Start is called before the first frame updatevoid Start(){pre = (GameObject)Resources.Load("prefabs/hitdisk/disk");}public void FreeDisk(disk dis){Debug.Log("factory free");foreach(disk d in used){if(d.gameObject.GetInstanceID()==dis.gameObject.GetInstanceID()){Debug.Log("find and free");free.Add(dis);used.Remove(dis);return;}}}}
2.4动作基类.cs
动作基类是后来实现飞行动作的父类,提供动作基类便于后续类调用动作类的方法 。

3D游戏设计第五次作业——打飞碟

文章插图
using System.Collections;using System.Collections.Generic;using UnityEngine;public class SSSAction :ScriptableObject{public bool enable = true;public bool destroy = false;public GameObject gameObject{get;set;}public Transform transform{get;set;}public IISSActionCallback callback{get;set;}protected SSSAction(){}// Start is called before the first frame updatepublic virtual void Start(){}// Update is called once per framepublic virtual void Update(){}}
2.5 飞行动作类.cs
飞行动作类在方法中实现物体的移动 , 这里我将飞行行动设置为简单的匀速直线运动 。当飞碟飞出屏幕或被点击时 , 即会调用回调函数通知动作管理器 。
using System.Collections;using System.Collections.Generic;using UnityEngine;public class CCFlyAction : SSSAction{public float speed;public Vector3 direction;public static CCFlyAction GetSSAction(Vector3 direction, float speed ){CCFlyAction action = ScriptableObject.CreateInstance();action.speed = speed;action.direction = direction;return action;}// Start is called before the first frame updatepublic override void Start(){}// Update is called once per framepublic override void Update(){if(this.enable==true){this.gameObject.transform.position += direction*speed*Time.deltaTime;if(this.gameObject.transform.position.y>5||this.gameObject.transform.position.y<-5||this.gameObject.transform.position.x>9){this.destroy = true;this.enable = false;this.callback.SSSActionEvent(this);}}}}
2.6 动作管理器基类.cs
使用方法为飞碟添加动作,并且开始动作 。在中根据动作的状态进行相应的操作 , 为真则将其添加在删除队列,为真则进行该动作 。
using System.Collections;using System.Collections.Generic;using UnityEngine;public class SSActionManager : MonoBehaviour{private Dictionary actions = new Dictionary();private List> waitingAdd = new List>();private List waitingDelete = new List();// Start is called before the first frame updatevoid Start(){}// Update is called once per frameprotected void Update(){foreach(SSSAction ac in waitingAdd) actions[ac.GetInstanceID()] = ac;waitingAdd.Clear();foreach(KeyValuePairkv in actions){SSSAction ac = kv.Value;if(ac.destroy){waitingDelete.Add(ac.GetInstanceID());}else if(ac.enable){ac.Update();}}foreach(int key in waitingDelete){SSSAction ac = actions[key];actions.Remove(key);Destroy(ac);}waitingDelete.Clear();}public void RunAction(GameObject gameobject,SSSAction action, IISSActionCallback manager){action.gameObject = gameobject;action.transform = gameobject.transform;action.callback = manager;waitingAdd.Add(action);action.Start();}}
2.7飞行动作管理器.cs
方法在接收到动作回调时,通知场景控制器释放飞碟 。方法Fly提供给场景控制器,使得场景控制器可以控制飞碟开始进行飞行动作 。
using System.Collections;using System.Collections.Generic;using UnityEngine;public class CCActionManager : SSActionManager, IISSActionCallback{public DiskSceneController sceneController;public CCFlyAction fly;// Start is called before the first frame updateprotected void Start(){sceneController = (DiskSceneController)SSSDirector.getInstance().currentSceneController;sceneController.actionManager = this;}public void Fly(GameObject disk, float speed, Vector3 dir){fly = CCFlyAction.GetSSAction(dir,speed);RunAction(disk, fly, this);}// Update is called once per frameprotected new void Update(){base.Update();}#region IISSActionCallback implementationpublic void SSSActionEvent(SSSAction source, SSActionEventType events = SSActionEventType.Completed,int intParam = 0,string strParam = null, Object objectParam = null){// Debug.Log("manager free");sceneController.FreeDisk(source.gameObject);}#endregion}
2.8 动作回调接口.cs
该接口实现了方法 , 是用于动作管理器在动作完成时接收到动作完成的消息,从而进行相应释放物体操作 。
using System.Collections;using System.Collections.Generic;using UnityEngine;public enum SSActionEventType:int{Started, Completed}public interface IISSActionCallback{void SSSActionEvent(SSSAction source,SSActionEventType events = SSActionEventType.Completed,int intParam = 0,string strParam = null,Object objectParam = null);}
2.9 用户动作接口.cs
该接口提供了用户交互会涉及到的几个方法 。
using System.Collections;using System.Collections.Generic;using UnityEngine;public interface IIUserAction{GameState getGS();void GameOver();void gameStart();void Hit(Vector3 pos);}
3D游戏设计第五次作业——打飞碟

文章插图
2.10 用户交互类.cs
用户交互类响应用户鼠标的点击动作,当点击物体时调用场景控制器的Hit方法 , 当点击开始按钮时即开始游戏 。
using System.Collections;using System.Collections.Generic;using UnityEngine;public enum GameState{ running,start,end,beforeStart}public class UUserGUI : MonoBehaviour{int score=0;private IIUserAction action;// Start is called before the first frame updatevoid Start(){Debug.Log("action init");action = SSSDirector.getInstance().currentSceneController as IIUserAction;Debug.Log("action name"+action.ToString());}public void setScore(int s){score = s;}// Update is called once per framevoid OnGUI(){GUI.Label(new Rect(10,10,100,50),"得分:"+score);// if(action.getGS() != GameState.running){if(action.getGS()!=GameState.running){if(GUI.Button(new Rect(100,150,100,50),"开始")){action.gameStart();}}if(Input.GetMouseButtonDown(0)){action.Hit(Input.mousePosition);}if(action.getGS()==GameState.end){GUI.Label(new Rect(Screen.width/2-50,Screen.height/2-25,100,50),"游戏结束!");}// }}}
2.11 场景控制器接口.cs
场景控制器接口提供一个场景控制器应该实现的几个方法 。
using System.Collections;using System.Collections.Generic;using UnityEngine;public interface IISceneController{void LoadResources();void Pause();void Resume();}
2.12 飞碟场景控制器.cs
场景控制器实现游戏的逻辑,完成丢飞盘、获取游戏状态、释放飞盘、重新开始游戏等的方法 。
using System.Collections;using System.Collections.Generic;using UnityEngine;public class DiskSceneController : MonoBehaviour, IISceneController, IIUserAction{float time = 0;int throwCount = 0;public int disknum = 10;public GameState state = GameState.beforeStart;int score = 0;DiskFactory diskfactory;public CCActionManager actionManager;UUserGUI usergui;//要移动的物体public GameObject obj;// Start is called before the first frame updatevoid Start(){SSSDirector director = SSSDirector.getInstance();director.currentSceneController = this;gameObject.AddComponent();gameObject.AddComponent();gameObject.AddComponent();LoadResources();}public void LoadResources(){diskfactory = Singleton.Instance;usergui = Singleton.Instance;actionManager = Singleton.Instance;}public void Hit(Vector3 pos){Ray ray = Camera.main.ScreenPointToRay(pos);RaycastHit hit;bool isCollider = Physics.Raycast(ray, out hit);if(isCollider){var fa = hit.collider.gameObject.transform.parent;fa.position = new Vector3(0,-6,0);score += countScore(fa.gameObject.GetComponent());usergui.setScore(score);}}public GameState getGS(){return state;}private int countScore(disk d){return d.color + d.size +4- d.speed;}public void Pause(){}public void Resume(){throwCount = 0;time = 0;score = 0;usergui.setScore(0);}void Update(){if(state==GameState.running){if(throwCount>=20){state = GameState.end;}time += Time.deltaTime;if(time>0.5){time = 0;for(int i = 0;i<3;i++){throwCount++;ThrowDisk();}}}}public void ThrowDisk(){GameObject disk = diskfactory.getDisk();actionManager.Fly(disk, disk.GetComponent().speed,disk.GetComponent().dir);}public void gameStart(){Resume();state = GameState.running;}public void FreeDisk(GameObject disk){Debug.Log("scene free");diskfactory.FreeDisk(disk.GetComponent());}public void GameOver(){}}
2.13导演类.cs
方法获得当前的场景控制器,是静态成员变量 , 因此总是只有一个场景控制器 。
using System.Collections;using System.Collections.Generic;using UnityEngine;public class SSSDirector : System.Object{private static SSSDirector _instance;public IISceneController currentSceneController{get;set;}public bool running{get;set;}public static SSSDirector getInstance(){if(_instance == null){_instance = new SSSDirector();}return _instance;}}
3 视频展示和代码链接
视频链接:
代码链接:
提交的代码去掉了天空盒 。