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;
}
热门推荐
领导力:保持良好人际关系的重要性与技巧
乔布斯创业传奇:有志者事竟成
一文掌握西班牙自驾游:行程安排与驾驶规则详解
治疗骨质疏松,骨松宝丸这样服用最安全有效
专家共识:低剂量CT筛查助力肺结节早诊,降低肺癌死亡率
竹笋:竹林清味,文人雅食
108岁张春台的养生秘诀:规律生活与乐观心态
冬季润肺止咳有妙方:虫草花无花果汤制作详解
从内在动机到用户导向:心理学理论提升企业目标管理效能
国防科技大学:科技创新与军事教育改革双轮驱动,助力国防现代化
涠洲岛潜水攻略:蓝洞挑战性高,火山口生物多样
在“秦岭小慢慢”图书角,让孩子爱上阅读
地奈德乳膏治疗皮肤病,医生提醒这些禁忌和注意事项
冬季新生儿护理四大误区,这些错误千万别犯
小李和小张:在爱情中实现财务独立
备考心理调节:这些方法让你轻松上阵
饮食管理是关键,四方面做好肝硬化腹水护理
十日均线金叉五日线,股民狂喜!
紫微斗数职业指南:财帛宫官禄宫详解28星曜
交强险新规:安全驾驶最高可省30%保费
企干事教你预防企业合同纠纷
上海大师赛上演跨界对决:樊振东发ACE球挑战费德勒
科技助力“活化石”重生:华东师大成功实现中华鲟人工繁殖
锦襕袈裟:古代丝绸工艺的巅峰之作
生猪期货成交量增22%,大企业积极参与风险管理
专家详解:如何正确理解与管理情绪,从认知到调节的全方位指南
新员工培训实用指南:15个技巧助你快速融入团队
坚持打乒乓球:身体、心理、社交全方位获益
个人车辆保养指南:从清洁到定期检查的实用建议
气垫BB霜用多了会堵塞毛孔,这样做才安全