UnityRPG系列笔记----3
2016-07-05 15:38
585 查看
敌人的AI----1
上次两次博客把主角的移动写完了,这次根据作者的顺序会开始做敌人,需要资源的可以到作者本人的百度贴吧里面下载,由于版权问题,我这里就不提供下载了。AI一直是一个游戏的灵魂,先把简单的做好以后,之后我会好好研究一下ai的一些算法。创建一个一个Enemy脚本
using UnityEngine; using System.Collections; ///Author:CWH ///email:cwhisme@qq.com ///date:2014.1.17 public class Enemy : MonoBehaviour { #region 属性 public string m_name;//名字 public int m_level;//等级,以判断角色应当获取的经验 public int m_maxLife;//生命 public int m_currentLife;//当前生命 public int m_defense;//防御力 public int m_attack;//攻击力 public float m_speed;//速度 public int m_rotateSpeed;//旋转速度 public float m_attackRadius;//攻击半径 #endregion #region 对象 public Transform m_transform;//自己 protected Animation m_animation;//动画组件 public Transform m_attackTarget;//攻击对象 public BattleChange m_damageTarget;//伤害对象 private BattleChange m_changeState;//战斗时改变生命等属性脚本对象 protected Rigidbody m_rigidbody; #endregion #region 判断 public bool m_isBoss=false; protected bool m_isIdle=true; protected bool m_isDead=false; #endregion #region 变量 protected int m_idleStat;//定义空闲状态动画的随机值 protected float m_idleTime=0;//每一个空闲状态持续时间 ///声音 public AudioClip m_sound; public AudioClip m_attackSound; public AudioClip m_skillSound; protected Vector3 m_forward;//敌人的前方向 protected RaycastHit m_hit;//射线碰撞 protected float m_attackDistance=8;//会攻击的视线距离 protected LayerMask m_layerMask; protected float m_distanceToOther;//与攻击对象的距离 public Transform m_attackParticle;//普通攻击粒子效果 public Transform m_skillParticle;//技能攻击粒子效果 protected float m_attackDelay=2;//攻击延时 protected float m_skillRandom;//随机出现技能 #endregion #region 动画状态 protected string m_animationIdle="idle1"; protected string m_animationIdle2="idle2"; protected string m_animationIdle3="idle3"; protected string m_animationWalk="walk"; protected string m_animationAttack="attack"; protected string m_animationSkill="skill"; protected string m_animationDeath="death"; #endregion void Start () { ///加刚体设置 //m_rigidbody = (Rigidbody)m_transform.gameObject.AddComponent("Rigidbody"); ///m_rigidbody.freezeRotation = true; Init(); m_transform=this.transform;//获取自己对象 m_animation=GetComponent<Animation>(); m_layerMask=1<<LayerMask.NameToLayer("Human"); //m_layerMask=LayerMask.NameToLayer("Human"); m_changeState=GetComponent<BattleChange>(); m_changeState.m_defense=m_defense; m_changeState.m_life=m_currentLife; } protected void SetAttribute(string name,int level,int Life,int defense,int attack,int speed,int rotatteSpeed,float attackRadius) { m_name=name; m_level=level; m_maxLife=Life; m_currentLife=Life; m_defense=defense; m_attack=attack; m_speed=speed; m_rotateSpeed=rotatteSpeed; m_attackRadius=attackRadius; } protected virtual void Init() { } void Update () { if(m_isIdle) { m_idleTime-=Time.deltaTime; if(m_idleTime<0)///空闲随机时间到了就随机做出新动作 { m_idleStat=Random.Range(0,11); audio.clip=m_sound; audio.Play(); m_idleTime=3; } }else if(m_isDead){ //Debug.Log("is Dead"); }else{ RotateTo(); Attack(); } switch(m_idleStat) { case 1:m_animation.CrossFade(m_animationIdle); audio.clip=m_sound; audio.Play(); break; case 2:m_animation.CrossFade(m_animationIdle); m_transform.Rotate(0,m_rotateSpeed*Time.deltaTime,0); break; case 3:m_animation.CrossFade(m_animationIdle2); break; case 4:m_animation.CrossFade(m_animationIdle2); break; case 5:m_animation.CrossFade(m_animationWalk); m_transform.Rotate(0,m_rotateSpeed*Time.deltaTime,0); break; case 6:m_animation.CrossFade(m_animationWalk); m_transform.Rotate(0,m_rotateSpeed*Time.deltaTime,0); break; case 7:m_animation.CrossFade(m_animationWalk); m_transform.Rotate(0,m_rotateSpeed*Time.deltaTime,0); break; case 8:m_animation.CrossFade(m_animationWalk); m_transform.Translate(Vector3.forward*m_speed*Time.deltaTime); break; default:m_animation.CrossFade(m_animationIdle3); m_transform.Translate(Vector3.forward*m_speed*Time.deltaTime); break; } m_forward = m_transform.TransformDirection(Vector3.forward); if (Physics.Raycast(m_transform.position + Vector3.up, m_forward, out m_hit, m_attackDistance, m_layerMask)) { m_attackTarget=m_hit.collider.gameObject.transform;//如果看见任何人类对象,就获取其位置,并将Idle状态置为false if(m_attackTarget.GetComponent<BattleChange>().m_life!=0) { m_isIdle=false; } } GetState(); } protected void RotateTo() { Vector3 m_oldAngle=m_transform.eulerAngles;//当前旋转角度 m_transform.LookAt(m_attackTarget.position);//盯着攻击对象 float m_target=m_transform.eulerAngles.y;//目标角度吧 float m_targetAngle=Mathf.MoveTowardsAngle(m_oldAngle.y,m_target,m_rotateSpeed*Time.deltaTime);//计算应转动的角度 m_transform.eulerAngles=new Vector3(0,m_targetAngle,0);//转动角度 } protected void Attack() { m_distanceToOther=Vector3.Distance(m_transform.position,m_attackTarget.position); m_attackDelay-=Time.deltaTime; if(m_distanceToOther<m_attackRadius)///目标进入攻击半径,攻击 { if(m_attackDelay<0) { m_forward=m_transform.TransformDirection(Vector3.forward); /// if(Physics.Raycast(m_transform.position+Vector3.up,m_forward,out m_hit,m_attackRadius,m_layerMask)) /// { /// m_animation.CrossFade(m_animationAttack); /// Instantiate(m_attackParticle,m_hit.collider.gameObject.transform.position+Vector3.up,Quaternion.identity);//攻击,实例化一个粒子 /// m_attackDelay=2;//攻击成功,重置延时 /// } if(Physics.Raycast(m_transform.position+Vector3.up,m_forward,out m_hit,m_attackRadius,m_layerMask)) { m_skillRandom=Random.value; if(m_skillRandom<0.96f)///大概有4%的几率发出技能 { m_animation.CrossFade(m_animationAttack); m_damageTarget=m_hit.collider.gameObject.GetComponent<BattleChange>(); StartCoroutine(WaitForAttack(0.6f,m_attackParticle,m_attackSound,m_attack)); if(m_damageTarget.m_isDead)///如果攻击目标死掉了的话,就回到Idle状态吧 { m_isIdle=true; } if(m_currentLife==0){ m_isDead=true; } }else { m_animation.CrossFade(m_animationSkill); m_damageTarget=m_hit.collider.gameObject.GetComponent<BattleChange>(); StartCoroutine(WaitForAttack(0.6f,m_attackParticle,m_attackSound,m_attack*3)); if(m_damageTarget.m_isDead)///如果攻击目标死掉了的话,就回到Idle状态吧 { m_isIdle=true; } if(m_currentLife==0){ m_isDead=true; } } m_attackDelay=2; } } }else if(m_distanceToOther<20)///如果距离小于20,对目标进行追击 { m_animation.CrossFade(m_animationWalk); m_transform.Translate(Vector3.forward*m_speed*Time.deltaTime); }else if(m_distanceToOther<90)/// 如果距离大于20,就回到Idle状态,不追目标了 { m_isIdle=true; }else///超过九十米的话,为了省点资源,就把这个敌人销毁罢 { Destroy(this.gameObject); } } void GetState() { m_currentLife=m_changeState.m_life; } IEnumerator WaitForAttack(float timer,Transform particle,AudioClip m_audio,int attack) { yield return new WaitForSeconds(timer); Instantiate(particle ,m_damageTarget.transform.position+Vector3.up,Quaternion.identity); audio.PlayOneShot(m_audio);//播放声音 m_damageTarget.Damage(attack);//调用对象的伤害函数 if(m_damageTarget.m_isDead)///如果攻击目标死掉了的话,就回到Idle状态吧 { m_isIdle=true; } } }
一开始代码可能比较多,所以尽量贴出代码,但是要照着做就比较麻烦了,敌人的内容会在下一节继续说下去,有看过的朋友或者做这有疑问的朋友可以留言大家一起交流
相关文章推荐
- Uniyt热更新——LuaFrameWork学习(三)判断unity里对象为空
- android WIFI to unity
- unity htcvive sdk 按键
- 在Unity中避免某个对象的剔除Culling
- [UnityShader3]光之翼效果
- unity shader在小米2s上的问题
- 待机切换场景
- DrawCall优化
- [Unity3D]图形渲染优化、渲染管线优化、图形性能优化
- 减少Draw Call的方法
- Unity3D优化之Draw Call Batching
- Unity3D性能优化
- Draw Call Batching介绍
- DrawCall的介绍
- Unity中读取安卓相册选择图片的方法
- Unity 中子弹弓箭射击脚本
- Unity 三点生成一段贝塞尔曲线脚本
- unity抛物线路径模拟TrajectorySimulation
- Unity3D框架插件uFrame实践记录(二)
- unity 改变纹理像素点的颜色