本文由作者@zx一路飞奔出品,转载请注明出处
文章地址:http://blog.csdn.net/u014735301/article/details/43055923作者微博:http://weibo.com/u/1847349851
这几天编码下来,是时候写篇博客总结和分享下了,做出来的效果大致为:
方向键控制人物移动,靠近怪物时,按下攻击键,可以锁定怪物,进行攻击。也可以释放技能,
技能分为:单体锁定,无锁定,造成的伤害效果分为:单体伤害,群体伤害。
怪物受到人物的攻击,开始对人物进行攻击,人物远离时,进行追击,当之间的距离达到一定长度时,怪物的攻击目标消失
放上几张图看看效果吧
//人物状态 枚举
public enum ControlAnimationState {Idle,Move,WaitAttack,Attack,Cast,ActiveSkill,TakeAtk,Death};
//动画状态
public ControlAnimationState ctrlAnimState;
//人物状态
void HeroAnimationState() {
//静止
if(ctrlAnimState == ControlAnimationState.Idle)
{
animation.animationState = animation.Idle;
}
//行走
if(ctrlAnimState == ControlAnimationState.Move)
{
animation.animationState = animation.Move;
}
//攻击
if (ctrlAnimState == ControlAnimationState.Attack)
{
animation.animationState = animation.Attack;
}
//等待攻击
if (ctrlAnimState == ControlAnimationState.WaitAttack)
{
animation.animationState = animation.Idle;
WaitAttack();
}
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class AnimationController : MonoBehaviour {
public delegate void AnimationHandle();
public AnimationHandle animationState;
//动画类型1
[System.Serializable]
public class AnimationType01
{
public AnimationClip animation;
public float speedAnimation = 1.0f;
}
//动画类型2 可以控制动画播放速度
[System.Serializable]
public class AnimationType02
{
public AnimationClip animation;
public float speedAnimation = 1.0f;
public bool speedTuning;
}
//释放技能动画
[System.Serializable]
public class AnimationSkill
{
public PlayerSkillController.SkillType skillType;
public int skillIndex;
public AnimationClip animationSkill;
public float speedAnimation;
public float attackTimer;
public bool speedTuning;
}
public AnimationType01 idle,death; //静止,施法,死亡
public AnimationType02 move; //行走
public AnimationSkill skillSetup;//技能
private PlayerController playerController;
private PlayerSkillController playerSkill;
private PlayerStatus playerStatus;
public bool checkAttack; //检测攻击动画是否播放结束
public bool checkSkill;
// Use this for initialization
void Start () {
checkAttack = true;
checkSkill = true;
playerController = this.GetComponent();
playerStatus = this.GetComponent();
playerSkill = this.GetComponent();
}
// Update is called once per frame
void Update () {
if(animationState != null){
animationState();
}
}
//Idle Method
public void Idle(){
animation.CrossFade(idle.animation.name);
animation[idle.animation.name].speed = idle.speedAnimation;
}
//Move Method
public void Move(){
animation.Play(move.animation.name);
if(move.speedTuning) //可以变换速度
{
//与人物移动速度相关
animation[move.animation.name].speed = (playerStatus.status.movespd * 2) * move.speedAnimation;
}else
{
animation[move.animation.name].speed = move.speedAnimation;
}
}
//攻击(释放技能)
public void Attack()
{
//接受参数
ReceiveParam();
if (skillSetup.skillType==PlayerSkillController.SkillType.FreeTarget)
{
//playerSkill.UseSkill("Attack", skillSetup.skillIndex);
// checkSkill = false;
}
animation.Play(skillSetup.animationSkill.name);
if (skillSetup.speedTuning) //能进行速度控制
{
animation[skillSetup.animationSkill.name].speed = skillSetup.speedAnimation * (playerStatus.status.atkSpd * 2);
}else
{
animation[skillSetup.animationSkill.name].speed = skillSetup.speedAnimation;
}
//计算伤害,当动画播放时间超出攻击时间
if (animation[skillSetup.animationSkill.name].normalizedTime > skillSetup.attackTimer && animation[skillSetup.animationSkill.name].normalizedTime < 0.9f)
{
if (checkSkill)
{
playerSkill.UseSkill("Attack", skillSetup.skillIndex);
checkSkill = false;
}
}
//攻击动画播放结束
if(animation[skillSetup.animationSkill.name].normalizedTime > 0.9f)
{
playerController.ctrlAnimState = PlayerController.ControlAnimationState.WaitAttack;
playerController.onceAttack = false;
checkAttack = true;
checkSkill = true;
}
}
//死亡
public void Death()
{
animation.CrossFade(death.animation.name);
animation[death.animation.name].speed = death.speedAnimation;
}
//从playskill脚本接受参数
public void ReceiveParam() {
if (checkAttack)
{
//技能ID
skillSetup.skillIndex = playerSkill.FindSkillIndex(playerController.skillID);
//技能类型
skillSetup.skillType = playerSkill.activeSkillAttack[skillSetup.skillIndex].skillType;
//技能动画
skillSetup.animationSkill = playerSkill.activeSkillAttack[skillSetup.skillIndex].animationAttack;
//动画播放时间
skillSetup.speedAnimation = playerSkill.activeSkillAttack[skillSetup.skillIndex].speedAnimation;
//播放时间是否可控
skillSetup.speedTuning = playerSkill.activeSkillAttack[skillSetup.skillIndex].speedTuning;
//技能攻击时间
skillSetup.attackTimer = playerSkill.activeSkillAttack[skillSetup.skillIndex].attackTimer;
checkAttack = false;
}
}
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
/*
人物技能控制脚本
*/
public class PlayerSkillController : MonoBehaviour {
//技能类型:单体锁定,无锁定,
public enum SkillType {LockTarget,FreeTarget,Instance};
//伤害类型:单体伤害,群体伤害
public enum TargetSkill {SingleTarget,MultipleTarget};
//主动释放技能
[System.Serializable]
public class ActiveSkillAttack
{
public string skillName = "Skill Attack";//技能名称
public int skillID; //技能id
public int unlockLevel = 1;//解锁等级
public Texture2D skillIcon;//技能图标
public int mpUse;//mp消耗
public TargetSkill targetSkill = PlayerSkillController.TargetSkill.SingleTarget;//伤害类型
public SkillType skillType = PlayerSkillController.SkillType.LockTarget;//技能类型
public float skillRange;//技能范围
public AnimationClip animationAttack;//技能动画
public float speedAnimation = 1;//动画播放速度
public float CD = 0;//冷却时间
public float attackTimer = 0.5f;
public float percentDamage = 1;//伤害百分比
public float multipleDamage = 1;//伤害次数
[Multiline]
public string description = ""; //技能描述
public bool speedTuning;//动画播放速度是否可控
public GameObject skillFX;
public AudioClip soundFX;
}
public List activeSkillAttack = new List();
//在技能范围中的enemy
public List monsterInArea = new List();
//碰撞组
public Collider[] groupNearbyObject;
private int currentUseSkill;
private PlayerController controller;
private AnimationController animation;
// Use this for initialization
void Start () {
controller = this.GetComponent ();
animation = this.GetComponent();
}
// Update is called once per frame
void Update () {
}
public void UseSkill(string skillType,int indexSkill)
{
if (skillType=="Attack") {
//为锁定攻击
if (activeSkillAttack[indexSkill].skillType == SkillType.LockTarget)
{
//技能特效
if (activeSkillAttack[indexSkill].skillFX != null)
{
//在目标处生成技能特效
Instantiate(activeSkillAttack[indexSkill].skillFX, controller.target.gameObject.transform.position, Quaternion.identity);
}
//技能音效
if (activeSkillAttack[indexSkill].soundFX != null)
{
//在目标处生成技能音效
AudioSource.PlayClipAtPoint(activeSkillAttack[indexSkill].soundFX, controller.target.gameObject.transform.position);
}
//如果为锁定且单体攻击
if (activeSkillAttack[indexSkill].targetSkill == TargetSkill.SingleTarget)
{
EnemyController enemy;
enemy = controller.target.GetComponent();
enemy.GetDamage(activeSkillAttack[indexSkill].percentDamage*100, activeSkillAttack[indexSkill].multipleDamage);
}
//如果为锁定且群体攻击
if (activeSkillAttack[indexSkill].targetSkill == TargetSkill.MultipleTarget)
{
MakeDamage(activeSkillAttack[indexSkill].percentDamage * 100, activeSkillAttack[indexSkill].multipleDamage, activeSkillAttack[indexSkill].skillRange, controller.target.transform);
}
}
//为无锁定攻击
if (activeSkillAttack[indexSkill].skillType == SkillType.FreeTarget)
{
//技能特效
if (activeSkillAttack[indexSkill].skillFX != null)
{
//在目标处生成技能特效
Instantiate(activeSkillAttack[indexSkill].skillFX, transform.position, Quaternion.identity);
}
//技能音效
if (activeSkillAttack[indexSkill].soundFX != null)
{
//在目标处生成技能音效
AudioSource.PlayClipAtPoint(activeSkillAttack[indexSkill].soundFX, transform.position);
}
//为无锁定攻击(默认是群体伤害)
if (activeSkillAttack[indexSkill].skillType == SkillType.FreeTarget)
{
MakeDamage(activeSkillAttack[indexSkill].percentDamage * 100, activeSkillAttack[indexSkill].multipleDamage, activeSkillAttack[indexSkill].skillRange, this.transform);
}
}
}
}
//返回技能在列表中的下标
public int FindSkillIndex(int skillID)
{
for(int i=0;i 0)
{
//对列表中的enemy造成伤害
foreach (GameObject enemy in monsterInArea)
{
EnemyController enemyController;
enemyController = enemy.GetComponent();
enemyController.GetDamage(hit, multipleDamage);
}
}
}
}
代码可以参考 上面 MakeDamage()方法,通过在目标位置画出半径为radius的相交球,返回在这个球内的怪物,对其操作就行了
void Update () {
EnemyAnimationState();
Move();
}
public void Move() {
if (target != null)
{
this.transform.LookAt(target.transform.position);
destinationDistance = Vector3.Distance(target.transform.position, this.transform.position);
if (destinationDistance < 1.4f)
{
moveSpeed = 0;
WaitAttack();
}
if (destinationDistance > 1.4f && destinationDistance < 5f)
{
moveSpeed = 2f;
ctrlAnimState = ControlAnimationState.Move;
}
if (destinationDistance > 5f)
{
target = null;
moveSpeed = 0;
ctrlAnimState = ControlAnimationState.Idle;
}
}
//角色自身基础属性
[System.Serializable]
public class AttributeBase
{
public int lv, hp, mp, atk, def;//等级,血,蓝,攻击,防御
public float criticalRate, atkSpd,movespd, exp;//暴击率,攻速,移速,经验
}