笔记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。
}

制作小地图

在这里插入图片描述

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