官方遊戲--學習筆記二(英雄指令碼)

jz2017發表於2017-11-01

上一篇說完了如何控制英雄的移動,在這一篇我將補全剩餘部分。

程式碼註釋較為詳細,直接貼出來吧。

public class MyPlayerHealth : MonoBehaviour
{
    public Color mColor = new Vector4(1, 0, 0, 0.1f);   //更換閃爍背景色
    public Image mImage;    //紅色背景閃爍提醒受傷
    public Slider mSlider;  //滑塊顯示當前生命值
    public float mFashTime = 5f;    //閃爍時間
    public int mCurrentHealth;   //當前生命值

    Animator _Animator;

    int _StartHealth = 100;
    bool _TsTakedamage;
    bool _IsDeath;

    private void Awake()
    {
        mCurrentHealth = _StartHealth;
        _Animator = GetComponent<Animator>();
    }

前面部分給所需物件賦予了初始值,需要注意的是一般應該反著來,需要那種效果,為了達到那種效果,我才宣告瞭某個物件來實現效果

這樣可以鍛鍊腦的逆推能力,接下來時業務邏輯部分

 private void Update()
    {
        //受到傷害
        if (_TsTakedamage)
        {
            mImage.color = mColor;
        }
        else
        {
            mImage.color = Color.Lerp(mImage.color, Color.clear, mFashTime * Time.deltaTime);
        }
        _TsTakedamage = false;
    }
解釋一下:IsTakedamage 判斷英雄是否受到傷害,如果有臨時給全屏Image控制元件顏色賦值,之後下一幀該bool變數自動變為false,之後對顏色插值,知道變為透明

 public void TakeDamage(int amoutn)
    {
        if (_IsDeath)
            return;
        mCurrentHealth -= amoutn;

        mSlider.value = mCurrentHealth; //UI Slider元件值對應英雄生命值變化

        //如果英雄生命值小於0並且已經死亡,不應繼續執行Death中的邏輯
        if (mCurrentHealth <= 0 && !_IsDeath)
        {
            _IsDeath = true;
            Death();
        }
        _TsTakedamage = true;
    }
    private void Death()
    {
        _Animator.SetTrigger("Die");
    }

    //此函式在"Die"動畫啟動時執行
    public void RestartLevel()
    {
        // Reload the level that is currently loaded.
        SceneManager.LoadScene(0);
    }
上面兩個函式,均是外部引用,如TakeDamage被敵人攻擊指令碼所引用,RestartLevel被動畫事件驅動

===============================


下面是英雄射擊指令碼,相比較前兩個指令碼,雖然它程式碼數量多,但邏輯理解之後反而比較容易

public class MyPlayerShoot : MonoBehaviour
{
    public float mTimeInterval = 0.15f; //射擊時間間隔
    public float mDamagePerShoot = 20f; //射擊傷害點數
    public float mEffectDisplayTime = 0.2f; //射擊產生效果持續時間

    float timer;    //記時器
    LineRenderer _GunLine;  //射擊軌道效果
    Light _GunLight;    //射擊燈光效果
    Light _FaceLight;   //面部燈光效果

    Ray _Ray = new Ray();
    RaycastHit _Rh;

    float _Range = 100; //射擊最遠距離
    int _LayerMask; //哪些層納入射擊目標
    private void Awake()
    {
        _GunLine = GetComponent<LineRenderer>();
        _GunLight = GetComponent<Light>();
        _FaceLight = transform.GetChild(0).GetComponent<Light>();
        _LayerMask = LayerMask.GetMask("Shootable");
    }
程式碼註釋應該比較清晰了。接下來貼出業務邏輯部分程式碼

private void Update()
    {
        timer += Time.deltaTime;
        if (Input.GetButton("Fire1") && timer >= mTimeInterval)
        {
            Shoot();
        }
        //計時器達到效果停止時間
        if (timer >= mTimeInterval * mEffectDisplayTime)
        {
            DisableEffects();   //關閉所有射擊效果
        }
    }
 GetButton("Fire1"),表示按下或按住滑鼠左鍵返回true;接下來貼出具體實現部分程式碼
 private void Shoot()
    {
        //計時器歸0,等待射擊時間間隔
        timer = 0f;

        //開啟三個射擊特效
        _GunLine.enabled = true;
        _GunLight.enabled = true;
        _FaceLight.enabled = true;

        _Ray.origin = transform.position;   //設定射線的初始位置
        _Ray.direction = transform.forward; //設定射線的方向

        _GunLine.SetPosition(0, transform.position);    //軌道第一個點位英雄位置

        if (Physics.Raycast(_Ray, out _Rh, _Range, _LayerMask))
        {
            MyEnemyHealth meh = _Rh.collider.gameObject.GetComponent<MyEnemyHealth>();
            //如果擊中點所屬物件有MyEnemyHealth指令碼返回值不為null
            if (meh != null)
            {
                meh.TakeDamage(mDamagePerShoot);    //給敵人造成傷害
            }
            _GunLine.SetPosition(1, _Rh.point); //此時將軌道第二個點設定為擊中點
        }
        else
        {
            _GunLine.SetPosition(1, _Ray.origin + _Ray.direction * _Range); //如果沒有擊中點,直接沿著初始方向射出即可
        }
    }
    private void DisableEffects()
    {
        //關閉三個射擊特效
        _GunLine.enabled = false;
        _GunLight.enabled = false;
        _FaceLight.enabled = false;
    }
關於英雄指令碼的介紹完畢,到此英雄可以簡單的自由移動了。







相關文章