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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

【Unity2D入门教程】简单制作战机弹幕射击游戏⑥最终回扩展其它范围的内容

發布時間:2024/3/26 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Unity2D入门教程】简单制作战机弹幕射击游戏⑥最终回扩展其它范围的内容 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

制作分數和生命的UI:

由于我們前面沒有做類似的UI所以這里教大伙一下基本思路:

首先我們創建一個canvas用來創建兩個Text用來顯示分數和生命的UI

藍色的是分數黃色的是生命

我們創建一個scoreplay的腳本掛載在text上

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class ScoreDisplay : MonoBehaviour {Text scoreText;GameSeesion gameSession;private void Start(){scoreText = GetComponent<Text>();gameSession = FindObjectOfType<GameSeesion>();}private void Update(){scoreText.text = gameSession.GetScore().ToString();} }

創建一個空對象gamesession還有一個同名腳本掛載在它上面:

接著我們改一下Player和Enemy的腳本

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Player : MonoBehaviour {[Header("玩家移動")][SerializeField] float ySpeed = 10f;[SerializeField] float xSpeed = 10f;[SerializeField] float padding = 1f;[Header("Play Health")][SerializeField] int health = 500;[Header("ProjectTile")][SerializeField] GameObject laserPrefab;[SerializeField] float projectTileSpeed = 10f;[SerializeField] float projectTileFiringPeriod = 0.1f;//戰機在屏幕能移動的坐標float xMin;float xMax;float yMin;float yMax;//協程的編程是指在不堵塞主線程的情況下執行某些特定的函數Coroutine fireCoroutine;[SerializeField] AudioClip deathSFX;[SerializeField] [Range(0, 1)] float deathSoundVolume = 0.75f;[SerializeField] AudioClip shootSFX;[SerializeField] [Range(0, 1)] float shootSoundVolume = 0.55f;void Start(){SetUpMoveBoundaries();}private void SetUpMoveBoundaries(){Camera gameCamera = Camera.main;//之前的視頻說過,Camera.main.ViewportToWorldPoint()是將攝像機視角的坐標轉化為世界坐標然后padding是防止戰機出屏幕邊緣xMin = gameCamera.ViewportToWorldPoint(new Vector3(0, 0, 0)).x + padding;xMax = gameCamera.ViewportToWorldPoint(new Vector3(1, 0, 0)).x - padding;yMin = gameCamera.ViewportToWorldPoint(new Vector3(0, 0, 0)).y + padding;yMax = gameCamera.ViewportToWorldPoint(new Vector3(0, 1, 0)).y - padding;}void Update(){Move();Fire();}private void Move(){//Input Manager上兩個監控鍵盤上WSAD按鍵而生成-1到1值的var deltaY = Input.GetAxis("Vertical") * Time.deltaTime * ySpeed;var deltaX = Input.GetAxis("Horizontal") * Time.deltaTime * xSpeed;// Debug.Log(deltaX);//限制移動范圍var newXPos = Mathf.Clamp(transform.position.x + deltaX, xMin, xMax);var newYPos = Mathf.Clamp(transform.position.y + deltaY, yMin, yMax);transform.position = new Vector2(newXPos,newYPos);}private void Fire(){if (Input.GetButtonDown("Fire1")){fireCoroutine = StartCoroutine(FireContinuously());}if (Input.GetButtonUp("Fire1"))//這個Fire1也是Input Manager上的{StopCoroutine(fireCoroutine); //暫停某個協程// StopAllCoroutines();}}//協程函數是用關鍵字迭代器IEnumerator而且一定要用yield關鍵詞返回IEnumerator FireContinuously(){while (true){GameObject laser = Instantiate(laserPrefab, transform.position, Quaternion.identity) as GameObject; //生成子彈laser.GetComponent<Rigidbody2D>().velocity = new Vector2(0, projectTileSpeed); //給子彈一個向上的力AudioSource.PlayClipAtPoint(shootSFX, Camera.main.transform.position, shootSoundVolume);yield return new WaitForSeconds(projectTileFiringPeriod); //下一顆子彈發生的間隔時間}}private void OnTriggerEnter2D(Collider2D other){DamageDealer damageDealer = other.gameObject.GetComponent<DamageDealer>();if (!damageDealer) { return; }ProcessHit(damageDealer);}private void ProcessHit(DamageDealer damageDealer){health -= damageDealer.GetDamage(); //減去收到的傷害damageDealer.Hit();if (health <= 0){Die();}}public int GetHealth(){return health;}private void Die(){Destroy(gameObject); //生命值為小于等于0就銷毀AudioSource.PlayClipAtPoint(deathSFX, Camera.main.transform.position, deathSoundVolume);} }

?

using System.Collections; using System.Collections.Generic; using UnityEngine;public class Enemy : MonoBehaviour {[Header("Enemy States")][SerializeField] float health = 100f;[SerializeField] int scoreValue = 150;[Header("Shooting")][SerializeField] float shotCounter;[SerializeField] float minTimeBetweenShots = 0.2f;[SerializeField] float maxTimeBetweenShot = 1.5f;[SerializeField] GameObject projecttile;[SerializeField] float projecttileSpeed = 10f;[Header("Sound Effects")][SerializeField] GameObject deathDFX;[SerializeField] AudioClip deathSFX;[SerializeField] [Range(0,1)]float deathSoundVolume = 0.75f;[SerializeField] AudioClip shootSFX;[SerializeField] [Range(0, 1)] float shootSoundVolume = 0.50f;void Start(){shotCounter = Random.Range(minTimeBetweenShots, maxTimeBetweenShot);}void Update(){CountDownAndShoot();}private void CountDownAndShoot(){shotCounter -= Time.deltaTime; //計時器,用來當計時器小于等于0時重置發射時間并執行發射函數if(shotCounter <= 0){Fire();shotCounter = Random.Range(minTimeBetweenShots, maxTimeBetweenShot);}}private void Fire(){GameObject laser = Instantiate(projecttile, transform.position, Quaternion.identity) as GameObject;//生成子彈并給它一個向下的力,因為和主角方向反過來的laser.GetComponent<Rigidbody2D>().velocity = new Vector2(0, -projecttileSpeed);AudioSource.PlayClipAtPoint(shootSFX, Camera.main.transform.position, shootSoundVolume);}private void OnTriggerEnter2D(Collider2D other){DamageDealer damageDealer = other.gameObject.GetComponent<DamageDealer>();if (!damageDealer) { return; }ProcessHit(damageDealer); //同樣也是傷害處理的函數}private void ProcessHit(DamageDealer damageDealer){ health -= damageDealer.GetDamage();damageDealer.Hit();if (health <= 0){Die();}}private void Die(){FindObjectOfType<GameSeesion>().AddToScore(scoreValue);Destroy(gameObject);GameObject explosion = Instantiate(deathDFX,transform.position,transform.rotation);Destroy(explosion, 1f);AudioSource.PlayClipAtPoint(deathSFX, Camera.main.transform.position,deathSoundVolume);} }

其次顯示生命值的腳本也要創建好

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class ScoreDisplay : MonoBehaviour {Text scoreText;GameSeesion gameSession;private void Start(){scoreText = GetComponent<Text>();gameSession = FindObjectOfType<GameSeesion>();}private void Update(){scoreText.text = gameSession.GetScore().ToString();} }

?


創建Start和Game Over場景

其實

其實我前面教的差不多了,這里就直接把預設體拖進來就好

?

這里的Score Canvas是只需要score即可不需要生命的text

別忘了掛載onclike()監聽事件


?

?

設置連貫的背景音樂:

為了防止音樂在切換場景時重新播放,我們也要創建一個單例給它

先空對象Music Player然后創建同名腳本

using System.Collections; using System.Collections.Generic; using UnityEngine;public class MusicPlayer : MonoBehaviour {private void Awake(){SetUpSingleton();}private void SetUpSingleton(){if(FindObjectsOfType(GetType()).Length > 1){Destroy(gameObject);}else{DontDestroyOnLoad(gameObject);}} }

別忘了讓它一直循環。


?

生成游戲:

別忘了放到build setting上然后點擊PlayerSetting改圖標

?

?游戲畫面如下:

?

?

?

總結

以上是生活随笔為你收集整理的【Unity2D入门教程】简单制作战机弹幕射击游戏⑥最终回扩展其它范围的内容的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 狠狠爱夜夜 | 中文字幕av解说 | 午夜影院网站 | 亚洲成人高清在线观看 | 免费看60分钟黄视频 | 潘金莲一级淫片a.aaaaa播放 | 国产大奶在线 | 日韩色婷婷 | 日本一区精品视频 | 亚洲在线网站 | 全黄一级裸体 | 人人九九精品 | 国产页| 99日精品| 国产精品久久久久无码av色戒 | 国产专区自拍 | 不卡的av在线免费观看 | 免费黄色国产 | 亚洲影视在线 | 强睡邻居人妻中文字幕 | 黄色观看网站 | 国产精品国产精品国产专区不片 | 无码国产69精品久久久久网站 | 蜜桃视频污在线观看 | 精品人伦一区二区三 | 国产精品人 | 制服一区二区 | 欧美午夜一区二区三区 | 亚洲爽爽爽 | 欧美三级午夜理伦三级老人 | 国产精品天干天干 | 成人欧美一区二区三区 | 91浏览器在线观看 | 美女露出让男生揉的视频 | 欧美亚一区二区三区 | 内射无码专区久久亚洲 | 影音先锋中文字幕资源 | 亚洲AV不卡无码一区二区三区 | 色臀av| 色眯眯影视 | 97国产在线播放 | 色婷婷av在线 | 性欧美大战久久久久久久免费观看 | 国内精品视频在线播放 | 男女日批网站 | 亚洲国产精品午夜久久久 | 激情福利社 | 三年大片在线观看 | 精品免费视频 | 91色伦 | 成人一二三 | 亚洲不卡视频在线 | av综合网站| 少妇人妻无码专区视频 | 96精品视频在线观看 | 蜜芽久久 | 欧美xxxx888 | 毛片在线免费观看网站 | 亚洲熟妇一区 | 欧亚av| 日韩欧美久久久 | 久久久久久国产精品三级玉女聊斋 | 亚洲天码中字 | 亚洲电影一区二区 | 久久亚洲伊人 | 自拍偷拍亚洲欧美 | 99热这里只有精品久久 | 毛片在线视频 | 男人的天堂99 | aaaaa黄色片 天堂网在线观看 | 亚洲欧美中文字幕5发布 | 91影音| 免费看黄色a级片 | 亚洲成人偷拍 | 人超碰| 精品国产乱码久久久久久108 | 国产老头户外野战xxxxx | 激情av小说 | 久久久亚洲av波多野结衣 | 成人看片网 | 国产一区二区精品在线观看 | 亚洲中文字幕无码一区二区三区 | 日本亲与子乱xxx | 日日干,夜夜操 | 天天操天天干天天 | 日日综合网| 黑人巨大av| av丝袜在线 | 一节黄色片 | 久在线观看 | av中文字| 在线观看三级视频 | 超碰人人干人人 | 无套内谢少妇高潮免费 | 亚洲中文字幕97久久精品少妇 | 国产草草 | 久久理伦| 中文字幕一区三区 | 亚洲精品观看 |