问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Unity 3D RPG游戏的设计与实现

创作时间:
作者:
@小白创作中心

Unity 3D RPG游戏的设计与实现

引用
CSDN
1.
https://blog.csdn.net/brown_dd/article/details/136188863

本文将详细介绍Unity 3D RPG游戏中玩家与敌人交互、状态机设计、攻击动画实现以及攻击时滑动功能的代码实现。通过本文,你将了解如何在Unity中实现基本的玩家控制、状态切换、动画触发以及特效播放等核心功能。

实现鼠标点击的交互

public class PlayerInput : MonoBehaviour
{
    public float horizontalInput;
    public float verticalInput;
    public bool mouseDown;

    void Update()
    {
        if (!mouseDown && Time.timeScale != 0) // 游戏运行中,Time.timeScale等于0时,游戏时间会停止更新,此时不应该响应玩家输入
        {
            mouseDown = Input.GetMouseButtonDown(0);
        }
        horizontalInput = Input.GetAxis("Horizontal");
        verticalInput = Input.GetAxis("Vertical");
    }

    private void OnDisable()
    {
        mouseDown = false; // 清除鼠标输入
        horizontalInput = 0;
        verticalInput = 0;
    }
}

状态机的初步设计

private void StateSwitchTo(CharacterState newState)
{
    if (isPlayer)
    {
        playerInput.mouseDown = false; // 清除鼠标输入,因为Enemy是由ai控制的,所以不需要mouseDown
    }

    // 对于当前状态的处理
    switch (currentState)
    {
        case CharacterState.Normal:
            break;
        case CharacterState.Attacking:
            animator.SetTrigger("Attack");
            break;
    }

    // 对于新状态的处理
    switch (newState)
    {
        case CharacterState.Normal:
            break;
        case CharacterState.Attacking:
            animator.SetTrigger("Attack");
            if (isPlayer)
                attackStartTime = Time.time; // 记录角色攻击开始时间的时间点
            if (!isPlayer)
            {
                Quaternion newRotition = Quaternion.LookRotation(playerTarget.transform.position - transform.position); // 计算角色的朝向
                transform.rotation = newRotition;
            }
            break;
    }
    currentState = newState;
    Debug.Log("state changed to " + currentState);
}

normal与attacking的状态转换

private void CalculateMove()
{
    if (playerInput.mouseDown && cc.isGrounded)
    {
        StateSwitchTo(CharacterState.Attacking);
        return;
    }
}

void FixedUpdate()
{
    switch (currentState)
    {
        case CharacterState.Normal:
            if (isPlayer)
                CalculateMove();
            else
                CalculateEnemyMove();
            break;
        case CharacterState.Attacking:
            if (isPlayer)
            {
                moveVelocity = Vector3.zero; // 将移动速度归零,防止前一帧速度对滑动的干扰
                if (Time.time < attackStartTime + slideDuration)
                {
                    float passedTime = Time.time - attackStartTime;
                    float lerpTime = passedTime / slideDuration;
                    moveVelocity = Vector3.Lerp(transform.forward * slideSpeed, Vector3.zero, lerpTime);
                }
            }
            break;
    }
}

攻击状态的设计与实现

玩家攻击

玩家攻击动画的实现:

点击图示位置打开动画控制器:

代码实现:

private void StateSwitchTo(CharacterState newState)
{
    if (isPlayer)
    {
        playerInput.mouseDown = false; // 清除鼠标输入,因为Enemy是由ai控制的,所以不需要mouseDown
    }

    // 对于当前状态的处理
    switch (currentState)
    {
        case CharacterState.Normal:
            break;
        case CharacterState.Attacking:
            animator.SetTrigger("Attack");
            break;
    }

    // 对于新状态的处理
    switch (newState)
    {
        case CharacterState.Normal:
            break;
        case CharacterState.Attacking:
            animator.SetTrigger("Attack");
            if (isPlayer)
                attackStartTime = Time.time; // 记录角色攻击开始时间的时间点
            if (!isPlayer)
            {
                Quaternion newRotition = Quaternion.LookRotation(playerTarget.transform.position - transform.position); // 计算角色的朝向
                transform.rotation = newRotition;
            }
            break;
    }
    currentState = newState;
    Debug.Log("state changed to " + currentState);
}

public void AttackAnimationEnds()
{
    StateSwitchTo(CharacterState.Normal); // 攻击状态转换为常态
}

玩家攻击特效的实现:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.VFX;

public class PlayerVFXManager : MonoBehaviour
{
    public VisualEffect visualEffect;
    public ParticleSystem particleSystem;

    public void UpdateStep(bool state)
    {
        if (state)
        {
            visualEffect.Play(); // 播放VFX动画
        }
        else
        {
            visualEffect.Stop();
        }
    }

    public void PlayBlade01()
    {
        particleSystem.Play();
    }
}

敌人攻击

敌人攻击动画的实现:

打开敌人的动画控制器后将敌人的攻击动作设计完毕,后续与玩家的设计原理相同。

代码实现:

private void CalculateEnemyMove()
{
    if (Vector3.Distance(transform.position, playerTarget.position) > agent.stoppingDistance)
    {
        agent.SetDestination(playerTarget.position);
        animator.SetFloat("Speed", 0.2f);
    }
    else
    {
        agent.SetDestination(transform.position);
        animator.SetFloat("Speed", 0f);
        StateSwitchTo(CharacterState.Attacking); // 靠近玩家时切换为攻击状态
    }
}

敌人攻击特效的实现:

代码实现:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.VFX;

public class EnemyVFXManager : MonoBehaviour
{
    public VisualEffect visualEffect;
    public VisualEffect AttackVFX;

    public void PlayerAttackAnimation()
    {
        AttackVFX.Play();
    }

    public void BurstFootStep()
    {
        visualEffect.Play();
    }
}

实现攻击时滑动的功能

private float attackStartTime;
public float slideDuration = 0.5f;
public float slideSpeed = 0.4f;

switch (newState)
{
    case CharacterState.Normal:
        break;
    case CharacterState.Attacking:
        animator.SetTrigger("Attack");
        if (isPlayer)
        {
            attackStartTime = Time.time; // 记录角色攻击开始时间的时间点
            moveVelocity = Vector3.zero; // 将移动速度归零,防止前一帧速度对滑动的干扰
            if (Time.time < attackStartTime + slideDuration)
            {
                float passedTime = Time.time - attackStartTime;
                float lerpTime = passedTime / slideDuration;
                moveVelocity = Vector3.Lerp(transform.forward * slideSpeed, Vector3.zero, lerpTime);
            }
        }
        break;
}
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号