基于unity的2D横版游戏开发日志 小结
前言
說是基于unity的2D橫版游戲,實際上只是一個初學unity與C#新人的練手Demo,目前還處于半成狀態。美術資源方面全部出自unity免費資源,經過自己的小修,大致拼出了一個游戲。代碼方面,僅僅初識C#語法,此前從未接觸過面向對象編程的我,顯然寫出來的東西顯然不堪入目,問題包括但不限于:1.未遵守命名規范。2.未領會面向對象編程的思想,代碼復用隨處可見。3.代碼思路及其不清晰,動畫狀態轉換判斷一半靠動畫機參數,一半靠代碼里的if else(再三確認.jpg)。4.總體架構沒想好,想到哪寫哪,beAttackBox滿足不了要求寫個beAttackBoxOfEnemy,還不行就beAttackBoxOfBoss,看架勢如果寫完整個游戲,要寫上千個腳本。5.維護性極差,腳本功能縱橫交錯,出了問題現在的我能解決,過一個月就只有上帝能解決了。
總而言之,這段小結僅出于記錄自己黑歷史的目的,冒著榮登知乎“你見過最爛的代碼是怎樣的”這一問題榜首的風險發布,不敢勞煩各位大佬斧正,只希望大伙就看個樂呵,盡量不要進行人身攻擊,以下是展示部分。
分割線
游戲展示
由于還有有關游戲導出分辨率的問題尚未解決,展示僅在編譯器中進行。
1.近戰敵人演示
2.遠程敵人演示
3.boss戰(自己寫的boss都能過不了?)
部分代碼展示
boss1AI
//bossAI形式不同于小怪enemyAI,不具有普適性。 //boss1行動模式用自然語言描述如下: //在場景中,boss一直處于戰斗狀態,以若干秒為一個周期,根據所設計的概率隨機選擇一個符合條件(與玩家的距離、自身血量所決定的階段、技能冷卻情況)的 //行動(發動某攻擊,接近玩家,遠離玩家),在完成行動后,進入后搖時間,后搖結束后進入下一周期,在受擊動畫完成后若干秒,立刻進入下一個周期。 //行動并不僅限于一個動畫,可以考慮兩個動畫進行組合以實現連招。boss子物體包含若干個范圍盒,按由外到內的順序排列,每進入一個范圍盒,可隨機選擇的動作增加。 //由外到內,增加的可選擇動作為: //1.接近玩家。 //2.遠離玩家、發動技能跳斬attack5(僅在該范圍盒)、發動技能突刺attack2(二階段新增技能旋轉攻擊attack4,隱身突襲attack3)。 //3.普通攻擊attack1、擊退踢腿attack6(后接突刺或跳斬)。 //具體數值見boss1Const/*其余說明:1.boss面向改變不屬于行動,于等待階段進行。* 2.當血量低于50時,進入二階段,立即進行三次隱身突襲attack3,并減少單個周期的時間以實現行動后搖減少,加速敵人攻擊。* 3.一定時間內受擊超過一定次數時,boss會踢腿擊退接突刺或跳斬的連招* * */ using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement;public class boss1AI : MonoBehaviour {static public float HP;public enum BossState { range1, range2, range3 };//public BossState bossState = BossState.range1;public AnimationCurve jump;public AudioSource attack2;private Animator ani;private SpriteRenderer spr;private Rigidbody2D rid;private GameObject player;private bool isIdle;private float animationLength;private int[] moving=new int[10000];//用于記錄boss行動的數組private int i = 0;private float waitingTime = 0;//后搖計時器private float movingTime = 0;//行動計時器private float attack3CD = 0;//特殊技能attack3計時器private int movingNumble = 0;//隨機數,用于決定boss的下一步行動private int attack3Times = 3;//attack3技能單詞釋放次數private float jumpTime=0;// Start is called before the first frame updatevoid Start(){ani = gameObject.GetComponent<Animator>();spr = gameObject.GetComponent<SpriteRenderer>();rid = gameObject.GetComponent<Rigidbody2D>();player = GameObject.FindGameObjectWithTag("Player");//判斷動畫狀態機播放的動畫是否為Idle//引用組件HP = boss1Const.maxHP;}// Update is called once per frameprivate void FixedUpdate(){animationLength = ani.GetCurrentAnimatorStateInfo(0).length;//獲取當前播放動畫長度if (waitingTime >= boss1Const.waitingTime){if (ani.GetBool("isIdle") == true){roll:switch (bossState){case BossState.range1:movingNumble = Random.Range(0, 15);//生成一個0到14之間的隨機數(包含),數字大小決定了移動距離break;case BossState.range2:movingNumble = Random.Range(0, 60);//生成一個0到59之間的隨機數(包含)15~34為跳斬,35-59為突刺,進入2階段后,單數正常判定,雙數為旋轉攻擊,隱身突襲為特殊技能,進入2階段每5個循環釋放一次break;case BossState.range3:movingNumble = Random.Range(35, 120);//生成一個0到119之間的隨機數(包含)60~104為普攻,105~119為擊退接突刺(或跳斬)break; }//處于待機狀態且不處于后搖時間中時,roll點決定boss下一步行動if (attack3CD <= 0 && (ani.GetInteger("attackingNumber") == 0 || ani.GetInteger("attackingNumber") == 3) && HP <= 0.5 * boss1Const.maxHP){moving[++i] = 3;}else if (movingNumble >= 0 && movingNumble < 15)//接近玩家{moving[++i] = 0;}else if (movingNumble >= 15 && movingNumble < 35){if (HP <= boss1Const.maxHP * 0.5 && movingNumble % 2 == 0)//旋轉攻擊(二階段時){moving[++i] = 4;}else//跳斬{moving[++i] = 5;}}else if (movingNumble >= 35 && movingNumble < 60){if (HP <= boss1Const.maxHP * 0.5 && movingNumble % 2 == 0)//旋轉攻擊(二階段時){moving[++i] = 4;}else//突刺{moving[++i] = 2;}}else if (movingNumble >= 60 && movingNumble < 105)//普通攻擊{moving[++i] = 1;}else if (movingNumble >= 105 && movingNumble <= 120){moving[++i] = 6; }//根據movingNumble確定下一步行動if(moving[i-1]==6){if(i%2==0){moving[i] = 2;}else{moving[i] = 5;}}//查看上一步行動,若為踢腿,則根據隨機數指定下一步行動為突刺或跳斬if (i >= 2) {if (moving[i] == moving[i - 1] && moving[i] == moving[i - 2] && moving[i] != 3) {i--;goto roll;}}//查看即將進行的行動,若重復兩次以上,重新roll點決定行動}if (HP <= 0.5 * boss1Const.maxHP) {attack3CD -= Time.deltaTime;}//特殊技能冷卻時間改變switch(moving[i]){case 0:doWalk(movingNumble);break;case 1:doAttack1();break;case 2:doAttack2();break;case 3:doAttack3();break;case 4:doAttack4();break;case 5:doAttack5();break;case 6:doAttack6();break;}}else if(HP>0){doWait();}else{doDestroy();}//}void doWait(){waitingTime += Time.fixedDeltaTime;//累加后搖計時器doChangeFacing();//旋轉面向 }void doWalk(float velocity){ani.SetBool("isIdle", false);ani.SetBool("isWalking", true);movingTime += Time.fixedDeltaTime;if (movingTime > animationLength){waitingTime = boss1Const.waitingTime-boss1Const.waitingTimeAfterWalk;movingTime = 0;ani.SetBool("isWalking", false);ani.SetBool("isIdle", true);}transform.Translate(Vector2.right * Time.fixedDeltaTime * (velocity / 60 + 0.25f) * boss1Const.walkSpeed, Space.Self);//接近玩家一段距離}void doAttack1(){ani.SetBool("isIdle", false);ani.SetInteger("attackingNumber", 1);movingTime += Time.fixedDeltaTime;if (spr.sprite.name == "attack-A5" || spr.sprite.name == "attack-A6" || spr.sprite.name == "attack-A7"){doMove(1.5f);}//根據動畫播放進度進行相匹配的位移if (movingTime > animationLength){waitingTime = boss1Const.waitingTime - boss1Const.waitingTimeAfterAttack1;movingTime = 0;ani.SetInteger("attackingNumber", 0);ani.SetBool("isIdle", true);}}//普攻void doAttack2(){ani.SetBool("isIdle", false);ani.SetInteger("attackingNumber", 2);movingTime += Time.fixedDeltaTime;if(spr.sprite.name=="attack-B4"&& attack2.isPlaying == false){attack2.Play(); }if(spr.sprite.name=="attack-B3"){doChangeFacing();}if (spr.sprite.name == "attack-B4"||spr.sprite.name=="attack-B5" ){doMove(4f);}//根據動畫播放進度進行相匹配的位移if (movingTime > animationLength){waitingTime = boss1Const.waitingTime - boss1Const.waitingTimeAfterAttack2;movingTime = 0;ani.SetInteger("attackingNumber", 0);ani.SetBool("isIdle", true);}}//突刺void doAttack3(){ani.SetInteger("attackingNumber", 3);ani.SetBool("isIdle", false);ani.SetBool("isWalking", false);movingTime += Time.fixedDeltaTime;if (spr.sprite.name == "attack-C1"){spr.color = Color.Lerp(new Color(1, 1, 1, 1), new Color(1, 1, 1, 0), movingTime / animationLength * 3f);}else if(spr.sprite.name!="attack-C1"&&spr.sprite.name!="attack-C2"){spr.color = Color.Lerp(new Color(1, 1, 1, 0), new Color(1, 1, 1, 1), (movingTime - 0.5f * animationLength) * 3f);}//實現隱身效果if (spr.sprite.name=="attack-C2"){doFlash(player.transform.position - (Vector3.right + Random.Range(-1, 1) * Vector3.right*2) * 0.5f + Vector3.up * 0.5f);doChangeFacing();//隨機瞬移至玩家身邊并調整面向}if(spr.sprite.name=="attack-C7"||spr.sprite.name=="attack-C8"){doJump(boss1Const.jumpHeight*0.5f);}if (movingTime > animationLength){if(attack3Times>1){attack3Times--;movingTime = 0;waitingTime = boss1Const.waitingTime - boss1Const.waitingTimeAfterAttack3;ani.SetInteger("attackingNumber", 0);ani.SetBool("isIdle", true);}else{attack3Times = 3;movingTime = 0;waitingTime = boss1Const.waitingTime - boss1Const.waitingTimeAfterAttack3;attack3CD = boss1Const.attack3CD;ani.SetInteger("attackingNumber", 0);ani.SetBool("isIdle", true);}}}//隱身突襲void doAttack4(){ani.SetInteger("attackingNumber", 4);ani.SetBool("isIdle", false);movingTime += Time.fixedDeltaTime;if(spr.sprite.name!="attack-D1"&&spr.sprite.name!="attack-D2"&&spr.sprite.name!="attack-D12"&&spr.sprite.name!="attack-D7"){doMove(4f);}if(spr.sprite.name=="attack-D7"){doChangeFacing();}if (movingTime > animationLength){waitingTime = boss1Const.waitingTime - boss1Const.waitingTimeAfterAttack4;movingTime = 0;ani.SetInteger("attackingNumber", 0);ani.SetBool("isIdle", true);}}//旋轉攻擊void doAttack5(){ani.SetInteger("attackingNumber", 5);ani.SetBool("isIdle", false);movingTime += Time.fixedDeltaTime;if(spr.sprite.name == "jump-attack-1" || spr.sprite.name== "jump-attack-2"||spr.sprite.name== "jump-attack-3"){doJump(boss1Const.jumpHeight);}if (spr.sprite.name != "jump-attack-8"){doMove(Random.Range(2.5f, 2.8f));}//根據動畫播放進度進行相匹配的位移if (movingTime > animationLength){waitingTime = boss1Const.waitingTime - boss1Const.waitingTimeAfterAttack5;movingTime = 0;ani.SetInteger("attackingNumber", 0);ani.SetBool("isIdle", true);}}//跳斬void doAttack6(){ani.SetInteger("attackingNumber", 6);ani.SetBool("isIdle", false);movingTime += Time.fixedDeltaTime;if (spr.sprite.name == "kick-3" || spr.sprite.name == "kick-4"){doMove(4f);}if (movingTime >= animationLength){movingTime = 0;waitingTime = boss1Const.waitingTime - boss1Const.waitingTimeAfterAttack6;ani.SetInteger("attackingNumber", 0);ani.SetBool("isIdle", true);}}//踢腿void doMove(float velocity){transform.Translate(Vector2.right * Time.fixedDeltaTime*velocity , Space.Self);}//位移void doChangeFacing(){if (player.transform.position.x <= transform.position.x){transform.rotation = Quaternion.Euler(0, 180, 0);}else{transform.rotation = Quaternion.Euler(0, 0, 0);}}//改變面向void doJump(float jumpHeight){jumpTime += Time.fixedDeltaTime;transform.Translate(new Vector3(0, jump.Evaluate(jumpTime) - jump.Evaluate(jumpTime - Time.fixedDeltaTime)) * jumpHeight, Space.World);if(jumpTime>=0.5f){jumpTime = 0;}}//跳躍void doFlash(Vector3 Position){transform.position = Position;}//閃爍void doDestroy(){ani.SetBool("isDead", true);movingTime += Time.deltaTime;if (movingTime >= animationLength){StartCoroutine(reStart());}}IEnumerator reStart(){yield return new WaitForSecondsRealtime(3.0f);SceneManager.LoadScene("title");} }enemy1AI
using System.Collections; using System.Collections.Generic; using UnityEngine;public class enemy1AI : MonoBehaviour {private Animator ani;private SpriteRenderer spr;private Rigidbody2D rid;private GameObject attackBox;private GameObject beAttackBox;private GameObject isGroundBox;private BoxCollider2D attackBoxCollider;private GameObject player;private enemyState enemyState;private enemyConst enemyConst;//組件引用//狀態private float attackTime = 0;private float wanderTime = 0;private float readyAttackTime = 0;private float velocity = 0;private float waitingTime= 0;private float hitTime = 0;//計時器// Start is called before the first frame updatevoid Start(){ani = gameObject.GetComponent<Animator>();spr = gameObject.GetComponent<SpriteRenderer>();rid = gameObject.GetComponent<Rigidbody2D>();enemyConst = GetComponent<enemyConst>();player = GameObject.FindGameObjectWithTag("Player");//讀取組件for (int i = 0; i < transform.childCount; i++){switch (transform.GetChild(i).name){case "attackBox":attackBox = transform.GetChild(i).gameObject;break;case "beAttackBox":beAttackBox = transform.GetChild(i).gameObject;break;case "isGroundBox":isGroundBox = transform.GetChild(i).gameObject;break;}}//讀取子物體attackBoxCollider = attackBox.GetComponent<BoxCollider2D>();//讀取子物體組件enemyState = GetComponent<enemyState>();}// Update is called once per frameprivate void FixedUpdate(){if(ani.GetBool("isDead")==false){setGrativy();//根據敵人狀態設置重力doWander();//警戒范圍內無玩家時進行巡邏doChase();//玩家進入警戒范圍后進行追擊,并在脫離追擊范圍前持續追擊doAttack();//玩家進入攻擊范圍內進行攻擊doBeHit();//受擊時播放受擊動畫}doDestroy();//死亡時播放死亡動畫}void Update(){ani.SetFloat("attackSpeed", enemyConst.attackSpeed);}void doMove(float velocity,float speed){if (velocity > 0){transform.rotation = Quaternion.Euler(0, 0, 0);}else if (velocity < 0){transform.rotation = Quaternion.Euler(0, 180, 0);}//判斷是否需要旋轉enemy1ani.SetFloat("velocity", velocity);transform.Translate(Vector2.right * Time.fixedDeltaTime * velocity * speed, Space.World);//左右移動enemy1}//移動enemy1void doWander(){if (enemyState.state == enemyState.State.wander && ani.GetBool("isBeingHit") == false) {waitingTime = 0;float velocity = 0;wanderTime += Time.fixedDeltaTime;if (wanderTime <= 0.25 * enemyConst.wanderLength){velocity = 1;}else if (wanderTime >= 0.25 * enemyConst.wanderLength && wanderTime <= enemyConst.wanderLength * 0.5){velocity = 0;}else if (wanderTime >= 0.5 * enemyConst.wanderLength && wanderTime <= enemyConst.wanderLength * 0.75){velocity = -1;}else if (wanderTime >= 0.75 * enemyConst.wanderLength && wanderTime <= enemyConst.wanderLength){velocity = 0;}else{wanderTime = 0;}//根據計時器設定velocity方向以實現巡邏,單次巡邏時長為enemy1Const.wanderLength,巡邏模式為右走-停止-左走-停止doMove(velocity,enemyConst.walkSpeed);//移動enemy1}}void doChase(){if (enemyState.state == enemyState.State.chase && ani.GetBool("isAttacking1") == false && ani.GetBool("isAttacking2") == false && ani.GetBool("isBeingHit") == false) {ani.SetFloat("velocity", 0);waitingTime += Time.fixedDeltaTime;if (waitingTime >= enemyConst.baseChangeTime) {if (transform.position.x - player.transform.position.x >= 0){velocity = -1;}else if (player.transform.position.x - transform.position.x >= 0){velocity = 1;}doMove(velocity, enemyConst.chaseSpeed);}}}void doAttack(){readyAttackTime += Time.fixedDeltaTime;if (enemyState.state == enemyState.State.attack || ani.GetBool("isAttacking1") == true || ani.GetBool("isAttacking2") == true) //確保攻擊動畫播放完畢{if (ani.GetBool("isGrounded") == true && ani.GetBool("isBeingHit") == false && ani.GetBool("isAttacking1") == false && ani.GetBool("isAttacking2") == false && enemyState.state == enemyState.State.attack && readyAttackTime >= enemyConst.baseAttackTime) {attackTime = 0;ani.SetFloat("velocity", 0);//站定進行攻擊if (Random.Range(1,3)==1){ani.SetBool("isAttacking1", true);}else{ani.SetBool("isAttacking2", true);}}//隨機發起一種形式的新攻擊if (ani.GetBool("isAttacking1") == true){attackTime += Time.fixedDeltaTime;if (attackTime >= 1 / enemyConst.attackSpeed * enemyConst.attackAnimation1Length){ani.SetBool("isAttacking1", false);waitingTime = 0;readyAttackTime = 0;}}else if(ani.GetBool("isAttacking2")==true){attackTime += Time.fixedDeltaTime;if (attackTime >= 1 / enemyConst.attackSpeed * enemyConst.attackAnimation2Length) {ani.SetBool("isAttacking2", false);waitingTime = 0;readyAttackTime = 0;}}//攻擊計時,以轉化動畫狀態}}void doBeHit(){if (ani.GetBool("isBeingHit") == true){hitTime += Time.fixedDeltaTime;if (hitTime >= enemyConst.hitAnimationLength){hitTime = 0;ani.SetBool("isBeingHit", false);}}}void doDestroy(){if(enemyState.HP<=0){ani.SetBool("isDead", true);Destroy(gameObject, enemyConst.deadAnimationLength);}}private void setGrativy(){if (ani.GetBool("isBeingHit") == true){rid.gravityScale = 0;}else{rid.gravityScale = 10;}//受擊狀態下重力設置為0以實現受擊時的僵直;} }enemy2AI
using System.Collections; using System.Collections.Generic; using UnityEngine;public class enemy2AI : MonoBehaviour {public GameObject arrow;private Animator ani;private SpriteRenderer spr;private Rigidbody2D rid;private GameObject attackBox;private GameObject beAttackBox;private GameObject isGroundBox;private BoxCollider2D attackBoxCollider;private GameObject player;private enemyState enemyState;private enemyConst enemyConst;private GameObject shootPoint;private GameObject shootPoint2;//組件引用//狀態private float attackTime = 0;private float wanderTime = 0;private float readyAttackTime = 0;private float velocity = 0;private float waitingTime = 0;private float hitTime = 0;private bool havingInstantiateArrow = false;//計時器// Start is called before the first frame updatevoid Start(){ani = gameObject.GetComponent<Animator>();spr = gameObject.GetComponent<SpriteRenderer>();rid = gameObject.GetComponent<Rigidbody2D>();enemyConst = GetComponent<enemyConst>();player = GameObject.FindGameObjectWithTag("Player");//讀取組件for (int i = 0; i < transform.childCount; i++){switch (transform.GetChild(i).name){case "attackBox":attackBox = transform.GetChild(i).gameObject;break;case "beAttackBox":beAttackBox = transform.GetChild(i).gameObject;break;case "isGroundBox":isGroundBox = transform.GetChild(i).gameObject;break;case "shootPoint":shootPoint = transform.GetChild(i).gameObject;break;case "shootPoint2":shootPoint2 = transform.GetChild(i).gameObject;break;}}//讀取子物體attackBoxCollider = attackBox.GetComponent<BoxCollider2D>();//讀取子物體組件enemyState = GetComponent<enemyState>();}// Update is called once per frameprivate void FixedUpdate(){if (ani.GetBool("isDead") == false){setGrativy();//根據敵人狀態設置重力doWander();//警戒范圍內無玩家時進行巡邏doChase();//玩家進入警戒范圍后進行追擊,并在脫離追擊范圍前持續追擊doAttack();//玩家進入攻擊范圍內進行攻擊doBeHit();//受擊時播放受擊動畫}doDestroy();//死亡時播放死亡動畫}void Update(){ani.SetFloat("attackSpeed", enemyConst.attackSpeed);}void doMove(float velocity, float speed){if (velocity > 0){transform.rotation = Quaternion.Euler(0, 0, 0);}else if (velocity < 0){transform.rotation = Quaternion.Euler(0, 180, 0);}//判斷是否需要旋轉enemy1ani.SetFloat("velocity", velocity);transform.Translate(Vector2.right * Time.fixedDeltaTime * velocity * speed, Space.World);//左右移動enemy1}//移動enemy1void doWander(){if (enemyState.state == enemyState.State.wander && ani.GetBool("isBeingHit") == false){waitingTime = 0;float velocity = 0;wanderTime += Time.fixedDeltaTime;if (wanderTime <= 0.25 * enemyConst.wanderLength){velocity = 1;}else if (wanderTime >= 0.25 * enemyConst.wanderLength && wanderTime <= enemyConst.wanderLength * 0.5){velocity = 0;}else if (wanderTime >= 0.5 * enemyConst.wanderLength && wanderTime <= enemyConst.wanderLength * 0.75){velocity = -1;}else if (wanderTime >= 0.75 * enemyConst.wanderLength && wanderTime <= enemyConst.wanderLength){velocity = 0;}else{wanderTime = 0;}//根據計時器設定velocity方向以實現巡邏,單次巡邏時長為enemy1Const.wanderLength,巡邏模式為右走-停止-左走-停止doMove(velocity, enemyConst.walkSpeed);//移動enemy1}}void doChase(){if (enemyState.state == enemyState.State.chase && ani.GetBool("isAttacking1") == false && ani.GetBool("isAttacking2") == false && ani.GetBool("isBeingHit") == false){ani.SetFloat("velocity", 0);waitingTime += Time.fixedDeltaTime;if (waitingTime >= enemyConst.baseChangeTime){if (transform.position.x - player.transform.position.x >= 0){velocity = -1;}else if (player.transform.position.x - transform.position.x >= 0){velocity = 1;}doMove(velocity, enemyConst.chaseSpeed);}}}void doAttack(){readyAttackTime += Time.fixedDeltaTime;if (enemyState.state == enemyState.State.attack || ani.GetBool("isAttacking1") == true || ani.GetBool("isAttacking2") == true) //確保攻擊動畫播放完畢{if (ani.GetBool("isGrounded") == true && ani.GetBool("isBeingHit") == false && ani.GetBool("isAttacking1") == false && ani.GetBool("isAttacking2") == false && enemyState.state == enemyState.State.attack && readyAttackTime >= enemyConst.baseAttackTime){attackTime = 0;ani.SetFloat("velocity", 0);//站定進行攻擊if (player.transform.position.y + 1 >= transform.position.y) //判斷是否需要向下射箭{ani.SetBool("isAttacking1", true); }else{ani.SetBool("isAttacking2", true);}}//根據玩家位置發動攻擊if (ani.GetBool("isAttacking1") == true){attackTime += Time.fixedDeltaTime;if (spr.sprite.name == "attack-A4"&&havingInstantiateArrow==false){havingInstantiateArrow = true;Instantiate(arrow, shootPoint.transform.position, transform.rotation);}//生成水平的箭if (attackTime >= 1 / enemyConst.attackSpeed * enemyConst.attackAnimation1Length){ ani.SetBool("isAttacking1", false);havingInstantiateArrow = false;waitingTime = 0;readyAttackTime = 0;}//結束動畫}else if (ani.GetBool("isAttacking2") == true){attackTime += Time.fixedDeltaTime;if (spr.sprite.name == "attack-B4" && havingInstantiateArrow == false){havingInstantiateArrow = true;Instantiate(arrow, shootPoint2.transform.position, Quaternion.Euler(0, transform.rotation.y*180, 315));}//生成斜向下的箭if (attackTime >= 1 / enemyConst.attackSpeed * enemyConst.attackAnimation2Length){ani.SetBool("isAttacking2", false);havingInstantiateArrow = false;waitingTime = 0;readyAttackTime = 0;}//結束動畫}//攻擊計時,以轉化動畫狀態}}void doBeHit(){if (ani.GetBool("isBeingHit") == true){hitTime += Time.fixedDeltaTime;if (hitTime >= enemyConst.hitAnimationLength){hitTime = 0;ani.SetBool("isBeingHit", false);}}}void doDestroy(){if (enemyState.HP <= 0){ani.SetBool("isDead", true);Destroy(gameObject, enemyConst.deadAnimationLength);}}private void setGrativy(){if (ani.GetBool("isBeingHit") == true){rid.gravityScale = 0;}else{rid.gravityScale = 10;}//受擊狀態下重力設置為0以實現受擊時的僵直;} }總結
歷經二十天的努力,我的第一款游戲demo的制作算是告一段落了,盡管還有數不清的不足之處,但是起碼是一個可以運行的游戲了。我不敢說自己已經盡全力去把它做到最好了,不過我想下一次,我會做的更好。
9/12 1:40 -----ydx
總結
以上是生活随笔為你收集整理的基于unity的2D横版游戏开发日志 小结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于Python的PyGame实现的横板
- 下一篇: unity2D横版游戏教程-1 让人物动