3D游戏设计第五次作业

2024-01-06 09:50

本文主要是介绍3D游戏设计第五次作业,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

1代码架构

本次打飞碟游戏的代码架构是根据这几次课件构建的,主要涉及是mvc架构,动作管理器和工厂模式,代码文件如下:
在这里插入图片描述
UML图如下:
在这里插入图片描述

2 代码文件

2.1单实例类Singleton.cs

在整个项目中,有些类仅需要一个实例,如飞碟工厂、动作管理器、用户GUI,通过单实例类就可以实现获取这些实例。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Singleton<T>: 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类中,之后作为飞碟的组件。

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飞碟工厂DiskFactory.cs

飞碟工厂完成获取飞碟和释放飞碟的功能,在Start方法中首先进行获取飞碟预制,然后再之后根据需要实例化。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class DiskFactory : MonoBehaviour
{private List<disk> free = new List<disk>();private List<disk> used = new List<disk>();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<disk>();}// 颜色obj.GetComponent<disk>().color = Random.Range(0,3);obj.GetComponent<MeshRenderer>().material.color = colors[obj.GetComponent<disk>().color];//大小obj.GetComponent<disk>().size = Random.Range(0,3);int t = obj.GetComponent<disk>().size;obj.transform.localScale = new Vector3(sizes[t],sizes[t],sizes[t]);//速度obj.GetComponent<disk>().speed = Random.Range(1,4);//方向obj.GetComponent<disk>().dir = new Vector3(Random.Range(2,4),Random.Range(0,2),0);//初始位置obj.GetComponent<disk>().pos = new Vector3(-6,0,0);obj.transform.position = obj.GetComponent<disk>().pos;used.Add(obj.GetComponent<disk>());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动作基类SSSAction.cs

动作基类是后来实现飞行动作的父类,提供动作基类便于后续类调用动作类的方法。

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 飞行动作类CCFlyAction.cs

飞行动作类在Update方法中实现物体的移动,这里我将飞行行动设置为简单的匀速直线运动。当飞碟飞出屏幕或被点击时,即会调用回调函数通知动作管理器。

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<CCFlyAction>();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 动作管理器基类SSActionManager.cs

使用RunAction方法为飞碟添加动作,并且开始动作。在Update中根据动作的状态进行相应的操作,destroy为真则将其添加在删除队列,enable为真则进行该动作。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class SSActionManager : MonoBehaviour
{private Dictionary<int,SSSAction> actions = new Dictionary<int,SSSAction>();private List<SSSAction> waitingAdd = new List<SSSAction>();private List<int> waitingDelete = new List<int>();// 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(KeyValuePair<int,SSSAction>kv 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飞行动作管理器CCActionManager.cs

方法SSActionEvent在接收到动作回调时,通知场景控制器释放飞碟。方法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 动作回调接口IISSActionCallback.cs

该接口实现了SSSActionEvent方法,是用于动作管理器在动作完成时接收到动作完成的消息,从而进行相应释放物体操作。

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 用户动作接口IIUserAction.cs

该接口提供了用户交互会涉及到的几个方法。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public interface IIUserAction{GameState getGS();void GameOver();void gameStart();void Hit(Vector3 pos);
}

2.10 用户交互类UUserGUI.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 场景控制器接口IISceneController.cs

场景控制器接口提供一个场景控制器应该实现的几个方法。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public interface IISceneController{void LoadResources();void Pause();void Resume();
}

2.12 飞碟场景控制器DiskSceneController.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<DiskFactory>();gameObject.AddComponent<CCActionManager>();gameObject.AddComponent<UUserGUI>();LoadResources();}public void LoadResources(){diskfactory = Singleton<DiskFactory>.Instance;usergui = Singleton<UUserGUI>.Instance;actionManager = Singleton<CCActionManager>.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<disk>());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<disk>().speed,disk.GetComponent<disk>().dir);}public void gameStart(){Resume();state = GameState.running;}public void FreeDisk(GameObject disk){Debug.Log("scene free");     diskfactory.FreeDisk(disk.GetComponent<disk>());}public void GameOver(){}
}

2.13导演类SSSDirector.cs

getInstance方法获得当前的场景控制器,_instance是静态成员变量,因此总是只有一个场景控制器。

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 视频展示和代码链接

视频链接:https://www.bilibili.com/video/BV1rP4y117Sx/?vd_source=aa1381bc757a530f161653f21b4b7d29
代码链接:https://gitee.com/k_co/3-d-games/tree/master/HW5
提交的代码去掉了天空盒。

这篇关于3D游戏设计第五次作业的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/575963

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

作业提交过程之HDFSMapReduce

作业提交全过程详解 (1)作业提交 第1步:Client调用job.waitForCompletion方法,向整个集群提交MapReduce作业。 第2步:Client向RM申请一个作业id。 第3步:RM给Client返回该job资源的提交路径和作业id。 第4步:Client提交jar包、切片信息和配置文件到指定的资源提交路径。 第5步:Client提交完资源后,向RM申请运行MrAp

怎么让1台电脑共享给7人同时流畅设计

在当今的创意设计与数字内容生产领域,图形工作站以其强大的计算能力、专业的图形处理能力和稳定的系统性能,成为了众多设计师、动画师、视频编辑师等创意工作者的必备工具。 设计团队面临资源有限,比如只有一台高性能电脑时,如何高效地让七人同时流畅地进行设计工作,便成为了一个亟待解决的问题。 一、硬件升级与配置 1.高性能处理器(CPU):选择多核、高线程的处理器,例如Intel的至强系列或AMD的Ry

国产游戏崛起:技术革新与文化自信的双重推动

近年来,国产游戏行业发展迅猛,技术水平和作品质量均得到了显著提升。特别是以《黑神话:悟空》为代表的一系列优秀作品,成功打破了过去中国游戏市场以手游和网游为主的局限,向全球玩家展示了中国在单机游戏领域的实力与潜力。随着中国开发者在画面渲染、物理引擎、AI 技术和服务器架构等方面取得了显著进展,国产游戏正逐步赢得国际市场的认可。然而,面对全球游戏行业的激烈竞争,国产游戏技术依然面临诸多挑战,未来的

基于51单片机的自动转向修复系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机

MiniGPT-3D, 首个高效的3D点云大语言模型,仅需一张RTX3090显卡,训练一天时间,已开源

项目主页:https://tangyuan96.github.io/minigpt_3d_project_page/ 代码:https://github.com/TangYuan96/MiniGPT-3D 论文:https://arxiv.org/pdf/2405.01413 MiniGPT-3D在多个任务上取得了SoTA,被ACM MM2024接收,只拥有47.8M的可训练参数,在一张RTX

SprinBoot+Vue网络商城海鲜市场的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍:CSDN认证博客专家,CSDN平台Java领域优质创作者,全网30w+

单片机毕业设计基于单片机的智能门禁系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍程序代码部分参考 设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订

火柴游戏java版

代码 /*** 火柴游戏* <p>* <li>有24根火柴</li>* <li>组成 A + B = C 等式</li>* <li>总共有多少种适合方式?</li>* <br>* <h>分析:</h>* <li>除去"+"、"="四根,最多可用火柴根数20根。</li>* <li>全部用两根组合成"1",最大数值为1111。使用枚举法,A和B范围在0~1111,C为A+B。判断</li>** @