#遊戲unity-音之國度#戰鬥系統優化
起初,在之前的博客中我們已經講解過了回合制戰鬥系統的主要代碼邏輯,但是這種代碼邏輯並不是什麼遊戲都適用的;就像悲慘的博主,寫了各自人物和敵人的代碼,在最後寫有關協程的控制代碼的時候,才心酸的發現,這樣安排代碼邏輯,也能達到博主想要的交替戰鬥控制權的效果,但是代碼很繞很不具有可讀性。博主之前是這樣想的——在每一個模型上綁定兩個腳本,一個是作爲主權進行主動攻擊的Player腳本,一個是在受到攻擊後,進行隨機反擊的Monster腳本,其中包括作爲相對於另一方的敵人的時候的AI算法。但是,在寫Control腳本時,發現,這樣的話,在寫協程的交替控制的時候,就需要實例化四個腳本的實例;其中,每個模型上的每個腳本各一個,之所以這樣做,是因爲在協程中要調用不同腳本的的不同方法以達到想要的功能實現。博主也確實硬着頭皮那樣寫了寫,但是發現,實例的四個腳本在調用時,會忘記誰是誰,哪個包括什麼方法,這對碼農本身就增加了閱讀難度好嘛。這就是血的教訓啊,劃重點!
所以,博主果斷扔掉了原來的腳本,重新上陣,根據網上查詢,增加了有關經驗值的數值計算的算法,重寫了腳本,對其進行了優化。
其實博主發生那樣的錯誤,完全是因爲想當然——因爲慣性思維就是把方法能按狀態分開在不同的腳本寫就分開呀,在一個腳本里多亂呀,但是這次就遇到了特殊情況了不是….所以,朋友們一定要提前寫好代碼邏輯的框架呀。
這次,博主把人物在所有狀態下響應的所有方法都放置在一個Hero腳本中,主要的代碼邏輯放在Control中來寫。還對其中的數據進行了私有的封裝處理而Hero中的邏輯和博主之前講過的是大致相似的,有補充和改變的,博主也清楚的寫了註釋了,還有問題的話,請留言或者私信博主哦。
優化後的Hero腳本——
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class Hero : MonoBehaviour//攻擊腳本
{
public Transform progress;
public int MAX_HP;
private int attack;
private int _hp;
public int exp=0;//經驗值
private bool Islife;
private bool Ismyturn;
GameObject monster;
private Hero enemyScript;
//等待玩家操作
public bool isWaitPlayer = true;
public bool ifUIshow = true;
//動畫組件
private Animation mAnim;
private Scrollbar hpProgress;
private Text hpText;
// Use this for initialization
void Start()
{
Islife = true;
mAnim = this.GetComponent<Animation>();
mAnim.Play("Walk");
if (progress != null)
{
hpText = progress.GetComponentInChildren<Text>();
hpProgress = progress.GetComponentInChildren<Scrollbar>();
}
Hp = MAX_HP;
}
//傷害
public void OnDamage(int mValue)
{
_hp -= mValue;
}
public void OnGUI()
{
//如果處於等待狀態,則顯示操作窗口
if (isWaitPlayer && ifUIshow)
{
GUI.Window(0, new Rect(Screen.width / 2 + 150, Screen.height / 2 + 150, 200, 200), InitWindow, "請選擇技能");
// mAnim.Play("skill");
mAnim.Play("Walk");
}
}
void InitWindow(int ID)
{
if (GUI.Button(new Rect(0, 20, 200, 30), "攻擊"))
{
mAnim.Play("Run");
OnDamage(10);
//交換操作權
isWaitPlayer = false;
ifUIshow = false;
}
if (GUI.Button(new Rect(0, 50, 200, 30), "法術"))
{
OnDamage(20);
mAnim.Play("Dying");
//交換操作權
isWaitPlayer = false;
ifUIshow = false;
}
}
bool islife()
{
if (this._hp <= 0)
Islife = false;
else
Islife = true;
return Islife;
}
void myturn()
{
Ismyturn = true;
}
public int Hp
{
get
{
return this._hp;
}
set
{
this._hp = value;
this.hpText.text = "血量:" + this._hp;
hpProgress.size = this._hp / (float)MAX_HP;
}
}
// Update is called once per frame
void Update()
{
}
void FixedUpdate()
{
Vector3 vtHeroWorldPos = this.transform.position;
Vector3 vtHeroScrpos = Camera.main.WorldToScreenPoint(vtHeroWorldPos);
progress.transform.position = vtHeroScrpos;
}
public void Ending()//一方血量爲0的時候跳出結束界面
{
if (this._hp != 0)
this.exp += 20;
}
void OnTriggerEnter(Collider other)
{
monster = GameObject.Find("對手");
enemyScript = monster.GetComponent<Hero>();
if (enemyScript == null)
{
return;
}
//this.Hp -= enemyScript.attack;
if (this.Hp <= 0)
{
this.Hp = 0;
}
Debug.Log("角色:" + this.name + " 掉血:" + enemyScript.attack + " 當前生命值:" + this.Hp);
if (this.Hp == 0)
{
Ending();
Debug.Log("角色:" + this.name + " 掛了");
}
}
//作爲敵人AI算法
public void StartAI()//給其中一個模型加的隨機反擊效果
{
if (!isWaitPlayer)
{
if (_hp> 20)
{
//80%
if (Random.Range(1, 5) % 5 != 1)
{
mAnim.Play("Dying");
attack = 5;
isWaitPlayer = true;
}
//20%
else
{
attack = 10;
mAnim.Play("Dying");
isWaitPlayer = true;
}
}
else
{
switch (Random.Range(1, 5) % 5)
{
case 0:
attack = 15;
mAnim.Play("Dying");
isWaitPlayer = true;
break;
}
}
}
}
}