【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#专题篇】---核心章题单实践练习


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



相关推荐
njsgcs7 小时前
枪战游戏“棋盘化”价值建模 强化学习或rag
游戏
Sator17 小时前
Unity烘焙光打包后光照丢失问题
unity·光照贴图
Howrun77710 小时前
虚幻引擎_核心框架
游戏引擎·虚幻
前端不太难11 小时前
HarmonyOS 游戏里,主线程到底该干什么?
游戏·状态模式·harmonyos
秃头续命码农人12 小时前
谈谈对Spring、Spring MVC、SpringBoot、SpringCloud,Mybatis框架的理解
java·spring boot·spring·mvc·maven·mybatis
远程软件小助理12 小时前
电脑玩手游哪个模拟器启动速度最快?MuMu、雷电、应用宝对比实测
游戏
树码小子14 小时前
SpringMVC(2)传入请求参数
spring·mvc
树码小子14 小时前
SpringMVC(1)初识MVC
spring·mvc
GLDbalala14 小时前
Unity 实现一个简单的构建机
unity·游戏引擎
风景的人生1 天前
请求参数相关注解
spring·mvc