日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Unity3d--改进飞碟游戏 作业6

發布時間:2023/12/20 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Unity3d--改进飞碟游戏 作业6 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

3dgame 作業6

1. 作業內容

改進飛碟(Hit UFO)游戲:

游戲內容要求:

  • 按 adapter模式 設計圖修改飛碟游戲
  • 使它同時支持物理運動與運動學(變換)運動
  • 2. 游戲配置

  • 游戲中共有三種飛碟,創建好三個飛碟的預制類。
  • 在三個預制類中分別添加Disk腳本,并且設置好每個預制類的大小。
  • 創建好三種飛碟不同的材質,并添加。
  • 創建一個空對象,并將SceneController添加到該對象中,即可運行。
  • 3. UML類圖

    • 與上一次作業相比,多了一個PhysicAction用于給物體添加重力影響,還有就是添加了一個ActionAdapter,與PhysicAction 和MoveToAction關聯,從而從而使得SceneController更加容易的調用物體運動的方法。

    4. 分析

    1. 適配器模式(Adapter Pattern):

    將一個接口轉換成客戶希望的另一個接口,使接口不兼容的那些類可以一起工作。適配器模式既可以作為類結構型模式,也可以作為對象結構型模式。在適配器模式中,我們通過增加一個新的適配器類來解決接口不兼容的問題,使得原本沒有任何關系的類可以協同工作。

    根據適配器類與適配者類的關系不同,適配器模式可分為對象適配器和類適配器兩種,在對象適配器模式中,適配器與適配者之間是關聯關系;在類適配器模式中,適配器與適配者之間是繼承(或實現)關系。

    這里使用了ActionAdapter與PhysicAction 和MoveToAction關聯,從而更加方便的調用SSAction接口的方法。

    2. 物理運動與運動學(變換)運動

    物理運動包括物體的碰撞以及物體的重力影響,重力影響可以通過給物體添加一個逐漸均勻變大的速度實現。而物體的碰撞以及運動學變換可以通過給對象添加unity內置的DigidBody實現,添加之后,對象就會擁有與真實情況相同的物理特性,包括與物理碰撞之后的反應,以及可以對物體施加力的作用進行加速。

    5. 代碼

    • UnitySingleton類
    • 給每個需要單實例化的類繼承,包括SceneController、DiskProductor、ScoreRecorder讓其可以單實例話,同時可以靜態被其他類調用。
    public class UnitySingleton<T> : MonoBehaviour where T : Component {//用于單例實例化protected static T _instance;public static T Instance() {if (_instance == null) { _instance = FindObjectOfType(typeof(T)) as T;if (_instance == null) {GameObject obj = new GameObject();obj.name = typeof(T).ToString();_instance = obj.AddComponent<T>();}}return _instance;} }
    • SceneCotnroller
    • 場景總控制類,調用各個接口以及創建、添加所需要的對象。
    using System.Collections; using System.Collections.Generic; using UnityEngine;[System.Serializable]public class SceneController : UnitySingleton<SceneController>{public static int roundNum = 10; //回合數量public static int trialNumber = 10; //每個Round有多少個trialpublic float[] level = new float[roundNum]; //記錄每個round出現的時間間隔,每個round的記錄難度public float random; //時間間隔隨機部分的范圍private float time; //用于計時private float timeInterval; //記錄時間間隔[SerializeField] private int round; //round記錄第幾個回合[SerializeField] private int trial; //count記錄第幾個trialpublic bool gameStart;public ActionAdapter action; //動作管理對象void Awake() {_instance = this;for (int i = 0; i < roundNum; i++) { //初始化每個round的難度,round值越大,時間間隔越小,難度越高level [i] = 2f - 0.1f * roundNum;}time = 0; timeInterval = 0; round = 0; trial = 0;gameStart = false; //游戲初始狀態為等待random = 0.1f; //飛碟時間隨機浮動范圍action = gameObject.AddComponent<ActionAdapter> () as ActionAdapter;gameObject.AddComponent<UserGUI> (); //添加用戶界面DiskProductor.Instance(); //初始化disk對象創建工廠ScoreRecorder.Instance(); //初始化計分器}void Update() {if (gameStart) { //判斷游戲是否已經開始time += Time.deltaTime;if (time < timeInterval) //時間沒到返回return; else { //時間到創建disk,并且計算得到下一次創建的時間間隔trial ++;CreateDisk (Random.Range(1, round + 1 / 2));time -= timeInterval;timeInterval = level [round] + Random.Range (-random, random);if (trial < trialNumber)return; trial = 0; //一個回合結束if (round < 9)round++;}}}void CreateDisk(int num) {//生成隨機位置,調用disk工廠創建diskfloat py = Random.Range (0, 4);for (int i = 0; i < num; i++) { //隨機創建多個飛碟Vector3 pos = new Vector3 (10f, py + i * 2, 0); //為了開始不碰撞,均勻分配disk的位置Vector3 v = new Vector3 (-10f, Random.Range (-0.2f, 0.2f), 0);int kind = Random.Range (0, 3); //隨機選擇三種飛碟的一種//創建disk,并且通過adapter給disk創建運動對象Disk tem = DiskProductor.Instance ().Create (pos, v, 5f, kind);action.moveDisk (tem.gameObject, tem.velocity * (tem.kind + 1), 50);}}public void Reset() { //重置函數time = 0; timeInterval = 0; round = 0; trial = 0;DiskProductor.Instance ().Reset ();ScoreRecorder.Instance ().Reset ();}public int GetRoundIndex() { //獲得回合數return round;} }
    • Disk
    • 每個飛碟對象的腳本類,存儲每個了飛碟的信息,以及返回對象池、運動的方法。
    using System.Collections; using System.Collections.Generic; using UnityEngine;public class Disk : MonoBehaviour {private float timeLeave; //記錄每個disk剩余飛行的時間public Vector3 velocity; //每個飛碟的基礎速度,disk的速度由基礎速度與種類決定public GameObject nextDisk; //記錄下一個空閑的飛碟public int poolIndex; //記錄該飛碟對象在對象池中的位置public ClickGUI clickgui; //每個飛碟的鼠標點擊響應腳本public int kind; //記錄每個飛碟對象的類型public Rigidbody rigid;bool enableEmit = true;void Awake() {timeLeave = 0;/**創建、設置飛碟腳本 */clickgui = this.gameObject.AddComponent(typeof(ClickGUI)) as ClickGUI;rigid = this.gameObject.AddComponent<Rigidbody> ();clickgui.setDisk(this);}public void init(Vector3 _position, Vector3 _velocity, float _lifeTime) {this.transform.position = _position;timeLeave = _lifeTime;velocity = _velocity;}void Update() {timeLeave -= Time.deltaTime;if (timeLeave < 0 || gameObject.transform.position.y < -5 || gameObject.transform.position.x < -10) //時間到了,返回到對象池ReturnToPool();}public void ReturnToPool() {gameObject.GetComponent<Rigidbody>().velocity = Vector3.zero;DiskProductor.Instance().Return(poolIndex, kind);} }
    • ScoreRecorder
    • 記錄分數
    public class ScoreRecorder : UnitySingleton<ScoreRecorder> {public int score; //分數void Start () {score = 0;}//記錄分數public void AddPoint(int point) {score += point;}public void Reset() {score = 0;} }
    • ClickGUI
    • 與上次作業類似,給每一個飛碟對象使用。不同的是點擊后分數增加、調用對象的返回對象池函數。
    public class ClickGUI : MonoBehaviour {// Use this for initializationDisk disk;public void setDisk(Disk disk){this.disk = disk;}void OnMouseDown(){ScoreRecorder.Instance ().AddPoint (disk.kind + 1);disk.ReturnToPool ();} }
    • UserGUI
    • 用戶界面,包括游戲重啟、游戲開始,分數、回合顯示。
    public class UserGUI : MonoBehaviour{private GUIStyle MyStyle;private GUIStyle MyButtonStyle;void Start() {MyStyle = new GUIStyle ();MyStyle.fontSize = 20;MyStyle.normal.textColor = new Color (255f, 0, 0);MyButtonStyle = new GUIStyle ("button");MyButtonStyle.fontSize = 30;}void OnGUI() {//回合顯示GUI.Label (new Rect (10, 10, 100, 20), "Round:" + (SceneController.Instance ().GetRoundIndex () + 1), MyStyle);//分數顯示GUI.Label (new Rect (10, 40, 100, 20), "Score:" + (ScoreRecorder.Instance().score), MyStyle);if (SceneController.Instance ().gameStart) {//重啟if (GUI.Button (new Rect (Screen.width / 2 - 75, 20, 150, 50), "Restart", MyButtonStyle)) {SceneController.Instance ().Reset ();SceneController.Instance ().gameStart = false;}} else {//游戲開始if (GUI.Button (new Rect (Screen.width / 2 - 75, 20, 150, 50), "Start", MyButtonStyle)) {SceneController.Instance ().gameStart = true;}}} }
    • MoveToAction類

    • 物體運動的實現。將之前的每一幀移動改為添加一個力,同時修改為使用FixedUpdate實現運動,為了物體做勻速運動,只需要給物體添加一次力,所以該類的addforce只調用一次,同時在調用完后會被釋放。

    using System.Collections; using System.Collections.Generic; using UnityEngine;public class SSMoveToAction : SSAction //移動 {public Vector3 dest; //移動到的目的地public float speed; //移動速度public bool enableEmit = true;public Vector3 force;private SSMoveToAction() { }public static SSMoveToAction GetSSAction(Vector3 force, float speed) {SSMoveToAction action = ScriptableObject.CreateInstance<SSMoveToAction>();//創建實例action.force = force;action.speed = speed;return action;}public override void Update() {}public override void FixedUpdate() { //給物體添加力的時候需要使用FixedUpdate函數if(!this.destroy) { if(enableEmit) { //給物體添加一個力,從而給物體一個初速度gameobject.GetComponent<Rigidbody>().AddForce(force, ForceMode.Impulse);enableEmit = false;}this.destroy = true; //添加完力就進入回收隊列this.callback.SSActionEvent(this); }}public override void Start() {//移動過程無動作} }
    • PhysicAction

    • 通過Rigidbody中的velocity屬性實現物理的重力影響,每次調用都會增加物體向下的速度。

    using System.Collections; using System.Collections.Generic; using UnityEngine;public class PhysicAction : SSAction { float acceleration; //重力加速度private PhysicAction() { }public static PhysicAction GetPhysicAction() {PhysicAction action = ScriptableObject.CreateInstance<PhysicAction>();//創建實例return action;}public override void Start () {acceleration = 9.8f;}public override void Update () {if (gameobject.activeSelf) { //物體運動期間,每隔一個時間單位,物體的速度會加上一個agameobject.GetComponent<Rigidbody> ().velocity += Vector3.down * acceleration * Time.deltaTime;} else { //disk返回后回收該動作對象this.destroy = true;this.callback.SSActionEvent(this); }}public override void FixedUpdate() {} }
    • ActionAdapter類

    • 將物體兩個運動創建的接口MoveToAction、PhysicAction,轉化為主控制器直接使用的接口。

    using System.Collections; using System.Collections.Generic; using UnityEngine;public class ActionAdapter : SSActionManager{private SSMoveToAction movedisk;private PhysicAction physic;public SceneController sceneController;public void Start(){sceneController = SceneController.Instance();sceneController.action = this;}public void moveDisk(GameObject disk, Vector3 dest, float speed) {movedisk = SSMoveToAction.GetSSAction (dest, speed); //獲得被是配的對象this.RunAction (disk, movedisk, this); //調用被是配對象的函數physic = PhysicAction.GetPhysicAction ();this.RunAction (disk, physic, this);} }

    游戲圖片以及視頻、代碼地址。

    視頻地址:https://www.bilibili.com/video/av70686629/

    或者:hw6.mov

    代碼地址:https://github.com/ouzj5/3dgame/tree/master/hw6

    總結

    以上是生活随笔為你收集整理的Unity3d--改进飞碟游戏 作业6的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。