筆記21 坦克大戰:小地圖

創建地面,添加跟隨攝像機

在這裏插入圖片描述

代碼:跟隨攝像機FlowTarget

 public class FlowTarget : MonoBehaviour {
    //跟隨的目標
    public Transform target;
    //跟隨的高度
    public float height;
    //跟隨的距離
    public float distance;

    //兩個更新的方法:Update和LateUpdate。 把Update改爲LateUpdate
    //物體移動是在Update裏面做的,攝像機是跟隨物體移動,所以在LateUpdate裏面。
    void LateUpdate () {
        //法二:平滑跟隨。我的前方和目標的前方逐漸一致,利用插值。
        //此方法,Y軸是不需要跟隨的,將其置爲零
        Vector3 forward = transform.forward;
        forward.y = 0;
        //1可以寫成public變量,在外面調整平滑。爲了讓各個設備一樣,所以* Time.deltaTime
        Vector3 newForward = Vector3.Lerp(forward, target.forward, 1 * Time.deltaTime);
        //此處減去newForward * distance
        transform.position = target.position - newForward * distance + Vector3.up * height;
        //看向目標點(否則攝像機不會旋轉)
        transform.LookAt(target);        
    }
}

添加音頻管理器

在這裏插入圖片描述

代碼:音頻管理器AudioManager

 public class AudioManager : MonoBehaviour {
    //音頻播放器有了,首先寫成單例類。
    public static AudioManager Instance;

    //寫出兩個播放器(背景音、音效)。然後到unity裏關聯(背景音,循環打鉤)。
    public AudioSource bgmPlayer;
    public AudioSource sePlayer;

	void Awake () {
        //單例類一定要在Awake裏面賦值。因爲這個方法調用的時機比Start靠前。
        //這樣可以保證在第一時間把這個單例做成。
        Instance = this;
	}
	
	// 下面給三個方法
    //一個播放bgm。傳進來一個name,就是你播放的文件名稱
    public void PlayMusic(string name)
    {
        //如果當前沒有播放,再去播放
        if(bgmPlayer.isPlaying == false)
        {
            /*加載音頻資源。類型AudioClip。
            從哪個位置加載?直接把name(外界傳進來的)放那就可以了。*/
            AudioClip clip = Resources.Load<AudioClip>(name);
            //更換當前播放的聲音片段
            bgmPlayer.clip = clip;
            //播放Play
            bgmPlayer.Play();
        }       
    }
    //停止播放
    public void StopMusic()
    {
        bgmPlayer.Stop();
    }
    //播放音效
    public void PlaySound(string name)
    {
            /*加載音頻資源。類型AudioClip。
            從哪個位置加載?直接把name(外界傳進來的)放那就可以了。*/
        AudioClip clip = Resources.Load<AudioClip>(name);
        //播放音效
        sePlayer.PlayOneShot(clip);
    }
}

製作坦克預設體

在這裏插入圖片描述

代碼:坦克預設體TankBass

public class TankBass : MonoBehaviour {
    //輪胎,即車輪碰撞器
    public WheelCollider[] wheel;
    //血量。public使我們可以在unity裏修改血量。
    public int Hp = 100;
    //炮臺
    public Transform Turret;
    //子彈。每個坦克都會實例化子彈
    public GameObject BulletPre;
    //爆炸效果
    public GameObject BombPre;
    //開火點
    public Transform FirePoint;


    //protected 受保護的(該類和子類可以訪問)。
    //子類一定會在自己的Start、Update裏寫東西,所以,寫成虛方法virtual
    protected virtual void Start () {
		
	}

    protected virtual void Update () {
		//如果血量小於等於0,就不能對坦克進行操作了
        if (Hp <= 0)
        {
            return;
        }
	}

    //受到攻擊。把子彈寫成一個觸發
    private void OnTriggerEnter(Collider other)
    {
        //受到子彈攻擊。觸發的Tag值等於子彈Bullet,血量大於100。
        if (other.tag == "Bullet" && Hp > 0)
        {
            //減血
            Hp -= 30;
            //播放被打中時的音效
            AudioManager.Instance.PlaySound("hitWall");
            //判斷血量
            if(Hp <= 0)
            {
                //播放爆炸時的聲音
                AudioManager.Instance.PlaySound("boom");
                //實例化爆炸效果。在當前位置爆炸
                Instantiate(BombPre, transform.position, Quaternion.identity);
                //炸飛炮臺
                //由於之前沒有給炮臺添加剛體,此處通過代碼添加
                /*先拿到炮臺這個物體gameObject.添加一個組件AddComponent<>,
                把組件的類型寫到<>裏。此時就添加了剛體。*/
                Turret.gameObject.AddComponent<Rigidbody>();
                /*給這個剛體,一個向上的力AddForce(Vector3.up * 300f)。
                首先得到這個剛體Turret.GetComponent<Rigidbody>()*/
                Turret.GetComponent<Rigidbody>().AddForce(Vector3.up * 300f);
                //銷燬炮臺。5之後應該是落地了。
                Destroy(Turret.gameObject, 5f);
            }
        }
    }

    //開火。
    //protected 受保護的(該類和子類可以訪問)。但是還不確定子類是否要重寫方法,所以不要寫成虛方法。
    protected void Fire()
    {
        //播放開火的聲音
        AudioManager.Instance.PlaySound("bullet");
        //實例化子彈。位置和開火點一樣,旋轉和開火點一樣。
        Instantiate(BulletPre, FirePoint.position, FirePoint.rotation);
    }
} 

製作炮彈,利用坦克預設體制作玩家坦克、敵人坦克

在這裏插入圖片描述

代碼:炮彈BulletControl

public class BulletControl : MonoBehaviour {
    
	void Start () {
        //給子彈一個向前方的力。因爲這個裏只給一次,所以在Start裏面寫就好了。
        GetComponent<Rigidbody>().AddForce(transform.forward * 3000f);
    }

    //子彈銷燬。無論碰到什麼,銷燬自己。
    private void OnTriggerEnter(Collider other)
    {
        Destroy(gameObject);
    }
} 

代碼:玩家坦克PlayerControl

 public class PlayerControl : TankBass {
    //修改繼承、繼承於TankBass。

    //希望炮管可以上下移動,先找到炮管。
    public Transform Guntrans;
    //計時器
    private float timer;

    protected override void Start()
    {
        base.Start();
        //“base.Start();”表示,會調用父類裏的Start方法。
        //鼠標隱藏。鼠標的模式改成鎖定的。
        Cursor.lockState = CursorLockMode.Locked;

    }
    protected override void Update()
    {
        base.Update();
        // Update控制移動
        //首先得到輸入軸
        float vertical = Input.GetAxis("Vertical");
        float horizontal = Input.GetAxis("Horizontal");
       //如果水平軸不爲零
       if(horizontal != 0)
        {
            //轉向
            wheel[0].steerAngle = horizontal * 50;
            wheel[1].steerAngle = horizontal * 50;
            //播放移動的聲音
            AudioManager.Instance.PlayMusic("move");
        }
        else
        {
            AudioManager.Instance.StopMusic();
        }
       //如果垂直軸不等於0
       if(vertical != 0)
        {
            //前進。給垂直方向上的力
            wheel[2].motorTorque = vertical * 2000;
            wheel[3].motorTorque = vertical * 2000;
        }
       

        //左右旋轉炮臺。監聽鼠標的左右滑動。
        float mouseX = Input.GetAxis("Mouse X");
        //如果這個值不爲0
        if(mouseX != 0)
        {
            //旋轉歐拉角。垂直軸(Y軸)*鼠標左右移動(有正負)*20度*換算單位(變成每秒)
            Turret.localEulerAngles += Vector3.up * mouseX * 20 * Time.deltaTime;
        }

        //上下旋轉炮管。監聽鼠標的上下滑動。
        float mouseY = Input.GetAxis("Mouse Y");
        //如果這個值不爲0
        if (mouseY != 0)
        {
            //旋轉歐拉角。垂直軸(Y軸)*鼠標左右移動(有正負)*20度*換算單位(變成每秒)
            Guntrans.localEulerAngles += Vector3.left * mouseY * 5 * Time.deltaTime;
            //限制角度。當前的角度Vector3.Angle(炮管的正前方,炮臺的正前方)
            float angle = Vector3.Angle(Guntrans.forward, Turret.forward);
            //如果上下都大於5度
            if(angle > 5)
            {
                //就把要加的度數減回來
                Guntrans.localEulerAngles -= Vector3.left * mouseY * 5 * Time.deltaTime;
            }
        }

        //開火。最好給一個計時器,不能讓它一直開火。
        //計時器在這裏一直計時
        timer += Time.deltaTime;
        //此處,規定1秒可以開一發,並且按了左鍵
        if(timer > 1f && Input.GetMouseButtonDown(0))
        {
            //把timer置爲0
            timer = 0;
            //調用開火方法
            Fire();
        }
    }
}

代碼:敵人坦克EnemyControl

雖然敵人坦克的腳本代碼很少,但它繼承了父類坦克允許他繼承的方法。
敵人是否有其他功能,需完善。

 public class EnemyControl : TankBass{
    //修改繼承、繼承於TankBass。
}

製作小地圖

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章