【UnityRPG游戏制作】NPC交互逻辑、动玩法


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

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

👨‍💻 本文由 秩沅 原创
👨‍💻 收录于专栏就业宝典

⭐🅰️推荐专栏⭐

⭐-软件设计师高频考点大全



文章目录

    • ⭐前言⭐
    • [🎶(==二==) NPC逻辑相关](#🎶(==二==) NPC逻辑相关)
    • [(==1==) NPC范围检测](#(==1==) NPC范围检测)
    • [(==2==) NPC动画添加](#(==2==) NPC动画添加)
    • [(==3==) NPC和玩家的攻击受伤交互(事件中心)](#(==3==) NPC和玩家的攻击受伤交互(事件中心))
    • [(==4==) NPC的受伤特效添加](#(==4==) NPC的受伤特效添加)
    • [(==5==) NPC的死亡特效添加](#(==5==) NPC的死亡特效添加)
    • ⭐🅰️⭐

⭐前言⭐


🎶(二) NPC逻辑相关



(1) NPC范围检测


csharp 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//-------------------------------
//-------功能: NPC交互脚本
//-------创建者:         -------
//------------------------------

public class NPCContorller : MonoBehaviour
{
    public PlayerContorller playerCtrl;

    //范围检测
    private void OnTriggerEnter(Collider other)
    {
        playerCtrl.isNearby  = true;
    }
    private void OnTriggerExit(Collider other)
    {
        playerCtrl.isNearby = false;
    }
}

(2) NPC动画添加




(3) NPC和玩家的攻击受伤交互(事件中心)


  • EnemyController 敌人
csharp 复制代码
   using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;

//-------------------------------
//-------功能:  敌人控制器
//-------创建者:         -------
//------------------------------

public class EnemyController : MonoBehaviour
{
    public GameObject player;   //对标玩家
    public Animator animator;   //对标动画机
    public GameObject enemyNPC; //对标敌人
    public int hp;              //血量
    public Image hpSlider;      //血条
    private int attack = 10;    //敌人的攻击力
    public float CD_skill ;         //技能冷却时间

    private void Start()
    {
       
        enemyNPC = transform.GetChild(0).gameObject;
        animator = enemyNPC.GetComponent<Animator>();
        SendEvent();  //发送相关事件
    }

    private void Update()
    {
        CD_skill += Time.deltaTime; //CD一直在累加

    }

    /// <summary>
    /// 发送事件
    /// </summary>
    private void SendEvent()
    {
        //传递怪兽攻击事件(也是玩家受伤时)
        EventCenter.GetInstance().AddEventListener(PureNotification.PLAYER_INJURY, (int attack) =>
        {
            animator.SetBool("attack",true ); //攻击动画激活     
        });

        //传递怪兽受伤事件(玩家攻击时)
        EventCenter.GetInstance().AddEventListener(PureNotification.PLAYER_ATTRACK, ( ) =>
        { 
                animator.SetBool("hurt", true);  //受伤动画激活
        });

        //传递怪兽死亡事件
        EventCenter.GetInstance().AddEventListener(PureNotification.NPC_Died , () =>
        {      
                animator.SetBool("died", true);  //死亡动画激活
                gameObject.SetActive(false);     //给物体失活
                //暴金币
        });

    }

    //碰撞检测
    private void OnCollisionStay(Collision collision)
    {
        if (collision.gameObject.tag == "Player") //检测到如果是玩家的标签
        {
         
            if(CD_skill > 2f)  //攻击动画的冷却时间
            {
                Debug.Log("怪物即将攻击");
                CD_skill = 0;
                //触发攻击事件
                EventCenter.GetInstance().EventTrigger(PureNotification.PLAYER_INJURY, Attack());
               
            }    
    
        }
    }



    /// <summary>
    /// 传递攻击力
    /// </summary>
    /// <returns></returns>
    public  int  Attack()
    {
        return attack;
    }
   
    //碰撞检测
    private void OnCollisionExit(Collision collision)
    {
        if (collision.gameObject.tag == "Player") //检测到如果是玩家的标签
        {
            animator.SetBool("attack", false);       
            collision.gameObject.GetComponent<PlayerContorller>().animator .SetBool("hurt", false);

        }
    }


    //范围触发检测
    private void OnTriggerStay(Collider other)
    {
      if(other.tag == "Player")  //检测到如果是玩家的标签
        {
            //让怪物看向玩家
            transform.LookAt(other.gameObject.transform.position);
            //并且向其移动
            transform.Translate(Vector3.forward * 1 * Time.deltaTime);
        
        }

    }
 
}
  • PlayerContorller玩家
csharp 复制代码
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UIElements;
using static UnityEditor.Experimental.GraphView.GraphView;

//-------------------------------
//-------功能: 玩家控制器
//-------创建者:        
//------------------------------

public class PlayerContorller : MonoBehaviour
{
    //-----------------------------------------
    //---------------成员变量区-----------------
    //-----------------------------------------

    public float  speed = 1;         //速度倍量
    public Rigidbody rigidbody;      //刚体组建的声明
    public Animator  animator;       //动画控制器声明
    public GameObject[] playersitem; //角色数组声明
    public bool isNearby = false;    //人物是否在附近
    public float CD_skill ;         //技能冷却时间
    public int curWeaponNum;        //拥有武器数
    public int attack ;             //攻击力
    public int defence ;            //防御力
  

    //-----------------------------------------
    //-----------------------------------------


    void Start()
    {
        rigidbody = GetComponent<Rigidbody>();

        SendEvent();//发送事件给事件中心
    }
    void Update()
    {
        CD_skill += Time.deltaTime;       //CD一直在累加
        InputMonitoring();
    }
        void FixedUpdate()
    {
        Move();
    }


    /// <summary>
    /// 更换角色[数组]
    /// </summary>
    /// <param name="value"></param>
    public void ChangePlayers(int value)
    {
        for (int i = 0; i < playersitem.Length; i++)
        {
            if (i == value)
            {
                animator = playersitem[i].GetComponent<Animator>();
                playersitem[i].SetActive(true);
            }
            else
            {
                playersitem[i].SetActive(false);
            }
        }
    }
  
    /// <summary>
    ///玩家移动相关
    /// </summary>
    private void Move()
    {
        //速度大小
        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");
    
        if (Input.GetAxis("Vertical") != 0 || Input.GetAxis("Horizontal") != 0)
        {
            //方向
            Vector3 dirction = new Vector3(horizontal, 0, vertical);
            //让角色的看向与移动方向保持一致
            transform.rotation = Quaternion.LookRotation(dirction);
            rigidbody.MovePosition(transform.position + dirction * speed * Time.deltaTime);
            animator.SetBool("walk", true);
            //加速奔跑
            if (Input.GetKey(KeyCode.LeftShift) )
            {
                animator.SetBool("run", true);
                animator.SetBool("walk", true);                
                rigidbody.MovePosition(transform.position + dirction * speed*3 * Time.deltaTime);
            }
            else 
            {
                animator.SetBool("run", false);;
                animator.SetBool("walk", true);
            }            
        }
        else 
        {
            animator.SetBool("walk", false);
        }
    }


    /// <summary>
    /// 键盘监听相关
    /// </summary>
    public void InputMonitoring()
    {
        //人物角色切换
        if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            ChangePlayers(0);
        }

        if (Input.GetKeyDown(KeyCode.Alpha2))
        {
            ChangePlayers(1);
        }

        if (Input.GetKeyDown(KeyCode.Alpha3))
        {
            ChangePlayers(2);
        }
        //范围检测弹出和NPC的对话框
        if (isNearby && Input.GetKeyDown(KeyCode.F))
        {          
            //发送通知打开面板
            GameFacade.Instance.SendNotification(PureNotification.SHOW_PANEL, "NPCTipPanel");
        
        }
        //打开背包面板
        if ( Input.GetKeyDown(KeyCode.Tab))
        {
            //发送通知打开面板
            GameFacade.Instance.SendNotification(PureNotification.SHOW_PANEL, "BackpackPanel");

        }
        //打开角色面板
        if ( Input.GetKeyDown(KeyCode.C))
        {
            //发送通知打开面板
            GameFacade.Instance.SendNotification(PureNotification.SHOW_PANEL, "RolePanel");
        }

        //攻击监听
        if (Input.GetKeyDown(KeyCode.Space) && CD_skill >= 1.0f) //按下空格键攻击,并且技能恢复冷却
        {

            if (curWeaponNum > 0)  //有武器时的技能相关
            {
                animator.speed = 2;
                animator.SetTrigger("Attack2");
            }
            else                  //没有武器时的技能相关
            {
                animator.speed = 1;
                animator.SetTrigger("Attack1");
            }

            CD_skill = 0;

            #region
            //技能开始冷却

            //    audioSource.clip = Resources.Load<AudioClip>("music/01");
            //    audioSource.Play();
            //    cd_Put = 0;
            //var enemys = GameObject.FindGameObjectsWithTag("enemy");
            //foreach (GameObject enemy in enemys)
            //{
            //    if (enemy != null)
            //    {
            //        if (Vector3.Distance(enemy.transform.position, this.transform.position) <= 5)
            //        {
            //            enemy.transform.GetComponent<_03EnemyCtrl>().SubSelf(50);
            //        }
            //    }
            //}
            //var bosses = GameObject.FindGameObjectsWithTag("boss");
            //foreach (GameObject boss in bosses)
            //{
            //    if (boss != null)
            //    {
            //        if (Vector3.Distance(boss.transform.position, this.transform.position) <= 5)
            //        {
            //            boss.transform.GetComponent<boss>().SubHP();
            //        }
            //    }
            //}
            #endregion
        }

        //if (Input.GetKeyDown(KeyCode.E))
        //{
        //    changeWeapon = !changeWeapon;
        //}
        //if (Input.GetKeyDown(KeyCode.Q))
        //{
        //    AddHP();
        //    diaPanel.USeHP();
        //}
        //if (enemys != null && enemys.transform.childCount <= 0 && key != null)
        //{
        //    key.gameObject.SetActive(true);
        //}


    }


    /// <summary>
    /// 发送事件
    /// </summary>
    private void SendEvent()
    {
        //传递玩家攻击事件
        EventCenter.GetInstance().AddEventListener(PureNotification.PLAYER_ATTRACK, () =>
        {
           
        });

        //传递玩家受伤事件(怪物攻击时)
        EventCenter.GetInstance().AddEventListener(PureNotification.PLAYER_INJURY , (int attack) =>
        {
            animator.SetBool("hurt", true);
           Debug.Log(attack + "掉血了");                                 
        });   
    }
}

(4) NPC的受伤特效添加


csharp 复制代码
    /// <summary>
    /// 碰撞检测
    /// </summary>
    /// <param name="collision"></param>
    private void OnCollisionStay(Collision collision)
    {
        //若碰到敌人,并进行攻击
        if (collision.gameObject.tag == "enemy" && Input.GetKeyDown(KeyCode.Space))
        {
            Debug.Log("造成伤害");
            enemyController = collision.gameObject.GetComponent<EnemyController>();
            //触发攻击事件
            enemyController.animator.SetBool("hurt", true);  //怪物受伤动画激活
            enemyController.transform.GetChild(2).GetChild(0).GetComponent<ParticleSystem>().Play();
            enemyController.hp -= attack;//减少血量
            enemyController. hpSlider.fillAmount = (enemyController.hp / 100.0f);
            if (enemyController.hp <= 0) //死亡判断
            {
                collision.transform.GetChild(0).GetComponent<Animator>() .SetBool("died", true);  //死亡动画激活
                                                                                                  //播放动画
                collision.transform.GetChild(2).GetChild(0).GetComponent<ParticleSystem>().Play();
                collision. gameObject.SetActive(false); //将敌人失活
                //暴钻石(实例化)
                Instantiate(Resources.Load<GameObject>("Perfab/Prop/damon"), collision.transform.position , Quaternion.identity);
                Destroy(collision.gameObject, 3);
            }
        }
    }

(5) NPC的死亡特效添加


csharp 复制代码
   /// <summary>
   /// 碰撞检测
   /// </summary>
   /// <param name="collision"></param>
   private void OnCollisionStay(Collision collision)
   {
       //若碰到敌人,并进行攻击
       if (collision.gameObject.tag == "enemy" && Input.GetKeyDown(KeyCode.Space))
       {
           Debug.Log("造成伤害");
           enemyController = collision.gameObject.GetComponent<EnemyController>();
           //触发攻击事件
           enemyController.animator.SetBool("hurt", true);  //怪物受伤动画激活
           enemyController.transform.GetChild(2).GetChild(0).GetComponent<ParticleSystem>().Play();
           enemyController.hp -= attack;//减少血量
           enemyController. hpSlider.fillAmount = (enemyController.hp / 100.0f);
           if (enemyController.hp <= 0) //死亡判断
           {
               collision.transform.GetChild(0).GetComponent<Animator>() .SetBool("died", true);  //死亡动画激活
                                                                                                 //播放动画
               collision.transform.GetChild(2).GetChild(0).GetComponent<ParticleSystem>().Play();
               collision. gameObject.SetActive(false); //将敌人失活
               //暴钻石(实例化)
               Instantiate(Resources.Load<GameObject>("Perfab/Prop/damon"), collision.transform.position , Quaternion.identity);
               Destroy(collision.gameObject, 3);
           }
       }
   }

⭐🅰️⭐


【Unityc#专题篇】之c#进阶篇】

【Unityc#专题篇】之c#核心篇】

【Unityc#专题篇】之c#基础篇】

【Unity-c#专题篇】之c#入门篇】

【Unityc#专题篇】---进阶章题单实践练习

【Unityc#专题篇】---基础章题单实践练习

【Unityc#专题篇】---核心章题单实践练习


你们的点赞👍 收藏⭐ 留言📝 关注✅是我持续创作,输出优质内容的最大动力!



相关推荐
虾球xz7 分钟前
游戏引擎学习第61天
java·学习·游戏引擎
Camllia3732 分钟前
《CS2》报错dxgi.dll缺失怎么办?《CS2》游戏提示dxgi.dll缺失要怎么解决?
游戏
葡萄架子1 小时前
用Python写炸金花游戏
windows·python·游戏
爱学习的小羊啊3 小时前
从零开始掌握Spring MVC:深入解析@Controller与@RequestMapping注解的使用
java·spring·mvc
两水先木示3 小时前
【Unity3D】Jobs、Burst并行计算裁剪Texture3D物体
unity·jobs·burst
la_vie_est_belle10 小时前
《Cocos Creator游戏实战》非固定摇杆实现原理
游戏·cocos creator·游戏开发·cocos·非固定摇杆
Thomas_YXQ10 小时前
Unity3D Huatuo技术原理剖析详解
unity·unity3d·游戏开发·性能调优·热更新
火云洞红孩儿12 小时前
基于AI IDE 打造快速化的游戏LUA脚本的生成系统
c++·人工智能·inscode·游戏引擎·lua·游戏开发·脚本系统
虾球xz13 小时前
游戏引擎学习第59天
学习·游戏引擎
zh路西法13 小时前
【C++决策和状态管理】从状态模式,有限状态机,行为树到决策树(二):从FSM开始的2D游戏角色操控底层源码编写
c++·游戏·unity·设计模式·状态模式