unity 3D RPG 项目学习笔记

敌人对象的添加以及相关动画与脚本实现

添加一个敌人

在hierachy中创建一个空对象enemy01,将npc01预制体作为enemy0的子对象并重名名为Visual。

删掉visual的animator(animator的动画播放器无法作用于父对象enemy01)

给enemy01添加相关组件

animator

图中的enemy01继承自player,找到之前创建的player动画控制器,右键-create-animator override controller,

图中controller将player拖拽过来,视为继承自player,将对应的动画状态如图设置(enemy没有airborne,设置为idel)

charactor contrroller

参数如图

nav mesh agent

参数如图:

该组件是为了实现enemy01的自动寻路,这里运用到了对地图的烘焙,windows-ai-navigation,

max slope设置为0,避免enemy上楼梯,点击bake。

脚本设置

enemy01与player共用一个脚本。

using System.Collections;

using System.Collections.Generic;

using Unity.VisualScripting;

using UnityEngine;

public class Character : MonoBehaviour

{

    private CharacterController cc;//角色进行移动,通常使用character controller组件,rigidbody通常用来实现物理交互

    public float speed = 10f;

    private Vector3 moveVelocity;

    private PlayerInput playerInput;

    private float verticalVelocity;

    private float Gravity=-9.8f;

    private Animator animator;

    public bool isPlayer=true;

    private UnityEngine.AI.NavMeshAgent navAgent;//引入ai组件

    private Transform targetPlayer;//记录玩家位置

   

   private void Awake() {

    cc=GetComponent<CharacterController>();

    animator=GetComponent<Animator>(); //组件获取

    if(!isPlayer){

         navAgent=GetComponent<UnityEngine.AI.NavMeshAgent>();

        targetPlayer=GameObject.Find("Player").transform;//获取目标玩家de位置

        navAgent.speed=speed;//设置移动速度

    }

       

        else

        {

              playerInput=GetComponent<PlayerInput>();

        }

   }

        private void CalculateEnemyMove(){

            if(Vector3.Distance(transform.position,targetPlayer.position)>navAgent.stoppingDistance)//计算当前角色(由transform.position表示其位置)与目标玩家(由targetPlayer.position表示其位置)之间的直线距离

            {

                navAgent.SetDestination(targetPlayer.position);//调用navAgent.SetDestination(targetPlayer.position)将角色的移动目的地设置为目标玩家的位置,使其继续朝向目标移动。

                animator.SetFloat("Speed",0.2f);

            }else{

                navAgent.SetDestination(transform.position);//执行navAgent.SetDestination(transform.position)将角色的移动目的地设置为当前角色的位置,这意味着角色将停止移动并保持在当前位置。

                animator.SetFloat("Speed",0f);

            }

        }

       private void CalculateMove(){

        moveVelocity.Set(playerInput.horizontalInput,0,playerInput.verticalInput);//获取输入的值并将其转化为三维向量

        moveVelocity.Normalize();//向量的归一化

        moveVelocity=Quaternion.Euler(0,-45,0)*moveVelocity;//实现对向量的旋转(与相机旋转角度相同)

        moveVelocity*=speed*Time.deltaTime;

        animator.SetFloat("Speed",moveVelocity.magnitude);//将物体当前的速度大小(即moveVelocity的模长)赋值给Animator控制器中的名为"Speed"的动画参数,moveVelocity.magnitue获取moveVelocity的模长

        //为了防止player持续转向,判断moveVelocity是否为零,若为零则不进行旋转

        if(moveVelocity!=Vector3.zero){

            transform.rotation=Quaternion.LookRotation(moveVelocity);

        }

        animator.SetBool("AirBorne",!cc.isGrounded);//调用animator的bool参数"AirBorne",若cc.isGrounded为false,即角色没有与地面接触,则将bool参数设置为true,否则为false

       

       }

       

   

   

       

       

   

   

    //这段代码的主要目的是在每一帧的固定更新阶段,先计算出对象应有的速度,然后基于此速度信息来实际移动游戏对象。

    void FixedUpdate(){

        if(isPlayer)

        CalculateMove();

        else

        CalculateEnemyMove();

        if(isPlayer){

             //如果对象没有与地面接触,那么它的速度为重力加速度,否则速度为重力加速度的0.3倍

        if(cc.isGrounded==false){

            verticalVelocity=Gravity;

        }

        else{

            verticalVelocity=Gravity*0.3f;//判断当角色在地面时,依旧施加力的原因是角色控制器的设计中,在角色仍在地面上时,下一帧角色仍会浮在地面上,isGrounded=false,所以需要在重力加速度上施加一个小的力

        }

           

            moveVelocity+=verticalVelocity*Vector3.up*Time.deltaTime;//将垂直方向的力与水平方向的力矢量相加,将verticalVelocity转化成三维向量

        }

       

        cc.Move(moveVelocity);   //移动游戏对象


 

    }

   

}

ps:isplayer默认为true,在unity中将enemy的isplayer设置为false

将player的标签设置为player

(出了一个bug,enemy动画可以正常播放,也会朝向player,但是无法移动,怀疑是bake的问题)

enemy的脚步特效设置

新建一个VFX空对象作为visual的子对象,将如图所示预制体作为VFX子对象

脚本设置

创建一个EnemyVFXmanager

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.VFX;

public class EnemyVFXManager : MonoBehaviour

{

 public VisualEffect visualEffect;

 public void BurstFootStep(){

   visualEffect.Play();

 }

   

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值