unity手游<少侠历险记>(2)人物攻击动画判定和怪物AI
2016-06-24 10:56
555 查看
本文由作者@zx一路飞奔出品,转载请注明出处
文章地址:http://blog.csdn.net/u014735301/article/details/43055923
作者微博:http://weibo.com/u/1847349851
这几天编码下来,是时候写篇博客总结和分享下了,做出来的效果大致为:
方向键控制人物移动,靠近怪物时,按下攻击键,可以锁定怪物,进行攻击。也可以释放技能,
技能分为:单体锁定,无锁定,造成的伤害效果分为:单体伤害,群体伤害。
怪物受到人物的攻击,开始对人物进行攻击,人物远离时,进行追击,当之间的距离达到一定长度时,怪物的攻击目标消失
放上几张图看看效果吧
![](http://img.blog.csdn.net/20150123151116374?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxNDczNTMwMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](http://img.blog.csdn.net/20150123151135468?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxNDczNTMwMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](http://img.blog.csdn.net/20150123151200990?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxNDczNTMwMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](http://img.blog.csdn.net/20150123151210475?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxNDczNTMwMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
在人物控制脚本中,使用了委托的方式,根据状态的不同来调用动画控制脚本中对应的方法
下面给出代码片段供参考
[csharp] view
plain copy
//人物状态 枚举
public enum ControlAnimationState {Idle,Move,WaitAttack,Attack,Cast,ActiveSkill,TakeAtk,Death};
//动画状态
public ControlAnimationState ctrlAnimState;
[csharp] view
plain copy
//人物状态
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();
}
}
下面把动画控制脚本代码全部给出
[csharp] view
plain copy
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<PlayerController>();
playerStatus = this.GetComponent<PlayerStatus>();
playerSkill = this.GetComponent<PlayerSkillController>();
}
// 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;
}
}
}
plain copy
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> activeSkillAttack = new List<ActiveSkillAttack>();
//在技能范围中的enemy
public List<GameObject> monsterInArea = new List<GameObject>();
//碰撞组
public Collider[] groupNearbyObject;
private int currentUseSkill;
private PlayerController controller;
private AnimationController animation;
// Use this for initialization
void Start () {
controller = this.GetComponent<PlayerController> ();
animation = this.GetComponent<AnimationController>();
}
// 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<EnemyController>();
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<activeSkillAttack.Count;i++)
{
if(skillID == activeSkillAttack[i].skillID)
{
currentUseSkill = i;
return currentUseSkill;
}
}
return 0;
}
//对技能范围内的enemy造成伤害
public void MakeDamage(float hit, float multipleDamage, float radius,Transform transform)
{
//清空列表
monsterInArea.Clear();
//返回球型半径之内(包括半径)的所有碰撞体 collider[]。
groupNearbyObject = Physics.OverlapSphere(transform.position, radius);
foreach (Collider groupObj in groupNearbyObject)
{
//其中是enemy的话 加入列表
if (groupObj.gameObject.tag == Tags.enemy)
monsterInArea.Add(groupObj.transform.gameObject);
}
if (monsterInArea.Count > 0)
{
//对列表中的enemy造成伤害
foreach (GameObject enemy in monsterInArea)
{
EnemyController enemyController;
enemyController = enemy.GetComponent<EnemyController>();
enemyController.GetDamage(hit, multipleDamage);
}
}
}
}
这里我把普通攻击也算作一种技能。大概的攻击流程就是这样
![](http://img.blog.csdn.net/20150123153554742?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxNDczNTMwMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
代码可以参考 上面 MakeDamage()方法,通过在目标位置画出半径为radius的相交球,返回在这个球内的怪物,对其操作就行了
[csharp] view
plain copy
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;
}
}
[csharp] view
plain copy
//角色自身基础属性
[System.Serializable]
public class AttributeBase
{
public int lv, hp, mp, atk, def;//等级,血,蓝,攻击,防御
public float criticalRate, atkSpd,movespd, exp;//暴击率,攻速,移速,经验
}
其次是研究NGUI HUD插件,让 player和怪物之间攻击造成的伤害不仅仅局限在控制台内,让血条,和伤害数字显示在屏幕上,更直观的呈现!
文章地址:http://blog.csdn.net/u014735301/article/details/43055923
作者微博:http://weibo.com/u/1847349851
这几天编码下来,是时候写篇博客总结和分享下了,做出来的效果大致为:
方向键控制人物移动,靠近怪物时,按下攻击键,可以锁定怪物,进行攻击。也可以释放技能,
技能分为:单体锁定,无锁定,造成的伤害效果分为:单体伤害,群体伤害。
怪物受到人物的攻击,开始对人物进行攻击,人物远离时,进行追击,当之间的距离达到一定长度时,怪物的攻击目标消失
放上几张图看看效果吧
动画控制
这里的动画控制,并没有使用unity自身的动画状态机,而是通过脚本写一个状态类,通过对状态的判断,播放对应的动画片段在人物控制脚本中,使用了委托的方式,根据状态的不同来调用动画控制脚本中对应的方法
下面给出代码片段供参考
[csharp] view
plain copy
//人物状态 枚举
public enum ControlAnimationState {Idle,Move,WaitAttack,Attack,Cast,ActiveSkill,TakeAtk,Death};
//动画状态
public ControlAnimationState ctrlAnimState;
[csharp] view
plain copy
//人物状态
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();
}
}
下面把动画控制脚本代码全部给出
[csharp] view
plain copy
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<PlayerController>();
playerStatus = this.GetComponent<PlayerStatus>();
playerSkill = this.GetComponent<PlayerSkillController>();
}
// 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;
}
}
}
技能控制
[csharp] viewplain copy
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> activeSkillAttack = new List<ActiveSkillAttack>();
//在技能范围中的enemy
public List<GameObject> monsterInArea = new List<GameObject>();
//碰撞组
public Collider[] groupNearbyObject;
private int currentUseSkill;
private PlayerController controller;
private AnimationController animation;
// Use this for initialization
void Start () {
controller = this.GetComponent<PlayerController> ();
animation = this.GetComponent<AnimationController>();
}
// 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<EnemyController>();
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<activeSkillAttack.Count;i++)
{
if(skillID == activeSkillAttack[i].skillID)
{
currentUseSkill = i;
return currentUseSkill;
}
}
return 0;
}
//对技能范围内的enemy造成伤害
public void MakeDamage(float hit, float multipleDamage, float radius,Transform transform)
{
//清空列表
monsterInArea.Clear();
//返回球型半径之内(包括半径)的所有碰撞体 collider[]。
groupNearbyObject = Physics.OverlapSphere(transform.position, radius);
foreach (Collider groupObj in groupNearbyObject)
{
//其中是enemy的话 加入列表
if (groupObj.gameObject.tag == Tags.enemy)
monsterInArea.Add(groupObj.transform.gameObject);
}
if (monsterInArea.Count > 0)
{
//对列表中的enemy造成伤害
foreach (GameObject enemy in monsterInArea)
{
EnemyController enemyController;
enemyController = enemy.GetComponent<EnemyController>();
enemyController.GetDamage(hit, multipleDamage);
}
}
}
}
这里我把普通攻击也算作一种技能。大概的攻击流程就是这样
技能范围确定
在释放技能时,如何选定技能攻击范围,让在这个范围内的敌人都受到伤害,要用到Physics.OverlapSphere(transform.position, radius);代码可以参考 上面 MakeDamage()方法,通过在目标位置画出半径为radius的相交球,返回在这个球内的怪物,对其操作就行了
怪物AI
谈AI,其实真算不上,就是通过对怪物和player之间距离的控制来对怪物target操作[csharp] view
plain copy
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;
}
}
总结
目前大致做了这么多东西,后续的计划是加上一个属性脚本,控制人物和 怪物的基本属性,由于是学习用,不太复杂,通过属性脚来计算人物造成的伤害等[csharp] view
plain copy
//角色自身基础属性
[System.Serializable]
public class AttributeBase
{
public int lv, hp, mp, atk, def;//等级,血,蓝,攻击,防御
public float criticalRate, atkSpd,movespd, exp;//暴击率,攻速,移速,经验
}
其次是研究NGUI HUD插件,让 player和怪物之间攻击造成的伤害不仅仅局限在控制台内,让血条,和伤害数字显示在屏幕上,更直观的呈现!
相关文章推荐
- unity商店demo学习:跑酷游戏
- Unity连接MySQL数据库
- 序列化 文件 Serialize
- unity调用Android剪切板基于Android studio
- unity学习之NGUI做NPC对话
- unity 文件、图片加载与保存
- Unity3d 各种反编译比较
- unity制作斗地主游戏大致流程
- Unity3D鼠标选中物品并拖动物品的方法
- unity3d异步加载场景
- unity导入模型后贴图丢失
- Unity与注册登录服务器交互原理及code
- 【unityshader】径向模糊
- unity3d 碰撞器和触发器的区别
- unity通过android adb查看真机日志
- 如何将Unity中的脚本文件转为dll文件
- Unity3d坐标与NGUI坐标转换
- unity引用dll文件方法
- unity3d屏蔽Windows10输入法
- 【Unity3D实战】零基础一步一步教你制作酷跑类游戏(1)