Hit And Run Practice
Introduction
在RPG游戏中,控制角色对敌方单位进行攻击这样的战斗系统几乎是必备的,而在战斗系统中,根据玩家的输入进行角色的自动寻路则也是系统的基础功能。这个DEMO主要介绍了一个简单战斗表现的实现和利用NavMesh进行自动寻路。
Battle System
战斗系统的实现思路步骤如下:
- 在Unity3D中导入一个人物模型,并创建一个可供人物活动的Terrain
- 调整摄像机至正确的视角(可以始终处于人物背后也可以45度俯角跟随)
- 创建攻击动画与伤害显示
- 创建血条
- 逻辑脚本编写(包括攻击方向与距离求解,攻击物体判定)
- 运行测试
其中,对于具体的攻击在每一帧中的实现逻辑思路如下(攻击动作由鼠标与攻击按键共同完成,鼠标位置代表攻击方向,按键则给出攻击指令):
- 获取鼠标位置Input.MousePosition
- 由当前鼠标位置与角色位置求出攻击方向向量并归一化
- 由角色位置向攻击方向向量做出一条长度为攻击距离的线段,求解与线段相交的物体集合
- 遍历物体集合,对其中的可攻击对象执行HITed方法
- 播放角色攻击动画,如攻击方向与角色朝向不一致则先进行角色转身
虽然上述思路可以实现简单的攻击判定,但是在计算与线段相交的物体集合时会出现一定误差,并且由于攻击动画的存在,使得攻击效果的出现无法固定在动画播放的具体一帧中。
改进后的攻击判定
- 编辑攻击动画,在武器挥舞到具体位置的那一帧中加入回调事件
- 在回调函数中求解当前武器攻击范围内的所有敌方单位,也可以在武器模型的需要位置上(如剑锋)附上一个空对象用于求解
- 执行被影响敌方单位的HITed方法
当然也可以用之前的空对象的碰撞触发回调来求解被攻击的敌方单位
角色控制脚本主要Code如下:
using UnityEngine;
using UnityEngine.AI;
using System;
using System.Collections;
using System.Collections.Generic;
#pragma warning disable
public class ASCLBasicController : MonoBehaviour
{
Animator animator;
public Collider floorPlane;//in this demonstration this is set manually, the Retail Ability system has methods for dealing with this automatically via data structures for environments
public Collider attackPlane;
public Enemy[] enemies;//this array is filled during START by searching for prefabs that have the enemy script attached to them
public Transform hitReport;//this is for a text mesh object that tells us what damage we did...we need to know where this instance is so we can instantiate off of it
public Transform particleHit;//this is for a particle emmiter that shows us a hit...we need to know where this instance is so we can instantiate off of it
//the retail ability system will have this "Inside" an abilities class structual data
public List<Ability> abilities = new List<Ability>();//not really actual abilities as yet, HERE they are only attacks...the retail Ability System package will have actual ones
int ahc=1; //ability hit counter, combo attacks have more than one hit, this variable keeps track of how many hits we have used in update
public bool hitCheck;//<<< IMPORTANT mecanim tells us to perform a hit check at a specific point in attack animations by settting this to TRUE
public int WeaponState=0;//unarmed, 1H, 2H, bow, dual, pistol, rifle, spear and ss(sword and shield)
public bool wasAttacking;// we need this so we can take lock the direction we are facing during attacks, mecanim sometimes moves past the target which would flip the character around wildly
public Renderer movementTarget;
Transform destFloor;
float rotateSpeed = 20.0f; //used to smooth out turning
public Vector3 attackPos;
public Vector3 lookAtPos;
float gravity = -0.3f;//unused in this demonstration
float fallspeed = 0.0f;
NavMeshAgent mr;
bool isArrived;
public bool rightButtonDown=false;//we use this to "skip out" of consecutive right mouse down input...
// Use this for initialization
void Start ()
{
animator = GetComponentInChildren<Animator>();//need this...
movementTarget.transform.position = transform.position;//initializing our movement target as our current position
movementTarget.enabled = true;
lookAtPos = transform.position+transform.forward;