【unity之IMGUI实践】敌方逻辑封装实现【六】

这篇具有很好参考价值的文章主要介绍了【unity之IMGUI实践】敌方逻辑封装实现【六】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【unity之IMGUI实践】敌方逻辑封装实现【六】,# UnityGUI篇,# unity简单游戏demo制作,unity,游戏引擎,单例模式,c#,游戏


👨‍💻个人主页:@元宇宙-秩沅

👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅!

👨‍💻 本文由 秩沅 原创

👨‍💻 收录于专栏unityUI专题篇
【unity之IMGUI实践】敌方逻辑封装实现【六】,# UnityGUI篇,# unity简单游戏demo制作,unity,游戏引擎,单例模式,c#,游戏


⭐通用API实现抽象行为封装【五】⭐



🎶前言

【unity之IMGUI实践】敌方逻辑封装实现【六】,# UnityGUI篇,# unity简单游戏demo制作,unity,游戏引擎,单例模式,c#,游戏
【unity之IMGUI实践】敌方逻辑封装实现【六】,# UnityGUI篇,# unity简单游戏demo制作,unity,游戏引擎,单例模式,c#,游戏


🅰️


🎶(A)UML


【unity之IMGUI实践】敌方逻辑封装实现【六】,# UnityGUI篇,# unity简单游戏demo制作,unity,游戏引擎,单例模式,c#,游戏


🎶(B)需求分析


【unity之IMGUI实践】敌方逻辑封装实现【六】,# UnityGUI篇,# unity简单游戏demo制作,unity,游戏引擎,单例模式,c#,游戏
【unity之IMGUI实践】敌方逻辑封装实现【六】,# UnityGUI篇,# unity简单游戏demo制作,unity,游戏引擎,单例模式,c#,游戏


🎶(C)行为实现——炮台的自动检测并攻击


【unity之IMGUI实践】敌方逻辑封装实现【六】,# UnityGUI篇,# unity简单游戏demo制作,unity,游戏引擎,单例模式,c#,游戏


😶‍🌫️:步骤实现
1.炮台的行为逻辑封装:旋转,触发检测,发射炮弹及特效
2.检测玩家后自动瞄准攻击
3.玩家扣血,更新血条,触发保护罩特效及死亡


——————————————【unity之IMGUI实践】敌方逻辑封装实现【六】,# UnityGUI篇,# unity简单游戏demo制作,unity,游戏引擎,单例模式,c#,游戏

涉及到四个脚本

炮台封装

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//—————————————————————————————————————
//___________项目:       ______________
//___________功能: 炮台的行为逻辑实现
//___________创建者:秩沅_______________
//_____________________________________
//-------------------------------------
public class battery : TankFather
{
    public AudioSource shootMusic;   //发射音效
    public GameObject shootball;     //发射的子弹类型
    public float shootSpeed = 1000f; //子弹的速度 
    public Transform shootTransform; //发射的组件信息
    public bool shootSwitch = false;
    //射击检测参数
    public Transform player;         //闯入者
    private float endTime = 8f;      //子弹发射间隔的时间

    
    private void Start()
    {
        //属性初始化赋值
        Head = transform.GetChild(0);
        maxBlood = 500;
        nowBlood = 500;
        attack = 20;   
        HeadSpeed = 50;
        //射击音效关闭
        shootMusic.enabled = false;
 
    }

    private void Update()
    {  
        if (shootSwitch == false)   //不停的旋转
        {
            Head.transform.Rotate(Vector3.up * HeadSpeed * Time.deltaTime);
        }          
        else 
        {
            Head.transform.LookAt(player);
            //倒计时发射子弹
            endTime = Mathf.MoveTowards(endTime, 0, 0.1f);
            if(endTime <= 0)
            {
                Fire();
                endTime = 3f;
            }
        }     
    }

    //玩家进入范围内就开始射击
    private void OnTriggerEnter(Collider other)
    {
        if(other.tag == "Player")
        {
            shootSwitch = true;
            player = other.transform;
        }

       
    }

    //受伤检测
    private void OnTriggerStay(Collider other)
    {
        float off = Vector3.Distance(other.transform.position, transform.position);
        if (other.gameObject.tag == "bullet" && off < 2)
        {
            //添加子弹挂载的目标坦克,方便获取该子弹的攻击力,与受伤逻辑相结合
            BulletMove ball = other.gameObject.GetComponent<BulletMove>();
            TankFather ballTank = ball.Tank.GetComponent<TankFather>();

            //当子弹不是自己打的到自己身上的时候
            if (ballTank.tag != gameObject.tag)
            {
                //扣血
                Heart(ballTank);
            }

        }
    }
    
    //玩家出去后就停止射击
    private void OnTriggerExit(Collider other)
    {
        if (other.tag == "Player")
        {
            shootSwitch = false;
        }
    }

    //开火重写
    public override void Fire()
    {
      //开启射击音效
      shootMusic.enabled = true;
      shootMusic.Play();
      GameObject ball =  Instantiate(shootball, shootTransform.position , shootTransform.rotation);
      BulletMove movScript = ball.GetComponent<BulletMove>();
      Rigidbody shootBall = ball.GetComponent<Rigidbody>();
      shootBall.AddForce(shootTransform .transform.forward * shootSpeed );
      movScript.Tank =gameObject ;  //声明子弹是由谁打出去的
    }

    
}


坦克基类更新

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//—————————————————————————————————————
//___________项目:       
//___________功能: 坦克基类——集中子类相同点
//___________创建者:______秩沅______
//___________________________________
//-------------------------------------
public abstract  class TankFather : MonoBehaviour
{
    //攻击和防御相关
    public int attack;
    public int defence; 
    public float  nowBlood;
    public float  maxBlood;
    //移动和转速相关
    public int moveSpeed;
    public int RotateSpeed;
    public int HeadSpeed;
    public Transform  Head;
    //击败特效
    public GameObject diedEffect;
    //收到伤害打开保护罩的特效
    public GameObject ProtectEffectMain;
    public GameObject ProtectEffectOther;

    private void Awake()
    {
       // ProtectEffectMain = Resources.Load<GameObject>(@"Prefabs/OherResoure/Protect1");
       // ProtectEffectOther = Resources.Load<GameObject>(@"Prefabs/OherResoure/Protect2");
    }

    //受伤行为
    public virtual  void Heart(TankFather other)
    {
       
        //当攻击力大于防御力时才生效
        if (other.attack - defence > 0)
            {
                nowBlood -= (other.attack - defence);
            }
        if (nowBlood <= 0)
            {
                nowBlood = 0;
                Death();
            }

        if (gameObject.tag == "Player")//如果是主玩家才更新血条
        {
            //更新血条
            GamePlane.SingleInstance.UpdataBlood(maxBlood, nowBlood);
            //实例化保护罩的特效       
            GameObject eff = Instantiate(ProtectEffectMain, transform.position, transform.rotation);
            Destroy(eff,1f);
        }
      
        
    }

    //死亡行为
    public virtual  void Death()
    {
      
        //将特效实例化相关逻辑
        GameObject effect = Instantiate(diedEffect, this.transform.position ,this.transform.rotation);
        AudioSource soudClip = effect.GetComponent<AudioSource>();
        soudClip.enabled  = MusicContol.SingleMusicContol.nowMusicData.soundSwitch;
        soudClip.volume = MusicContol.SingleMusicContol.nowMusicData.soundRoll ;
        soudClip.mute = false;
        soudClip.playOnAwake = true;
        //死亡后展示死亡面板
        if (gameObject.tag == "Player")
        {
            Destroy(gameObject, 2F);
            DiedPlane.SingleInstance.Show();
        }
        else
        Destroy(gameObject);

      
      
    }

    //开火行为
    public abstract void Fire();  //子类中每一个的开火方式都不同,作为抽象方法
    
   
}

主坦克类更新

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//—————————————————————————————————————
//___________项目:       
//___________功能:  坦克的移动和旋转
//___________创建者:_______秩沅_______
//_____________________________________
//-------------------------------------
public class MainTank : TankFather
{
    //主坦克专有特征
    public  Weapon nowWeapon;
   
  

    //特征属性初始化
    private void Awake()
    {
        Head = transform.GetChild(1).GetChild(0);
        maxBlood = 1000;
        nowBlood = 1000;
        attack = 30;
        defence = 10;
        moveSpeed = 5;
        RotateSpeed = 50;
        HeadSpeed = 500;
    }

    private void Update()
    {
        //坦克的移动 = 大小*方向
        transform.Translate(Input.GetAxis("Vertical") *Vector3.forward*moveSpeed *Time.deltaTime );
        //坦克的旋转 = 大小*轴向
        transform.Rotate(Input.GetAxis("Horizontal") *Vector3.up *RotateSpeed *Time .deltaTime );
        //头部炮管的旋转 = 大小*轴向
        Head.Rotate(Input.GetAxis ("Mouse X") *Vector3.up*HeadSpeed*Time .deltaTime );
        //左键发射炮弹
        if(Input.GetMouseButtonDown(0))
        {
            Fire();

        }
    }

   

    //捡武器行为
    public void ChangeWeapon(GameObject weapon)
    {
        if (nowWeapon != null) nowWeapon.Vanish();  //销毁当前武器
        nowWeapon = weapon.GetComponent<Weapon>();       
        //头部留有存放武器的位置
        weapon.gameObject.transform.position = Head.GetChild(0).transform.position ;
        weapon.gameObject.transform.rotation = Head.GetChild(0).transform.rotation;
        weapon.gameObject.transform.SetParent(Head.GetChild(0));
        attack += nowWeapon.attack;
     
    }

    //开火行为重写
    public override void Fire() 
    {
        nowWeapon.Shoot(); 
    }

    //被子弹打到
    private void OnTriggerEnter(Collider other)
    {
       if(other.tag == "bullet")
        {
            try
            {
                //添加子弹挂载的目标坦克,方便获取该子弹的攻击力,与受伤逻辑相结合
                BulletMove ball = other.GetComponent<BulletMove>();
                TankFather ballTank = ball.Tank.GetComponent<TankFather>();

                //当子弹不是自己打的到自己身上的时候
                if (ballTank.tag != "Player")
                {
                    //扣血
                    Heart(ballTank);

                }
            }
            catch
            {
                throw;
            }

        }

    }

}

子弹发射更新

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//—————————————————————————————————————
//___________项目:       ______________
//___________功能:  子弹的逻辑相关
//___________创建者:秩沅_______________
//_____________________________________
//-------------------------------------
public class BulletMove : MonoBehaviour
{
    public  GameObject Tank;          //挂载在哪个坦克上
    public  GameObject DeidEffect;
    public  AudioSource distorySound; //销毁的音效
 

    private void Start()
    {
       
    }
    //子弹的销毁及特效
    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Environment")|| other.CompareTag("Enemy"))
        {
            if (DeidEffect != null)
            {
                GameObject eff =  Instantiate(DeidEffect, transform.position, transform.rotation);
                //音效控制
                distorySound = eff.GetComponent<AudioSource>();
                distorySound.enabled = MusicContol.SingleMusicContol.nowMusicData.soundSwitch;
                distorySound.volume = MusicContol.SingleMusicContol.nowMusicData.soundRoll;
                eff.AddComponent<SelfDestroy>();
            }
            Destroy(this.gameObject,2f);          
        }    
    }
    

}


🎶(D)行为实现——敌军坦克的移动路线和检测攻击


【unity之IMGUI实践】敌方逻辑封装实现【六】,# UnityGUI篇,# unity简单游戏demo制作,unity,游戏引擎,单例模式,c#,游戏
😶‍🌫️:步骤实现

  • 1.指定移动位置,设置朝向
  • 2.行为逻辑封装。开火,受伤
  • 3.自动检测闯入者

———— --------------————【unity之IMGUI实践】敌方逻辑封装实现【六】,# UnityGUI篇,# unity简单游戏demo制作,unity,游戏引擎,单例模式,c#,游戏

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//—————————————————————————————————————
//___________项目:      
//___________功能:敌方坦克逻辑封装
//___________创建者:秩沅_______________
//_____________________________________
//-------------------------------------
public class EnemyTank:TankFather 
{
    //随机移动点的位置数组
    public  Transform[] randomPosition;
    //目标位置
    private Transform target;
    //目标坦克
    public Transform Player;
    //检测范围
    public float distance = 10f;

    public AudioSource shootMusic;   //发射音效
    public GameObject shootball;     //发射的子弹类型
    public float shootSpeed = 1000f; //子弹的速度 
    public Transform[] shootTransform; //发射的组件信息
    public bool shootSwitch = false;  
    private float endTime = 3f;      //子弹发射间隔的时间

    private void Start()
    {
        //属性初始化赋值
        
        maxBlood = 500;
        nowBlood = 500;
        attack = 30;
        HeadSpeed = 50;
        //射击音效关闭
        shootMusic.enabled = false;
        moveSpeed = 10f;
        //先随机整一个目标点
        RandomPosition();

    }
    private void Update()
    {    
        transform.LookAt(target);

        //始终超自己的正方向移动
        transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);  //当距离差不多相等时,再随机目标点
        if(Vector3.Distance(transform .position ,target .position)< 0.5f)
        {
            RandomPosition();
        }
            

        //范围检测
        if (Vector3 .Distance(transform .position ,Player.position )<= distance && Player !=null )
        {
            //炮口瞄准玩家
            Head.transform.LookAt(Player);
            //倒计时发射子弹
            endTime = Mathf.MoveTowards(endTime, 0, 0.1f);
            if (endTime <= 0)
            {
                Fire();
                endTime = 3f;
            }        
        }
     
    }

    //随机指向一个移动点
    public void RandomPosition()
    {
        if (randomPosition.Length != 0)

            target = randomPosition[Random.Range(0, randomPosition.Length)];
    }
    //触发检测
    private void OnTriggerEnter(Collider other)
    {
       
        if (other.gameObject.tag == "bullet" )
        {
            //添加子弹挂载的目标坦克,方便获取该子弹的攻击力,与受伤逻辑相结合
            BulletMove ball = other.gameObject.GetComponent<BulletMove>();
            TankFather ballTank = ball.Tank.GetComponent<TankFather>();

            //当子弹不是自己打的到自己身上的时候
            if (ballTank.tag != gameObject.tag)
            {
                //扣血
                Heart(ballTank);
            }

        }
    }

    public override void Fire()
    {
        //开启射击音效
        shootMusic.enabled = true;
        shootMusic.Play();
        for (int i = 0; i < shootTransform.Length ; i++)
        {
            GameObject ball = Instantiate(shootball, shootTransform[i].position, shootTransform[i].rotation);
            BulletMove movScript = ball.GetComponent<BulletMove>();
            Rigidbody shootBall = ball.GetComponent<Rigidbody>();
            shootBall.AddForce(shootTransform[i].transform.forward * shootSpeed);
            movScript.Tank = gameObject;  //声明子弹是由谁打出去的
        }
     
    }

}

问题:
1.受到伤害,开启了保护罩但是不扣血
2.敌方坦克,原地打转,未按规定路线移动
解决:
1.子弹检测逻辑错误
2.位置空点绑定在对象身上变成了子对象因此无法达到效果

总结:

【unity之IMGUI实践】敌方逻辑封装实现【六】,# UnityGUI篇,# unity简单游戏demo制作,unity,游戏引擎,单例模式,c#,游戏

  • 1.检测触发的方式:①触发器检测②向量距离检测
  • 2.多点指定移动,加入向量距离判断,重合的机率小,故此不能 A物体距离 == B物体距离
  • 3.子坦克继承了父类脚本,引用传递时直接用父类即可获得该子类,(原因父类名字相同,但是子类名字不同,无法确定,所以里氏替换作用在此体现)

相关文章


⭐【2023unity游戏制作-mango的冒险】-6.关卡设计

⭐【2023unity游戏制作-mango的冒险】-5.攻击系统的简单实现

⭐【2023unity游戏制作-mango的冒险】-4.场景二的镜头和法球特效跟随

⭐【2023unity游戏制作-mango的冒险】-3.基础动作和动画API实现

⭐【2023unity游戏制作-mango的冒险】-2.始画面API制作

⭐【2023unity游戏制作-mango的冒险】-1.场景搭建

⭐“狂飙”游戏制作—游戏分类图鉴(网易游学)

⭐本站最全-unity常用API大全(万字详解),不信你不收藏



你们的点赞👍 收藏⭐ 留言📝 关注✅是我持续创作,输出优质内容的最大动力!文章来源地址https://www.toymoban.com/news/detail-612565.html

到了这里,关于【unity之IMGUI实践】敌方逻辑封装实现【六】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【unity之IMGUI实践】抽象父类继承实现【三】

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 : unityUI专题篇 🅰️ 总效果图 😶‍🌫️:步骤 1.创建游戏面板,进行组件管控 2.创建提示面板进行退出确定 3.同步面板直接的显隐和复

    2024年02月16日
    浏览(42)
  • 【Unity之IMGUI脚本封装】—自定义常用控件的封装(即拿即用)

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 :UnityUI篇实战 UML类图 封装代码: 按钮封装代码 封装代码 UML类图 封装代码 封装代码 封装代码 GUI.DrawTextrrue 没有自定义样式的重载 封装代

    2024年02月16日
    浏览(34)
  • 【Unity之IMGUI脚本封装】—编译模式下控件可视化及其封装

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 :UnityUI篇实战 缺点1:无法在编译过程进行可视化调整 缺点2:无法分辨率自适应 此图可忽略 UML类图 性能优化代码 完整代码: 按钮封装代

    2024年02月15日
    浏览(47)
  • 【Unity之IMGUI脚本封装】—位置信息类和控件基类的封装

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 : 缺点1:无法在编译过程进行可视化调整 缺点2:无法分辨率自适应 作用:让控件根据调整对齐 最终代码 特点: 类是抽象类:原因基类

    2024年02月17日
    浏览(34)
  • 【Unity之IMGUI】—自定义常用控件的封装(即拿即用)

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 :UnityUI篇实战 UML类图 封装代码: 按钮封装代码 封装代码 UML类图 封装代码 封装代码 封装代码 GUI.DrawTextrrue 没有自定义样式的重载 封装代

    2024年02月11日
    浏览(32)
  • 【Unity之IMGUI】—编译模式下控件可视化及其封装

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 :UnityUI篇实战 缺点1:无法在编译过程进行可视化调整 缺点2:无法分辨率自适应 此图可忽略 UML类图 性能优化代码 完整代码: 按钮封装代

    2024年02月10日
    浏览(32)
  • 【Unity之IMGUI】—位置信息类和控件基类的封装

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 : 缺点1:无法在编译过程进行可视化调整 缺点2:无法分辨率自适应 作用:让控件根据调整对齐 最终代码 特点: 类是抽象类:原因基类

    2024年02月12日
    浏览(25)
  • 【unity之IMGUI实践】单例模式管理数据存储【二】

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 : unityUI专题篇 🅰️ 😶‍🌫️:步骤实现 1.首先将音乐数据封装在类中,不采用单例模式 2. 而后封装一个游戏数据类为单例模式:功能

    2024年02月16日
    浏览(37)
  • 【unity之IMGUI实践】单例模式管理面板对象【一】

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 : unityUI专题篇 🅰️ API:简单的旋转 解析: 1.采用单例模式,原因: 单例模式无法被纂改基类,适合当管理者 2.基类提取了子类所有的共

    2024年02月15日
    浏览(38)
  • Unity中敌人简单逻辑的实现(来回走动,攻击)2D

    unity自带一套自动巡航系统,但是目前应该先了解最基本的使用代码控制敌人实现逻辑(1来回走动,2发现玩家时追着玩家,3进入敌人攻击范围时进行攻击),一般来说这是最基本的敌人的功能 分析完敌人所具备的能力后,就将敌人的能力进行拆解,分别进行实现 一 来回走

    2024年02月12日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包