Unity Learning Week 4

game introduction

Unity development, by controlling the movement and attack of tanks, protecting the base and destroying enemy tanks.

development process

Background import and material processing

Select the backgrand in the material Graphics as the background.
insert image description here

If the material has not been divided and needs to be divided manually, click the material to be divided, select Multiple in Sprite Mode, click the Sprite Editor at the bottom right , select Apply to enter the segmentation page, click Slice at the upper left corner, select Slice, the system will automatically divide, and click Apply.
insert image description here
insert image description here

Formation of prefab and 2D animation

The formation of the prefab
Create a Prafads folder under the Project panel and drag the textures under the Hierarchy panel back to the Prafabs folder to form a prefab.
The formation of 2D animation
Hold down ctrl and drag multiple pictures into the Hierarchy panel, create an Animation folder, name it and save it to the Animation folder.

Control the player's movement and its direction

 public void Move()
    {
    
    

        float i = Input.GetAxis("Horizontal");
        transform.Translate(Vector3.right * i * MoveSpeed * Time.fixedDeltaTime, Space.World);//施加一个向右的力随时间的变化而变化乘以移速
        if (i < 0)
        {
    
    
            sr.sprite = tanksprite[3];
            bulletsprite = new Vector3(0, 0, 90);
        }
        else if (i > 0)
        {
    
    
            sr.sprite = tanksprite[1];
            bulletsprite = new Vector3(0, 0, -90);
        }
        if (i != 0)
        {
    
    
            return;
        }
        float j = Input.GetAxis("Vertical");
        transform.Translate(Vector3.up * j * MoveSpeed * Time.fixedDeltaTime, Space.World);
        if (j < 0)
        {
    
    
            sr.sprite = tanksprite[2];
            bulletsprite = new Vector3(0, 0, 180);
        }
        else if (j > 0)
        {
    
    
            sr.sprite = tanksprite[0];
            bulletsprite = new Vector3(0, 0, 0);
        }
    }

player master code

public class Player : MonoBehaviour
{
    
    
    //属性
    public float MoveSpeed = 2;
    private Vector3 bulletsprite;
    private float time;
    private float defenttime=5;
    private bool isdefended=true;
    //引用方法
    public AudioClip attackAudio;//添加攻击音效
    public AudioClip explorAudio;//添加爆炸音效
    public SpriteRenderer sr;
    public Sprite[] tanksprite;//上,右,下,左
    public GameObject bulletPro;
    public GameObject explortank;
    public GameObject Shield0;
    private void Awake()
    {
    
    
        sr = GetComponent<SpriteRenderer>();
    }

Add a collider to solve the jitter

Add a rigid body and a collider to the player, and add a collider to other obstacles.
Click Constraints under the rigid body component to lock the Z axis to solve the rotation during movement.
Put the code in the FiexedUpdate life cycle function, because the fixed frame number can be Fix jitter

Tank's attack CD, mobile priority problem, level rendering

  private void FixedUpdate()//固定物理帧
    {
    
    
        if(Playerstate.Instance.isDefent)
        {
    
    
            return;
        }
        Move();
        //攻击CD
        if (time >= 0.4f)
        {
    
    
            Attack();
        }
        else
        {
    
    
            time += Time.fixedDeltaTime;
        }

    }

The larger the Oorder in Layer, the higher the rendering level.

Tank attack method, invincible protection time

  private void Attack()
    {
    
    
        if(Input.GetKeyDown(KeyCode.Space))//输入空格攻击
        {
    
    
            Instantiate(bulletPro, transform.position, Quaternion.Euler(transform.eulerAngles+bulletsprite));
            AudioSource.PlayClipAtPoint(attackAudio, transform.position);
            time = 0;

        }
    }
  void Update()
    {
    
    
        //保护时间
        if(isdefended)
        {
    
    
            Shield0.SetActive(true);
            defenttime -= Time.deltaTime;
            if(defenttime<=0)
            {
    
    
                isdefended = false;
                Shield0.SetActive(false);
            }
        }
     
     
    }

Death and Explosion of Tanks

 private void Die()
    {
    
    
        if(isdefended)
        {
    
    
            return;
        }
        Playerstate.Instance.dieplayer = true;
        //爆炸
        Instantiate(explortank, transform.position,transform.rotation);
        AudioSource.PlayClipAtPoint(explorAudio, transform.position);
        //死亡
        Destroy(gameObject);
    }

bullet script

public class Bullet : MonoBehaviour
{
    
    
    private float moveSpeed = 10;//子弹的移动速度
    public bool bulletplayer;
    // Start is called before the first frame update
    void Start()
    {
    
    
        
    }

    // Update is called once per frame
    void Update()
    {
    
    
        transform.Translate(transform.up*moveSpeed*Time.deltaTime,Space.World);
    }
    public void OnTriggerEnter2D(Collider2D collision)
    {
    
    
        switch(collision.tag)
        {
    
    
            case "Player1":
                {
    
    
                    if(!bulletplayer)
                    {
    
     collision.SendMessage("Die"); Destroy(gameObject); }
                   
                 }
                break;
            case "Heart":
                {
    
    
                    collision.SendMessage("Die");  //发送Die方法
                    Destroy(gameObject);
                }
                break;
            case "Wall":
                {
    
    
                    Destroy(collision.gameObject);
                    Destroy(gameObject);
                }
                break;
            case "Barriar":
                {
    
    
                    if (bulletplayer)
                    {
    
    
                        collision.SendMessage("PlayerAudio");
                    }
                    Destroy(gameObject);
                }
                break;
            case "Eneray":
                {
    
    
                    if(bulletplayer)
                    {
    
    
                        collision.SendMessage("Die");
                        Destroy(gameObject);
                    }
                   
                }
                break;
            default:break;

        }
    }
}

Enemy Scripting

public class Enemys : MonoBehaviour
{
    
    
    public float MoveSpeed = 2;
    private Vector3 bulletsprite;
    private float time;
    //private float defenttime = 3;
    private float timeChange=4;
    private float i;
    private float j=-1;
    //引用方法
    public SpriteRenderer sr;
    public Sprite[] tanksprite;//上,右,下,左
    public GameObject bulletPro;
    public GameObject explortank;

    private void Awake()
    {
    
    
        sr = GetComponent<SpriteRenderer>();
    }
    // Start is called before the first frame update
    void Start()
    {
    
    

    }

    // Update is called once per frame
    void Update()
    {
    
    
     
        //攻击CD
        if (time >= 3)
        {
    
    
            Attack();
        }
        else
        {
    
    
            time += Time.deltaTime;
        }
    }
    private void FixedUpdate()//固定物理帧
    {
    
    
        Move();
        
    }
    //坦克的攻击
    private void Attack()
    {
    
    
            Instantiate(bulletPro, transform.position, Quaternion.Euler(transform.eulerAngles + bulletsprite));
            time = 0;
        
    }
    //移动方法
    public void Move()
    {
    
    

        if (timeChange >= 4)
        {
    
    
            int num = Random.Range(0, 8);
            if (num >= 4)
            {
    
    
                i = 0;
                j = -1;
            }
            else if (num == 0)
            {
    
    
                j = 1;
                i = 0;
            }
            else if (num > 0 && num <= 2)
            {
    
    
                i = 1;
                j = 0;
            }
            else if (num > 2 && num < 4)
            {
    
    
                i = -1;
                j = 0;
            }
            timeChange = 0;
        }
        else
            timeChange += Time.fixedDeltaTime;

        
        transform.Translate(Vector3.right * i * MoveSpeed * Time.fixedDeltaTime, Space.World);//施加一个向右的力随时间的变化而变化乘以移速
        if (i < 0)
        {
    
    
            sr.sprite = tanksprite[3];
            bulletsprite = new Vector3(0, 0, 90);
        }
        else if (i > 0)
        {
    
    
            sr.sprite = tanksprite[1];
            bulletsprite = new Vector3(0, 0, -90);
        }
        if (i != 0)
        {
    
    
            return;
        }
        transform.Translate(Vector3.up * j * MoveSpeed * Time.fixedDeltaTime, Space.World);
        if (j < 0)
        {
    
    
            sr.sprite = tanksprite[2];
            bulletsprite = new Vector3(0, 0, 180);
        }
        else if (j > 0)
        {
    
    
            sr.sprite = tanksprite[0];
            bulletsprite = new Vector3(0, 0, 0);
        }
    }
    //坦克死亡方法
    private void Die()
    {
    
    

        Playerstate.Instance.score++;
        //爆炸
        Instantiate(explortank, transform.position, transform.rotation);

        //死亡
        Destroy(gameObject);
    }
    private void OnCollisionEnter2D(Collision2D collision)
    {
    
    
        if(collision.gameObject.tag=="Eneray")
        {
    
    
            timeChange = 4;
        }
    }
}

Tank spawn effects

public class Born : MonoBehaviour
{
    
    
    public GameObject BornPlayer;
    public GameObject[] EnemyBorn;
    public bool creatPlayer;
    public AudioClip bornAudio;
    // Start is called before the first frame update
    void Start()
    {
    
    
        Invoke("BornTank", 1.2f);  //延时特效
        AudioSource.PlayClipAtPoint(bornAudio, transform.position);
        Destroy(gameObject, 1.2f);   //延时销毁
    }

    // Update is called once per frame
    void Update()
    {
    
    
       
    }
    private void BornTank()
    {
    
    
        if (creatPlayer)
        {
    
    
            Instantiate(BornPlayer, transform.position, Quaternion.identity);
        }
        else
        {
    
    
            int num = Random.Range(0, 2);
            Instantiate(EnemyBorn[num], transform.position, Quaternion.identity);
        }
    }
}

Base (heart) explosion and death

public class Heart : MonoBehaviour
{
    
    
    public AudioClip dieAudio;
    public SpriteRenderer sr;
    public Sprite Borken;
    public GameObject Explorer;
    // Start is called before the first frame update
    void Start()
    {
    
    
        sr = GetComponent<SpriteRenderer>();
    }

    // Update is called once per frame
    //void Update()
    //{
    
    
        
    //}
    public void Die()
    {
    
    
        sr.sprite = Borken;
        Instantiate(Explorer,transform.position,transform.rotation);
        Playerstate.Instance.isDefent = true;
        AudioSource.PlayClipAtPoint(dieAudio,transform.position);
    }
}

map creation

public class MapCreat : MonoBehaviour
{
    
    
    private List<Vector3> itemlist = new List<Vector3>();
    //用来装饰地图
    //0,老家,1墙,2障碍,3出生,4河流,5草
    public GameObject[] item;
    private void Awake()
    {
    
    
        //老家
        GreateItem(item[0],new Vector3(0,-8,0),Quaternion.identity);
        //老家的墙
        GreateItem(item[1], new Vector3(-1, -8, 0), Quaternion.identity);
        GreateItem(item[1], new Vector3(1, -8, 0), Quaternion.identity);
        for(int i=-1;i<2;i++)
        {
    
    
            GreateItem(item[1], new Vector3(i, -7, 0), Quaternion.identity);
        }
        //初始化边界
        for(int i=-11;i<=10;i++)
        {
    
    
            GreateItem(item[6], new Vector3(i, -9, 0), Quaternion.identity);
        }
        for (int i = -11; i <=10; i++)
        {
    
    
            GreateItem(item[6], new Vector3(i, 9, 0), Quaternion.identity);
        }
        for (int i = -9; i <= 8; i++)
        {
    
    
            GreateItem(item[6], new Vector3(-11,i , 0), Quaternion.identity);
        }
        for (int i = -9; i <= 8; i++)
        {
    
    
            GreateItem(item[6], new Vector3(11, i, 0), Quaternion.identity);
        }
        //地图
        for(int i=0;i<60;i++)
        {
    
    
            GreateItem(item[1], CreateRandom(), Quaternion.identity);
        }
        for (int i = 0; i < 19; i++)
        {
    
    
            GreateItem(item[2], CreateRandom(), Quaternion.identity);
        }
        for (int i = 0; i < 18; i++)
        {
    
    
            GreateItem(item[4], CreateRandom(), Quaternion.identity);
        }
        for (int i = 0; i < 20; i++)
        {
    
    
            GreateItem(item[5], CreateRandom(), Quaternion.identity);
        }
        //玩家
        GameObject go = Instantiate(item[3], new Vector3(-2, -8, 0), Quaternion.identity);
            go.GetComponent<Born>().creatPlayer = true;
        //产生敌人
        GreateItem(item[3], new Vector3(-10, 8, 0), Quaternion.identity);
        GreateItem(item[3], new Vector3(10, 8, 0), Quaternion.identity);
        GreateItem(item[3], new Vector3(0, 8, 0), Quaternion.identity);
        //随时间产生
        InvokeRepeating("CreateEnemy",4,5);
    }
    private void GreateItem(GameObject CreategameObject,Vector3 Creatvector,Quaternion Craetquaternion)
    {
    
    
        GameObject itemgo = Instantiate(CreategameObject,Creatvector,Craetquaternion);
        itemgo.transform.SetParent(gameObject.transform);
        itemlist.Add(Creatvector);
    }
    //产生随机物
    private Vector3 CreateRandom()
    {
    
    
        //不产生边缘障碍
        while (true)
        {
    
    
            Vector3 Creatvector = new Vector3(Random.Range(-9, 10), Random.Range(-7, 8), 0);
            if (!HasPosition(Creatvector))
            {
    
    
                return Creatvector;
            }
        }
    }
    private bool HasPosition(Vector3 Creatpos)
    {
    
    
        for(int i=0;i<itemlist.Count;i++)
        {
    
    
            if(Creatpos==itemlist[i])
            {
    
     
                return true; 
            }
        }
        return false;
    }
    //随机产生敌人
    private void CreateEnemy()
    {
    
    
        int h = Random.Range(0, 3);
        Vector3 EnemyPos = new Vector3();
        if(h==0)
        {
    
    
           EnemyPos= new Vector3(-10, 8, 0);
        }
        else if(h==1)
        {
    
    
            EnemyPos = new Vector3(10, 8, 0);
        }
        else if(h==2)
        {
    
    
            EnemyPos = new Vector3(0, 8, 0);
        }

        GreateItem(item[3], EnemyPos , Quaternion.identity);
    }

}

Creation of player state management

Define the life value and score, which can be reflected in the UI interface in real time, death status, failure status, and call the corresponding method.

public class Playerstate : MonoBehaviour
{
    
    
    public int life = 3;
    public int score = 0;
    public bool dieplayer;
    public GameObject born;
    public GameObject isDefentUI;
    public bool isDefent;
    public Text playerLifeText;
    public Text playerScoreText;
    // Start is called before the first frame update
    //
    private static Playerstate instance;

    public static Playerstate Instance {
    
     get => instance; set => instance = value; }

    private void Awake()
    {
    
    
        Instance = this;
    }
    void Start()
    {
    
    

    }

    // Update is called once per frame
    void Update()
    {
    
    
        if(isDefent)
        {
    
    
            isDefentUI.SetActive(true);
            Invoke("ReturnMenu", 3);
        }
        if(dieplayer)
        {
    
    
            Reverce();  
        }
        playerLifeText.text = life.ToString();
        playerScoreText.text = score.ToString();
    }
    private void Reverce()
    {
    
    
        if (life <= 0)
        {
    
    
            //游戏失败
            isDefent = true;
            Invoke("ReturnMenu", 3);
        }
        else
        {
    
    
            life--;
            GameObject go = Instantiate(born, new Vector3(-2, -8, 0), Quaternion.identity);
            go.GetComponent<Born>().creatPlayer = true;
            dieplayer = false;
        }
    }
    private void ReturnMenu()
    {
    
    
        SceneManager.LoadScene(1);
    }
}

UI production

insert image description here

public class Image : MonoBehaviour
{
    
    
    public Transform poseone;
    public Transform posetwo;
        private float h = 1;
    // Start is called before the first frame update
    void Start()
    {
    
    
        
    }

    // Update is called once per frame
    void Update()
    {
    
    
        if(Input.GetKeyDown(KeyCode.W))
        {
    
    
            h = 1;
            transform.position = poseone.position;
        }
        else if(Input.GetKeyDown(KeyCode.S))
        {
    
    
            h = 2;
            transform.position = posetwo.position;
        }
        if (Input.GetKeyDown(KeyCode.Space) && h ==1)
        {
    
    
            SceneManager.LoadScene(0);
        }
    }
}

add sound effects

Audio Source components can be added by dragging and dropping.
insert image description here

Guess you like

Origin blog.csdn.net/AD_GOD/article/details/122906973