zoukankan      html  css  js  c++  java
  • 网络游戏制作---坦克大战(3)

    一、发射子弹

          这一部分实现玩家控制自己坦克发射子弹,而其他玩家保持不动。

          主要的思想使用RPC:

          1、首先为发射炮弹脚本添加PhotonView组件

          2、如果是本地组件,直接调用Fire()函数

          3、调用远程玩家的RPC的Fire()函数,来实现远程玩家的设计效果,进而实现同步。

    代码如下:

        //初始化PhotonView组件变量
        private PhotonView pv = null;
    
        //向pv变量分配PhotonView组件
        pv = GetComponent<PhotonView>();
    
        void Update()
        {
            //如果PhotonView是自己本地的组件,则点击鼠标左键时执行发射逻辑
            if (pv.isMine&&Input.GetMouseButtonDown(0))
            {
                //如果是自己本地的坦克,则调用本地函数并发射炮弹
                Fire();
    
                //调用远程玩家客户端的RPC函数Fire函数
                pv.RPC("Fire", PhotonTargets.Others, null);
            }
        }
    
        [PunRPC]
        void Fire()
        {
            //播放炮弹发射的声音
            sfx.PlayOneShot(fireSfx, 1.0f);
            Instantiate(cannon, firePos.position, firePos.rotation);
        }

    完整的FireCannon代码:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class FireCannon : MonoBehaviour
    {
        //炮弹预设
        private GameObject cannon = null;
    
        //炮弹发射声音
        private AudioClip fireSfx = null;
        //AudioSource组件
        private AudioSource sfx = null;
    
        //炮弹发射初始点
        public Transform firePos;
    
        //初始化PhotonView组件变量
        private PhotonView pv = null;
    
        void Awake()
        {
            //加载Resources文件夹中的Cannon预设
            cannon = (GameObject)Resources.Load("Cannon");
    
            //从Resources文件夹中加载炮弹声音文件
            fireSfx = Resources.Load<AudioClip>("CannonFire");
            //声明AudioSource变量
            sfx = GetComponent<AudioSource>();
    
            //向pv变量分配PhotonView组件
            pv = GetComponent<PhotonView>();
        }
    
        // Start is called before the first frame update
        void Start()
        {
    
        }
    
        // Update is called once per frame
        void Update()
        {
            //如果PhotonView是自己本地的组件,则点击鼠标左键时执行发射逻辑
            if (pv.isMine&&Input.GetMouseButtonDown(0))
            {
                //如果是自己本地的坦克,则调用本地函数并发射炮弹
                Fire();
    
                //调用远程玩家客户端的RPC函数Fire函数
                pv.RPC("Fire", PhotonTargets.Others, null);
            }
        }
    
        [PunRPC]
        void Fire()
        {
            //播放炮弹发射的声音
            sfx.PlayOneShot(fireSfx, 1.0f);
            Instantiate(cannon, firePos.position, firePos.rotation);
        }
    }

    二、坦克被击中时的处理及复活

    1、设置坦克MeshRenderer组件变量、爆炸预设、生命值变量

        //为实现坦克爆炸后的透明处理,声明MeshRenderer组件数组变量
        private MeshRenderer[] renderers;
    
        //坦克爆炸效果预设
        private GameObject expEffect = null;
    
        //坦克初始生命值
        private int initHp = 100;
        private int currHp = 0;

    2、获取MeshRenderer组件、加载爆炸效果

        void Awake()
        {
            //获取坦克的MeshRenderer组件
            renderers = GetComponentsInChildren<MeshRenderer>();
    
            //将当前生命值更改为初始生命值
            currHp = initHp;
            //加载坦克爆炸时需要生成的爆炸效果
            expEffect = Resources.Load<GameObject>("Med Explosion");
        }

    3、检测碰撞

        void OnTriggerEnter(Collider coll)
        {
            //根据tag判断碰撞的是否为炮弹
            if (currHp > 0 && coll.GetComponent<Collider>().tag == "CANNON")
            {
                currHp -= 20;
            }
            if (currHp <= 0)
            {
                StartCoroutine(this.ExplosionTank());
            }
        }

    4、使用协程函数实现生成爆炸效果

        //生成爆炸效果并处理坦克的复活
        IEnumerator ExplosionTank()
        {
            //生成爆炸效果
            Object effect = GameObject.Instantiate(expEffect, transform.position, Quaternion.identity);
    
            Destroy(effect, 3.0f);
    
            //透明处理坦克
            SetTankVisible(false);
            //等待3秒
            yield return new WaitForSeconds(3.0f);
    
            //复活时设置初始生命值
            currHp = initHp;
            //使坦克再次可见
            SetTankVisible(true);
        }

    完整代码:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class TankDamage : MonoBehaviour
    {
        //为实现坦克爆炸后的透明处理,声明MeshRenderer组件数组变量
        private MeshRenderer[] renderers;
    
        //坦克爆炸效果预设
        private GameObject expEffect = null;
    
        //坦克初始生命值
        private int initHp = 100;
        private int currHp = 0;
    
        void Awake()
        {
            //获取坦克的MeshRenderer组件
            renderers = GetComponentsInChildren<MeshRenderer>();
    
            //将当前生命值更改为初始生命值
            currHp = initHp;
            //加载坦克爆炸时需要生成的爆炸效果
            expEffect = Resources.Load<GameObject>("Med Explosion");
        }
    
        void OnTriggerEnter(Collider coll)
        {
            //根据tag判断碰撞的是否为炮弹
            if (currHp > 0 && coll.GetComponent<Collider>().tag == "CANNON")
            {
                currHp -= 20;
            }
            if (currHp <= 0)
            {
                StartCoroutine(this.ExplosionTank());
            }
        }
    
        //生成爆炸效果并处理坦克的复活
        IEnumerator ExplosionTank()
        {
            //生成爆炸效果
            Object effect = GameObject.Instantiate(expEffect, transform.position, Quaternion.identity);
    
            Destroy(effect, 3.0f);
    
            //透明处理坦克
            SetTankVisible(false);
            //等待3秒
            yield return new WaitForSeconds(3.0f);
    
            //复活时设置初始生命值
            currHp = initHp;
            //使坦克再次可见
            SetTankVisible(true);
        }
    
        //激活/禁用MeshRenderer函数
        void SetTankVisible(bool isVisible)
        {
            foreach (MeshRenderer _renderer in renderers)
            {
                _renderer.enabled = isVisible;
            }
        }
    }

    每次写点游戏都的偷偷摸摸,结果还是被老板逮住了,那个勉强的笑不知道意味着什么,就希望他能让我顺利毕业,别为难我,我没什么信仰,论文实在看不下去,唉,开组会又要被骂了,每次针对我,我就是个废铁,非要让我做王者的任务,我该怎么办,小伙子,要抗住啊!

  • 相关阅读:
    简单工厂模式、工厂模式、抽象工厂模式
    直接插入排序
    简单选择排序的陷阱
    面试3 题目二,不修改数组找到重复的数字
    二进制中1的个数(读不懂题目怎么办)
    用两个栈实现队列
    斐波那契数列
    替换空格
    python 实现杨辉三角(依旧遗留问题)
    递归实现二分查找
  • 原文地址:https://www.cnblogs.com/Optimism/p/11099263.html
Copyright © 2011-2022 走看看