【Unity2D入门教程】简单制作战机弹幕射击游戏② C#编写 Player和Enemy脚本

学习目标:

上期的水平大伙看到我已经写好了Enemy和Player的脚本了,现在就把脚本教给大伙,话不多说搞的不丑


学习内容:

首先是Player的脚本(之前没发现CSDN有这个代码段的,我的我的)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{


    [Header("玩家移动")]
    [SerializeField] float ySpeed = 10f;
    [SerializeField] float xSpeed = 10f;
    [SerializeField] float padding = 1f;

    [Header("Play Health")]
    [SerializeField] int health = 500;

    [Header("ProjectTile")]
    [SerializeField] GameObject laserPrefab;
    [SerializeField] float projectTileSpeed = 10f;
    [SerializeField] float projectTileFiringPeriod = 0.1f;
    //战机在屏幕能移动的坐标
    float xMin;
    float xMax;
    float yMin;
    float yMax;

    //协程的编程是指在不堵塞主线程的情况下执行某些特定的函数
    Coroutine fireCoroutine;
    void Start()
    {
        SetUpMoveBoundaries();
    }
    private void SetUpMoveBoundaries()
    {
        Camera gameCamera = Camera.main;
        //之前的视频说过,Camera.main.ViewportToWorldPoint()是将摄像机视角的坐标转化为世界坐标然后padding是防止战机出屏幕边缘
        xMin = gameCamera.ViewportToWorldPoint(new Vector3(0, 0, 0)).x + padding;
        xMax = gameCamera.ViewportToWorldPoint(new Vector3(1, 0, 0)).x - padding;
        yMin = gameCamera.ViewportToWorldPoint(new Vector3(0, 0, 0)).y + padding;
        yMax = gameCamera.ViewportToWorldPoint(new Vector3(0, 1, 0)).y - padding;
    }
    void Update()
    {
        Move();
        Fire();
    }
    private void Move()
    {
        //Input Manager上两个监控键盘上WSAD按键而生成-1到1值的
        var deltaY = Input.GetAxis("Vertical") * Time.deltaTime * ySpeed;
        var deltaX = Input.GetAxis("Horizontal") * Time.deltaTime * xSpeed;
       // Debug.Log(deltaX);
       //限制移动范围
        var newXPos = Mathf.Clamp(transform.position.x + deltaX, xMin, xMax);
        var newYPos = Mathf.Clamp(transform.position.y + deltaY, yMin, yMax);

        transform.position = new Vector2(newXPos,newYPos);
    }
    private void Fire()
    {
        if (Input.GetButtonDown("Fire1"))
        {
           fireCoroutine =  StartCoroutine(FireContinuously());
        }
        if (Input.GetButtonUp("Fire1"))//这个Fire1也是Input Manager上的
        {
            StopCoroutine(fireCoroutine); //暂停某个协程
            // StopAllCoroutines();
        }
    }
    //协程函数是用关键字迭代器IEnumerator而且一定要用yield关键词返回
    IEnumerator FireContinuously()
    {
        while (true)
        {
            GameObject laser = Instantiate(laserPrefab, transform.position, Quaternion.identity) as GameObject; //生成子弹
            laser.GetComponent<Rigidbody2D>().velocity = new Vector2(0, projectTileSpeed); //给子弹一个向上的力
            yield return new WaitForSeconds(projectTileFiringPeriod); //下一颗子弹发生的间隔时间
        }
    }

    private void OnTriggerEnter2D(Collider2D other)
    {
        DamageDealer damageDealer = other.gameObject.GetComponent<DamageDealer>();
        if (!damageDealer) { return; }
        ProcessHit(damageDealer);
    }

    private void ProcessHit(DamageDealer damageDealer)
    {
        health -= damageDealer.GetDamage(); //减去收到的伤害
        damageDealer.Hit();
        if (health <= 0)
        {
            Destroy(gameObject); //生命值为小于等于0就销毁
        }
    }
}

代码中我说的是Input Manager可以在菜单栏上找到

 

Positive表示的是正向

 Negative则是反向的,对于Horizontal 和 Vertical来说,反向意味着是0到-1的负值

DamageDealer是处理收到伤害的时候触发的脚本

内容如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DamageDealer : MonoBehaviour
{
    [SerializeField] int damage = 100;

    public int GetDamage()
    {
        return damage;
    }
    public void Hit()
    {
        Destroy(gameObject);    
    }
}

这个脚本使挂载到子弹Laser的游戏对象上的,下一期再讲

然后最后是Enemy脚本

内容如下

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Enemy : MonoBehaviour
{
    [SerializeField] float health = 100f;
    [SerializeField] float shotCounter;
    [SerializeField] float minTimeBetweenShots = 0.2f;
    [SerializeField] float maxTimeBetweenShot = 1.5f;
    [SerializeField] GameObject projecttile;
    [SerializeField] float projecttileSpeed = 10f;
    void Start()
    {
        shotCounter = Random.Range(minTimeBetweenShots, maxTimeBetweenShot);
    }

    void Update()
    {
        CountDownAndShoot();
    }
    private void CountDownAndShoot()
    {
        shotCounter -= Time.deltaTime; //计时器,用来当计时器小于等于0时重置发射时间并执行发射函数
        if(shotCounter <= 0)
        {
            Fire();
            shotCounter = Random.Range(minTimeBetweenShots, maxTimeBetweenShot);
        }
    }
    private void Fire()
    {
        GameObject laser = Instantiate(projecttile, transform.position, Quaternion.identity) as GameObject;//生成子弹并给它一个向下的力,因为和主角方向反过来的
        laser.GetComponent<Rigidbody2D>().velocity = new Vector2(0, -projecttileSpeed);
    }
    private void OnTriggerEnter2D(Collider2D other)
    {
        DamageDealer damageDealer = other.gameObject.GetComponent<DamageDealer>();
        if (!damageDealer) { return; }
        ProcessHit(damageDealer); //同样也是伤害处理的函数
    }

    private void ProcessHit(DamageDealer damageDealer)
    {        
        health -= damageDealer.GetDamage();
        damageDealer.Hit();
        if (health <= 0)
        {
            Destroy(gameObject);
        }
    }
}

学习产出:

别忘了设置好脚本上的参数,以及将我们创建的子弹预设体拖上去

挂载好以后,我们就可以实现Player的上下左右移动以及按住鼠标发射子弹和敌人也发射子弹

下一期教一下有关子弹的组件和脚本

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值