Unity简单2D游戏开发
Unity簡(jiǎn)單2D游戲開發(fā)
前言:
近日比較無聊,在b站找了一個(gè)up主,跟著他的教程來做游戲——開發(fā)一個(gè)簡(jiǎn)單的2D游戲
?
?
?
?
?
?
?
?
用 Tilemap 繪制場(chǎng)景
新建一個(gè)2D項(xiàng)目,在Unity Asset Store中搜索下載 “Pixel Adventure?”,第一個(gè)就是我們需要的
然后我們?cè)趙indow中的package manager中搜索下載一個(gè) Tilemap管理2D
安裝完成后,在我們的界面中新建一個(gè)Tilemap,并將子物體復(fù)制兩份,并以此修改Layer為0、1、2,方便放置不同物體在不同層
然后在window中找到2D下的TilePalette面板,新建一個(gè)new Palette,并取名“Adventure ”,放在一個(gè) palette目錄下
tile:瓷磚、地磚
palette:調(diào)色板
?
我們現(xiàn)在來導(dǎo)入資源,我們要先用到這個(gè)項(xiàng)目資源包中的 Terrain Sliced (16×16),這個(gè)文件,找到他,并且做一些屬性修改
?
Unity中自動(dòng)給它調(diào)成100像素,但我們的素材其實(shí)是16像素,所以我們改成16,另外MaxSize為1024就足夠用了,應(yīng)用設(shè)定。
然后將這個(gè)資源拖入Tile Palette 中。
然后就可以開畫了,我們先畫background
然后做border(是border:邊框,不是board,我聽錯(cuò)了,不好意思)
?
然后做這個(gè)footground(這是應(yīng)該是Foreground)
大致場(chǎng)景先做成這樣了
人物的等待和跑動(dòng)
我們將資源下面有個(gè) pink man目錄,將下面的 idle 動(dòng)畫拖入場(chǎng)景中,并指定一個(gè)新層(Player),并且按6,6放大:
人物出現(xiàn)!
我們將它放到左邊合適的位置,然后我們給人物添加2D剛體和2D碰撞盒,剛體注意凍結(jié)z軸避免以后發(fā)生突破次元的旋轉(zhuǎn),此時(shí),啟動(dòng)游戲,人物就會(huì)受重力影響下墜。
Unity很強(qiáng)大,它自帶了一個(gè) Tilemap Collider 2D來給“tile地板”做碰撞檢測(cè),我們選住border和footground來添加這個(gè)組件,OK,碰撞檢測(cè)就沒有問題了。
然后我們創(chuàng)建動(dòng)畫,先創(chuàng)建Idle,新建動(dòng)畫狀態(tài)機(jī),將Idle的一幫子圖片拖進(jìn)去,調(diào)整好速度,就大功告成。
同樣的道理,我們?cè)賱?chuàng)建跑步的動(dòng)畫。
然后我們?cè)趧?dòng)畫狀態(tài)機(jī)中創(chuàng)建一個(gè)混合樹來混合Idle和Run動(dòng)畫,用變量speed來控制兩個(gè)動(dòng)畫的轉(zhuǎn)變。
動(dòng)畫做好就是加入腳本的事情了
給主角掛載一個(gè)Player.cs
public class Player : MonoBehaviour {private int speedID = Animator.StringToHash("speed");public float speed = 5; //移動(dòng)速度private Animator _anim;private Rigidbody2D _rigidbody;private float x;void Start(){_anim = GetComponent<Animator>();_rigidbody = GetComponent<Rigidbody2D>();}void Update(){//x的范圍是-1到1x = Input.GetAxis("Horizontal");if (x > 0){ //正向移動(dòng)_rigidbody.transform.eulerAngles = new Vector3(0, 0, 0);_anim.SetFloat(speedID, 1);}if(x<0) {//反向移動(dòng)_rigidbody.transform.eulerAngles = new Vector3(0, 180, 0);_anim.SetFloat(speedID, 1);}if (x < 0.001f && x > -0.001f) {_anim.SetFloat(speedID, 0);}Run();}private void Run() {Vector3 movement = new Vector3(x, 0, 0);_rigidbody.transform.position += movement * speed * Time.deltaTime;} }2D的人物控制多是控制在剛體上,如果是3D的就可以控制在charactor controller上。
跳躍
給人物新建一個(gè)腳本——Jump.cs
public class Jump : MonoBehaviour {public float jumpVelocity = 5f;private Rigidbody2D _rigid;private int _jumpID = Animator.StringToHash("jump");private bool _jumpRequest = false;// Start is called before the first frame updatevoid Start(){_rigid = GetComponent<Rigidbody2D>(); }// Update is called once per framevoid Update(){if (Input.GetButtonDown("Jump")) {_jumpRequest = true;}}//這里為什么要用fixedUpdate?//因?yàn)槲覀兪菍?duì)剛體操作,這會(huì)和物理引擎發(fā)生強(qiáng)關(guān)聯(lián)//Unity的物理引擎是按照時(shí)間來更新的,FixedUpdate就是按照時(shí)間更新//而update是按幀更新,不同機(jī)子可能幀數(shù)不同,從而跳的高度、速度不同private void FixedUpdate(){if (_jumpRequest) {//給剛體上方來一個(gè)力,力的方式是不斷疊加_rigid.AddForce(Vector2.up * jumpVelocity, ForceMode2D.Impulse);_jumpRequest = false;}} }此時(shí)我們就可以實(shí)現(xiàn)基本的跳躍,但是我們會(huì)發(fā)現(xiàn)一個(gè)問題,跳躍的比較“沒勁”,就像是飄著一樣,所以我們?cè)俳o人物添加一個(gè)完善跳躍的腳本
public class BetterJump : MonoBehaviour {//跳躍下降時(shí)的加速度public float fallMultiplier = 2.5f;//跳躍上升時(shí)的加速度public float lowJumpMultiplier = 2f;private Rigidbody2D _rigid;private void Start(){_rigid = GetComponent<Rigidbody2D>();}private void FixedUpdate(){//y方向速度小于0,在下降if (_rigid.velocity.y < 0){_rigid.gravityScale = fallMultiplier;}//y方向在上升且沒有按下空格(即點(diǎn)了一下空格)else if (_rigid.velocity.y > 0 && Input.GetButtonDown("Jump")){_rigid.gravityScale = lowJumpMultiplier;}else {_rigid.gravityScale = 1;}} }跳躍效果非常成功,但是我們發(fā)現(xiàn)出現(xiàn)了一個(gè)意想不到的情況,人物可以被卡在邊緣。
這是因?yàn)槿宋飹燧d的碰撞盒與Tilemap的碰撞盒掛住了,我們可以給人物換成 Capsule Collider 2D
?
跳躍觸地檢測(cè)
為了避免人物可以連跳的情況,我們給人物的腳底加上一個(gè)檢測(cè)盒子
先給人物再掛一個(gè)腳本——JumpBox,我們會(huì)用這個(gè)腳本代替上面的Jump.cs腳本
腳本內(nèi)容:
public class JumpBox : MonoBehaviour {//跳躍向上給的力(前面的[Range(0, 10)]是方便在Unity界面中用線條調(diào)整)[Range(0, 10)] public float jumpVelocity = 5;//檢測(cè)層public LayerMask msk;//檢測(cè)盒子高度public float boxHeight;private Vector2 _playerSize;private Vector2 _boxSize;private bool _jumpRequest = false;private bool _grounded=false;private Rigidbody2D _rigid;private void Start(){_rigid = GetComponent<Rigidbody2D>();_playerSize = GetComponent<SpriteRenderer>().bounds.size;_boxSize = new Vector2(_playerSize.x* 0.4f, boxHeight);}private void Update(){//按下空格且在地上,則可以跳躍if (Input.GetButtonDown("Jump") && _grounded) {_jumpRequest = true;}}private void FixedUpdate(){if (_jumpRequest){//給剛體上方來一個(gè)力,力的方式是不斷疊加_rigid.AddForce(Vector2.up * jumpVelocity, ForceMode2D.Impulse);_jumpRequest = false;//跳躍就離開地面了_grounded = false;}else{//得到檢測(cè)盒子的中心位置(任務(wù)位置偏下)Vector2 boxCenter = (Vector2)transform.position +Vector2.down * _playerSize.y * 0.5f;//利用射線檢測(cè)盒子if (Physics2D.OverlapBox(boxCenter, _boxSize, 0, msk) != null){//檢測(cè)到地面了_grounded = true;}else{_grounded = false;}}}//這個(gè)方法是方便在Scene窗口下生成線框幫助檢測(cè)private void OnDrawGizmos(){if (_grounded){Gizmos.color = Color.red;}else {Gizmos.color = Color.green;}Vector2 boxCenter = (Vector2)transform.position +Vector2.down * _playerSize.y * 0.5f;Gizmos.DrawWireCube(boxCenter, _boxSize);} }Gizmos:小玩意
我們可以測(cè)試一下,記得將boxHeight先調(diào)成0.5左右試一試,然后給Tilemap上的這幾層貼上層名,然后指定給腳本中的msk,最后還有 關(guān)了原來那個(gè)Jump.cs腳本,否則一下會(huì)跳的特別高。
OK,到這一步,連續(xù)跳躍的問題就解決了,通過射線盒子檢測(cè)控制一個(gè)變量,根據(jù)這個(gè)變量考慮該不該響應(yīng)玩家發(fā)起的跳躍請(qǐng)求。
順便一提,這個(gè)OnDrawGizmos方法以前我沒接觸過,是個(gè)很好用的調(diào)試方法,學(xué)到了。
物品收集
在資源中可以找到Fruits目錄,我們將里面的某個(gè)水果拖到場(chǎng)景中來,我就拿Apple舉例了。
老規(guī)矩,新建了一個(gè)排序?qū)印狪tems,然后將這個(gè)蘋果的Order in Layer 設(shè)置成了1,并且調(diào)整了縮放為 6,6。
然后將圖片拖到合適的位置之后,給它一個(gè) Circle Collider 2D,設(shè)置成觸發(fā)器。
同樣的道理,我們?cè)龠x擇Fruts下的Collected來做收集物品之后的效果。我們將第一個(gè)Collected拖到場(chǎng)景中,然后賦予新的動(dòng)畫狀態(tài)機(jī),動(dòng)畫內(nèi)容是這個(gè)Collected的這幾幀動(dòng)畫,然后,我們將這個(gè)Collected作為Apple的子物體,我給他起名字叫了CollectedEffect。
然后,給蘋果掛上代碼:
public class FruitItem : MonoBehaviour {private GameObject _collectedEffect;private SpriteRenderer _spriteRenderer;private CircleCollider2D _circleCollider2D;private void Start(){//得到圖片渲染組件_spriteRenderer = GetComponent<SpriteRenderer>();//圓形觸發(fā)器_circleCollider2D = GetComponent<CircleCollider2D>();//得到子物體-消失特效,并且先禁用它_collectedEffect = transform.Find("CollectedEffect").gameObject;_collectedEffect.SetActive(false);}private void OnTriggerEnter2D(Collider2D collision){//玩家觸發(fā)if (collision.gameObject.tag == "Player") {_spriteRenderer.enabled = false;_circleCollider2D.enabled = false;_collectedEffect.SetActive(true);//延時(shí)0.2秒后消失Destroy(gameObject,0.2f);}} }這一套思路很不錯(cuò),物體的子物體是物體的退場(chǎng)動(dòng)畫,一般是禁用的,當(dāng)物體被玩家觸發(fā)則激活子物體,子物體被喚醒播放動(dòng)畫展示效果,0.2秒后銷毀。
?
物品收集的UI界面展示
建立Canvas,右上角是水果圖片和一個(gè)分?jǐn)?shù)文字,圖片會(huì)循環(huán)播放動(dòng)畫,最后效果如下:
我們新建一個(gè)全局控制器——GameController來管理分?jǐn)?shù)更新
代碼內(nèi)容:
public class GameController : MonoBehaviour {public int totalScore=0;public Text scoreText;public static GameController Instance;private void Start(){Instance = this;updateScore();}public void updateScore() {scoreText.text = "分?jǐn)?shù):"+totalScore.ToString();} }然后在蘋果自身腳本的觸發(fā)檢測(cè)中加分并且調(diào)用這個(gè)updateScore,蘋果中的腳本的觸發(fā)檢測(cè):
private void OnTriggerEnter2D(Collider2D collision){//玩家觸發(fā)if (collision.gameObject.tag == "Player") {_spriteRenderer.enabled = false;_circleCollider2D.enabled = false;_collectedEffect.SetActive(true);GameController.Instance.totalScore += score;GameController.Instance.updateScore();//延時(shí)0.2秒后消失Destroy(gameObject,0.2f);}}OK!
添加地面陷阱
在資源的找到Spikes,地面尖刺,這個(gè)就是我們的地面陷阱
將陷阱拖到游戲場(chǎng)景中,新加一個(gè)排序?qū)印猅rap,然后把Tag也設(shè)設(shè)置成Trap,給物體改名Spike
很物體添加組件:Box Collider 2D,調(diào)整大小到和尖刺差不多。
做一個(gè)UI界面,是游戲失敗后重新開始的界面,并且在GameController腳本中這樣寫:
public void showGameOverPanel() {gameOverPanel.SetActive(true);gameOverPanel.transform.Find("Button").GetComponent<Button>().onClick.AddListener(()=> {SceneManager.LoadScene("Level1");});}給人物腳本Player.cs添加:
private void OnCollisionEnter2D(Collision2D collision){if (collision.gameObject.tag == "Trap") {Destroy(gameObject);GameController.Instance.showGameOverPanel();}}這樣一來
添加浮動(dòng)平臺(tái)
找到Falling Platforms 目錄,將里面的on的第一張圖片拖入場(chǎng)景合適的位置,修改排序?qū)訛門rap,并改縮放為6,6
然后給它添加剛體2D(凍結(jié)z軸),再添加組件Target Joint 2D (目標(biāo)關(guān)節(jié)),剛體會(huì)讓它下落,而Targe Joint可以讓他保持住位置
把Layer修改為新建的Trap,把那個(gè)人物可調(diào)躍圖層加上這個(gè)Trap。
剩下就是給平臺(tái)掛上腳本
public class FallingPlatform : MonoBehaviour {public float fallingTime = 3;private TargetJoint2D _targetJoint2D;private BoxCollider2D _boxCollider2D;// Start is called before the first frame updatevoid Start(){_targetJoint2D = GetComponent<TargetJoint2D>();_boxCollider2D = GetComponent<BoxCollider2D>();}private void OnCollisionEnter2D(Collision2D collision){if (collision.gameObject.tag == "Player") {Invoke("Falling",fallingTime);}}private void Falling() {_targetJoint2D.enabled = false;_boxCollider2D.isTrigger=false;} }彈力蹦床
在資源中找到Trampoline,將Idle拖入到場(chǎng)景中,并修改排序?qū)訛門rap,縮放比例為6、6,Layer層為Trap。
給它添加碰撞盒子并且調(diào)整縮放到一定大小。
然后我們給它做動(dòng)畫,一個(gè)Idle,一個(gè)Jump,做好之后Idle為默認(rèn)狀態(tài),Idle轉(zhuǎn)Jump的方式是一個(gè)觸發(fā)變量jump(Trigger變量),然后我們給彈力床掛新腳本
public class Trampoline : MonoBehaviour {public float jumpForce = 17;private Animator _anim;private int _JumpID = Animator.StringToHash("jump");void Start(){_anim = GetComponent<Animator>();}void Update(){}private void OnCollisionEnter2D(Collision2D collision){if (collision.gameObject.tag == "Player") {_anim.SetTrigger(_JumpID);collision.gameObject.GetComponent<Rigidbody2D>().AddForce(new Vector2(0, jumpForce), ForceMode2D.Impulse);}} }添加滾動(dòng)電鋸
我們找到電鋸(saw)的圖片,拖到場(chǎng)景中,老規(guī)矩——改排序?qū)印⒏膶印⒏目s放(4、4)。然后我們將它拖到某平臺(tái)上。
然后我們會(huì)遇到問題,該怎么樣將電鋸被平臺(tái)部分遮住呢?
我們新建一個(gè)排序?qū)觙oreground,然后將foreground設(shè)置為該層即可。
給電鋸添加碰撞盒來檢測(cè)玩家的碰撞,
然后給電鋸新建動(dòng)畫,電鋸的播放效果。
最后,通過腳本來實(shí)現(xiàn)電鋸的左右移動(dòng):
public class Saw : MonoBehaviour {//電鋸移動(dòng)方向public float speed = 2;//改變方向的時(shí)間public float moveTime =3;private bool _directionRight = true;//計(jì)時(shí)器private float _timer ;private void Update(){if (_directionRight){transform.Translate(Vector2.right * speed * Time.deltaTime);}else {transform.Translate(Vector2.left * speed * Time.deltaTime);}_timer += Time.deltaTime;if (_timer > moveTime) {_timer = 0;//這個(gè)取反操作好騷啊!_directionRight = !_directionRight;}} }這樣就可以實(shí)現(xiàn)電鋸的動(dòng)態(tài)效果了,下一步就是讓人物一碰到電鋸就會(huì)遭遇不測(cè)。
在Player的控制腳本中的碰撞檢測(cè)部分加入這些語句即可
if (collision.gameObject.tag == "Saw"){Destroy(gameObject);GameController.Instance.showGameOverPanel();}回到Unity給電鋸賦一個(gè)新標(biāo)簽——Saw
起落風(fēng)扇
在資源中找到Fan,將Off拖入場(chǎng)景中,和前面一樣,排序?qū)痈臑門rap,縮放為6、6,調(diào)整到合適的位置
然后加上 Box Collider 2D
然后加上一個(gè)組件——Area Effector 2D,這個(gè)組件是一個(gè)區(qū)域的物理效果器
將我們的Box Collider 2D 設(shè)置為觸發(fā)器,并且勾選Used By Effector從而使觸發(fā)器與Area Effector 2D相關(guān)聯(lián)
然后將觸發(fā)盒子調(diào)整的大一些。
然后我們調(diào)整Area Effector 2D
Force Angle 調(diào)成 90 表示是想正上方的方向,Force Magnitude 調(diào)成 20 表示力的大小
然后運(yùn)行游戲,我們就可以看到基本的推力效果了。
然后我們添加動(dòng)畫,這個(gè)操作相信大家都會(huì),和前幾個(gè)物體一樣。
然后,我們添加粒子系統(tǒng)體現(xiàn)風(fēng)的感覺。
建立一個(gè)粒子系統(tǒng),注意在Render中調(diào)整排序?qū)訛門rap,這樣才能看見。
最后效果:
?
添加敵人
重置場(chǎng)景
我們復(fù)制目前已經(jīng)完成的場(chǎng)景,命名level2。
在level2中,我們將除了Main Camera、Grid、player之外的元素全部刪除掉。
然后我們將前置場(chǎng)景(Grid=》foreground)刪掉,重新創(chuàng)建一個(gè)Tilemap來繪制不同的場(chǎng)景,這個(gè)Tilemap重命名:foreground,排序?qū)诱{(diào)整為2。
然后,繪制這個(gè)Tilemap,并且添加Tilemap碰撞檢測(cè)器,調(diào)整圖層為 Ground。
添加忍者蛙
在資源中找到Ninja Frog,找一張合適的圖片拖入場(chǎng)景。
添加剛體、碰撞盒、修改排序?qū)訛镋nemy,然后將角色拖拽到合適的位置
然后創(chuàng)建動(dòng)畫ninja_run,將所有的run動(dòng)畫拖入,調(diào)整好速度即可。
再創(chuàng)建動(dòng)畫ninja_die,將所有的hit動(dòng)畫拖入,調(diào)整好速度即可。
然后在ninja_frog的動(dòng)畫狀態(tài)機(jī)中設(shè)置,默認(rèn)動(dòng)畫是run,然后添加一個(gè)觸發(fā)變量(die),使run動(dòng)畫單向指向die動(dòng)畫,不存在退出時(shí)間。
Unity界面上的組件就完成了,接下來,我們來創(chuàng)建腳本——NinjaFrog.cs,并將腳本賦予給Ninja Frog;
寫代碼之前我們先給Ninja Frog創(chuàng)建三個(gè)子物體,三個(gè)子物體對(duì)應(yīng)了忍者蛙的檢測(cè),位置如圖:
?
頭部用來檢測(cè)玩家是否踩到(踩到了忍者蛙,忍者蛙就要死)
右邊兩個(gè)用來檢測(cè)是否碰墻需要折返。
public class NinjaFrog : MonoBehaviour {[Range(0, 1)] public float speed = 0.1f;public LayerMask layer;public Transform headPoint;public Transform rightUp;public Transform rightDown;private bool _collided;private Animator _anim;private Rigidbody2D _rigidbody;private CapsuleCollider2D _capsuleCollider2D;private int dieID = Animator.StringToHash("die");private void Start(){_rigidbody = GetComponent<Rigidbody2D>();_anim = GetComponent<Animator>();_capsuleCollider2D = GetComponent<CapsuleCollider2D>();}private void FixedUpdate(){Vector3 movement = new Vector3(speed, _rigidbody.velocity.y, 0);transform.position += movement;//兩個(gè)參數(shù)是線段的起點(diǎn)和終點(diǎn)//射線檢測(cè)到layer層,則返回真,否則為假_collided = Physics2D.Linecast(rightUp.position,rightDown.position,layer);if (_collided){Debug.DrawLine(rightUp.position, rightDown.position, Color.red);transform.localScale = new Vector3(transform.localScale.x * -1,transform.localScale.y,transform.localScale.z);speed *= -1;}else {Debug.DrawLine(rightUp.position, rightDown.position, Color.yellow);}}private void OnCollisionEnter2D(Collision2D collision){if (collision!=null) {if (collision.gameObject.tag == "Player") {float height = collision.contacts[0].point.y - headPoint.position.y;//玩家踩到忍者蛙if (height > 0) {collision.gameObject.GetComponent<Rigidbody2D>().AddForce(Vector3.up * 3,ForceMode2D.Impulse);speed = 0;_anim.SetTrigger(dieID);//取消碰撞檢測(cè)器_capsuleCollider2D.enabled = false;_rigidbody.bodyType = RigidbodyType2D.Kinematic;Destroy(gameObject, 1);}}}} }最終效果:
?
會(huì)下落的石頭怪
資源中找到RockHead,找到Idle圖片,拖到場(chǎng)景中。
調(diào)整成Enemy層,添加一個(gè)rigidbody2D。
將剛體組件調(diào)整成kinematic,凍結(jié)x坐標(biāo),凍結(jié)z旋轉(zhuǎn)。
kinematic
游戲?qū)ο笫欠褡裱\(yùn)動(dòng)學(xué)物理定律,若激活,該物體不再受物理 引擎驅(qū)動(dòng),而只能通過變換來操作。適用于模擬運(yùn)動(dòng)的平臺(tái)或 者模擬由鉸鏈關(guān)節(jié)連接的剛體
先給這個(gè)石頭怪添加一個(gè)碰撞盒,盒子和自身大小位置相同。
再給石頭怪添加一個(gè)觸發(fā)盒,范圍是石頭怪正下方的范圍(一直到地面)。
添加一個(gè)Idle動(dòng)畫、再添加一個(gè)Bottom_hit動(dòng)畫,這兩個(gè)都可以在資源目錄下找到。
然后用動(dòng)畫狀態(tài)機(jī)連接,一個(gè)觸發(fā)型變量isBottomHit來進(jìn)入bottom_hit動(dòng)畫。
然后就是寫腳本了,新建一個(gè)腳本RockHeadControl.cs
public class BottomHitControl : MonoBehaviour {private static readonly int _bottomHitID = Animator.StringToHash("isBottomHit");private Rigidbody2D _rigidbody2D;private Animator _animator;private float _timer;private const float RockHeadWaitingTimeSpan = 4f;private const float RockHeadMoveBackTimeSpan = 0.3f;private bool _isGroundHit = false;private Vector3 _originalPosition;//一個(gè)向上的速度private Vector3 _velocity = Vector3.zero;private void Start(){_rigidbody2D = GetComponent<Rigidbody2D>();_animator = GetComponent<Animator>();_originalPosition = _rigidbody2D.position;}private void OnTriggerStay2D(Collider2D collision){if (collision.CompareTag("Player")) {_rigidbody2D.isKinematic = false;_rigidbody2D.gravityScale = 2f;}}private void OnCollisionEnter2D(Collision2D collision){if (collision.gameObject.CompareTag("Player")) {Vector3 playerLocalScale =collision.gameObject.transform.localScale;collision.gameObject.transform.localScale =new Vector3(playerLocalScale.x,playerLocalScale.y*0.1f,playerLocalScale.z);Vector3 colliderSize =collision.gameObject.GetComponent<CapsuleCollider2D>().size;collision.gameObject.GetComponent<CapsuleCollider2D>().size = new Vector3(colliderSize.x * 0.1f,colliderSize.y * 0.1f);Destroy(collision.gameObject, 0.5f);}//地面的層級(jí)Ground是第8層if (collision.gameObject.layer == 8) {_isGroundHit = true;_animator.SetTrigger(_bottomHitID);}}private void FixedUpdate(){if (_isGroundHit) {_timer += Time.fixedDeltaTime;if (_timer >= RockHeadWaitingTimeSpan &&transform.position != _originalPosition){//恢復(fù)原始狀態(tài)_rigidbody2D.isKinematic = true;_rigidbody2D.gravityScale = 1;transform.position = Vector3.SmoothDamp(transform.position,_originalPosition,ref _velocity,RockHeadMoveBackTimeSpan);}else if(transform.position==_originalPosition) {_isGroundHit = false;_timer = 0;}}} }?
?
?
?
?
?
?
?
?
?
?
?
?
總結(jié)
以上是生活随笔為你收集整理的Unity简单2D游戏开发的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java hex decodehex_J
- 下一篇: js-sha1实现SHA1加密