9月19日
第二天,第一次体验这种带一个小团队的感觉,各种大小不一的错误,,好多东西都是需要去想去提前做准备的,感觉这次团队做东西真的是一次很好的体验,虽然没有真正体验过公司中的开发是什么样子,但是也知道了,在写代码的时候是需要去考虑别人调用的,不可以只是想着自己,和以前自己闷头写代码的感觉完全不一样。不过却很享受这种每天忙碌,每天写代码的感觉。哎。。这完全跑题了。。下面来正题吧!
按照之前的想法,我想把一些公用的需要去调用的属性都写在一个公共脚本里,
#region 角色属性
public static int hero_Hp=100; //角色血量
public static int hero_NowHp=100;//当前血量
public static int hero_Mp = 20;//角色蓝条
public static int hero_NowMp = 20;//角色当前蓝条
public static float hero_Speed = 1f;//角色速度
public static float hero_Attck = 2f;//攻击力
public static float hero_Def = 1f;//防御力
public static int hero_Max_Exp = 10;//升级所需经验
public static int hero_Exp = 0;//当前经验
public static float hero_Attck_Interval = 1f;//角色攻击间隔
public static float hero_Attck_Distance = 2f;//角色近身攻击距离
public static float hero_Skills_Distance = 5f;//角色技能攻击距离
public static bool hero_IsDead = false;//角色是否死亡
#endregion
这个是人物属性设为静态的这样在其他的脚本中可以直接调用了。不太清楚这样写是否对,(一直都听说rpg是要有全局脚本啊,还有一些其他的,也没见过什么rpg的项目,所以就先按照自己的想法来写吧)
本来这里还打算写怪物的属性。后来发现多个怪物的时候这个脚本的属性就会被各种覆盖,就变成所有怪物的属性值都一样了。就没有写
在这里我主要是写怪物脚本来的,所以就先放上怪物脚本吧。至于角色脚本,等我看看队友写完的脚本后理解了我在放上来哈,,应该不会太久的。
先说下我的怪物需求吧。怪物闲置的时候要会随机做一些发呆之类的闲置动画,也会有一定的走路移动动画,怪物有一个自己领地的范围值如果玩家进入这个范围的话就会向玩家跑来达到规定的距离值就攻击玩家,当怪物死亡的时候会播放死亡动画。并且规定时间到了就会销毁自身。下面来看代码吧
#region 属性
public string enemy_Name = "";//怪物名字
public int enemy_Level;//怪物等级
public int enemy_Hp;//怪物血量
public int enemy_NowHp;//怪物当前血量
public float enemy_Speed;//怪物速度
public float enemy_Rotate;//怪物旋转速度
public float enemy_Attck;//攻击力
public float enemy_Def;//怪物防御力
public float enemy_Distance;//怪物自身领地范围
public float enemy_Attck_Interval;//怪物攻击间隔
public float enemy_Attck_Distance;//怪物近身攻击距离
public float enemy_Skills_Distance;//怪物远程攻击距离
public bool isDead=false;//判断是否死亡
public int idleStart = 0;//是否闲置状态
public float idle_Time = -1;//调用动画时间
public bool is_Idle = false;//是否是空闲状态
//防止已经到角色附近后还是走路的动画
public bool enemy_walk = false;
#endregion
#region 对象
public Animation m_animation;//动画
public Transform m_transform;
public GameObject m_player;//获取要追踪的对象
#endregion
#region 动画
//数组中前面4个是闲置的时候放的动画,之后按顺序,跑,攻击,死亡,攻击,发呆
private string[] enemy_Animation = { };
#endregion
这里说下,本来我是打算直接按照每个名字定义一个string类型的变量,但是发现找到的模型里面的每个模型的动画的名字都不一样,这样如果还用这个方式要么重写的时候每个名字改,要么就是修改动画的名字,最后我就打算用数组来写,这样会省一些工作量,大家如果动画名称一样的就直接用string类型定义就好了。
/// <summary>
/// 名字,等级,血量,防御,攻击力,移动速度,怪物旋转速度,攻击间距,普通攻击距离,技能攻击距离,动画
/// </summary>
/// <param name="name"></param>
/// <param name="level"></param>
/// <param name="hp"></param>
/// <param name="defens"></param>
/// <param name="attck"></param>
/// <param name="speed"></param>
/// <param name="Interval"></param>
/// <param name="Attck_Distance"></param>
/// <param name="Skills_Distance"></param>
/// <param name="m_ani"></param>
protected void SetAttribute(string name, int level, int hp, int defens, float attck, float speed, float rotate, float Interval, float Attck_Distance, float Skills_Distance, float m_Distance, string[] m_ani)
{
enemy_Name = name;
enemy_Level = level;
enemy_Hp = hp;
enemy_Def = defens;
enemy_Attck = attck;
enemy_Speed = speed;
enemy_Rotate = rotate;
enemy_Attck_Interval = Interval;
enemy_Attck_Distance = Attck_Distance;
enemy_Skills_Distance = Skills_Distance;
enemy_Distance = m_Distance;
enemy_Animation = m_ani;
}
protected virtual void Iint() {
}
下面的是我定义的一个虚方法,上面的方法是为了让虚方法被重写的时候可以修改怪物的各种属性,好生成不同攻击,等级之类的怪物的。
void Start () {
m_transform = this.transform;
m_player = GameObject.FindWithTag("Player");//通过标签获取玩家
m_animation = GetComponent<Animation>();
Iint();
因为我这里只有一个玩家就这么获取了。虚方法要在start中调用一次。。。要是不调用这个方法就白瞎了,,不实现效果了,
void Move()
{
Debug.Log(Vector3.Distance(m_transform.position, m_player.transform.position));
//判断自己是否死亡
if (!isDead)
{ //判断怪物和玩家的距离,要是在范围内就过去攻击玩家
if (!GameVaule.hero_IsDead)
{
if (Vector3.Distance(m_transform.position, m_player.transform.position) < enemy_Distance)
{
is_Idle = false;
}
else
{
is_Idle = true;
}
if (is_Idle)
{//如果处于空闲状态
//防止闲置时候一直播放动画的前几帧,当闲置时间过去3秒后随即分配动画的值
idle_Time -= Time.deltaTime;
if (idle_Time < 0)
{
idleStart = Random.Range(1, 8);
idle_Time = 3;
}
//角色闲置时候播放的动画
switch (idleStart)
{
case 1:
m_animation.CrossFade(enemy_Animation[0]);
break;
case 2:
m_animation.CrossFade(enemy_Animation[1]);
break;
case 3:
m_animation.CrossFade(enemy_Animation[2]);
break;
case 4:
m_animation.CrossFade(enemy_Animation[3]);
break;
case 5:
m_animation.CrossFade(enemy_Animation[4]);
transform.Translate(Vector3.forward * Time.deltaTime * enemy_Speed);
break;
case 6:
m_animation.CrossFade(enemy_Animation[4]);
m_transform.Rotate(0, enemy_Rotate * Time.deltaTime, 0);
transform.Translate(Vector3.forward * enemy_Speed * Time.deltaTime);
break;
case 7:
m_animation.CrossFade(enemy_Animation[4]);
m_transform.Rotate(0, -enemy_Rotate * Time.deltaTime, 0);
transform.Translate(Vector3.forward * enemy_Speed * Time.deltaTime);
break;
default:
m_animation.CrossFade(enemy_Animation[2]);
break;
}
}
else
{
Attack();
}
}
}
else
{
//玩家闲置时候播放的动画
switch (idleStart)
{
case 1:
m_animation.CrossFade(enemy_Animation[0]);
break;
case 2:
m_animation.CrossFade(enemy_Animation[1]);
break;
case 3:
m_animation.CrossFade(enemy_Animation[2]);
break;
case 4:
m_animation.CrossFade(enemy_Animation[3]);
break;
case 5:
m_animation.CrossFade(enemy_Animation[4]);
transform.Translate(Vector3.forward * Time.deltaTime * enemy_Speed);
break;
case 6:
m_animation.CrossFade(enemy_Animation[4]);
m_transform.Rotate(0, enemy_Rotate * Time.deltaTime, 0);
transform.Translate(Vector3.forward * enemy_Speed * Time.deltaTime);
break;
case 7:
m_animation.CrossFade(enemy_Animation[4]);
m_transform.Rotate(0, -enemy_Rotate * Time.deltaTime, 0);
transform.Translate(Vector3.forward * enemy_Speed * Time.deltaTime);
break;
default:
m_animation.CrossFade(enemy_Animation[2]);
break;
}
}
}
这里是我做的一个怪物ai的功能,其实看看感觉很简单的,没什么东西,,现在因为时间比较劲,就先正常能实现功能就好,后面有时间会优化的,会添加怪物不会走出规定的范围的,
代码中
Vector3.Distance(m_transform.position, m_player.transform.position)
这个是获取本身到玩家的距离,我是通过这个来判断玩家是否会进入怪物设定的范围值,
void Attack() {
//四元数,平滑插值 获取怪物的旋转 之后是目标位置减去本身的位置,也就是一个角度吧。最后是向目标转头的速度
m_transform.rotation = Quaternion.Slerp(m_transform.rotation, Quaternion.LookRotation(m_player.transform.position - m_transform.position), enemy_Rotate * Time.deltaTime);
if (Vector3.Distance(m_transform.position, m_player.transform.position) > 3)
{
//播放行走的动画
m_animation.CrossFade(enemy_Animation[4]);
//怪物转向玩家方向
m_transform.LookAt(m_player.transform.position);
//怪物移动到角色位置
m_transform.Translate(Vector3.forward * enemy_Speed * Time.deltaTime);
}
else {
enemy_Attck_Interval -= Time.deltaTime;
if (enemy_Attck_Interval <= 0) {
//攻击方式的随机数
int attck_Range;
attck_Range = Random.Range(0,2);
switch(attck_Range){
case 0:
m_animation.CrossFade(enemy_Animation[5]);
enemy_Attck_Interval = 2;
break;
case 1:
m_animation.CrossFade(enemy_Animation[7]);
enemy_Attck_Interval = 2;
break;
case 2:
m_animation.CrossFade(enemy_Animation[5]);
enemy_Attck_Interval = 2;
break;
}
}
}
}
这里是当怪物到达之前设定的与玩家的距离范围后就会开始执行攻击动画,这个模型有好几个攻击的动画,这里我就挑了2个动画,所以我设定了一个随机值,还去随机的播放不同的攻击动画,因为之前分配的一些疏忽(团队中一个人已经找到工作了,所以有些脚本写一半就离开了),调用攻击会让玩家掉血的部分没有做完,所以现在就先不写这个了 ,这几天我会把这个写完,到时候在补交上来。。
我相信我们会完成这个,虽说是一个我们以后找工作的项目,但是这也是我们所有的想法,心血,所以一定会完成的。加油!