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


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



相关推荐
/**书香门第*/1 小时前
Cocos creator 3.8 支持的动画 7
学习·游戏·游戏引擎·游戏程序·cocos2d
九州ip动态4 小时前
做网络推广及游戏注册为什么要换IP
网络·tcp/ip·游戏
向宇it15 小时前
【unity小技巧】unity 什么是反射?反射的作用?反射的使用场景?反射的缺点?常用的反射操作?反射常见示例
开发语言·游戏·unity·c#·游戏引擎
Heaphaestus,RC17 小时前
【Unity3D】获取 GameObject 的完整层级结构
unity·c#
芋芋qwq17 小时前
Unity UI射线检测 道具拖拽
ui·unity·游戏引擎
tealcwu18 小时前
【Unity服务】关于Unity LevelPlay的基本情况
unity·游戏引擎
大眼睛姑娘20 小时前
Unity3d场景童话梦幻卡通Q版城镇建筑植物山石3D模型游戏美术素材
unity·游戏美术
九州ip动态1 天前
模拟器多开限制ip,如何设置单窗口单ip,每个窗口ip不同
tcp/ip·游戏·媒体
鹿野素材屋1 天前
Unity Dots下的动画合批工具:GPU ECS Animation Baker
unity·游戏引擎
St_Ludwig1 天前
C语言 蓝桥杯某例题解决方案(查找完数)
c语言·c++·后端·算法·游戏·蓝桥杯