首先因为我们要写的程序较以往而言有点大,因此我们可以写一个文件夹用来储存基类对象“Scene/Boss”。
Boss这个模块我们可以暂时认为是三个字段组成,此时穿插一下,以往我们的编码是面对组件(GameObject(组件容器)(游戏对象消失,脚本消失))(脚本是组件,这种方式方便调试。但是不利于他人解读,最后功能不好整合,代码不好进行管理)。因此,此时我们要用面对对象的思维进行编码(对象(容器) gameobject)。
所以有三个字段:
1Transform(也就是聚合一个Transform)
private Transform _transform;
此时我们要考虑面对对象的封装性(防止外部对其进行改变和访问),如果外部想读取,此时可以添加访问器(进行字段封装)
public Transform Transform { get { return _transform; } }
2配置(BossCfg)(处理相关动作和行为)
private BossCfg _cfg;
public BossCfg Cfg { get { return _cfg; } }
此时我们可以定义几个虚方法供boss子类使用
//boss初始化
public virtual void Init()
{
}
//boss更新
public virtual void Update()
{
}
然而在Boss最初new对象的时候,我们要把必要的东西进行规范
此时我们需要构造器进行初始化(也可以说构造器就是用来初始化的)
public Boss(BossCfg cfg)
{
_cfg=cfg;
//此时我们可以考虑在new时就进行初始化,
Init();
}
此时我们可以去外部进行资源的导入和配置的添加(导入时建议记录下文件名,方便以后的操作。并且建议放在统一的文件夹里(导入到Model/Boss文件夹下),方便查找)。因为此时我们的资源来源于网上,没有统一的标准,所以在接下来的使用时要将其规范化:
在一定规范下做出来的模型一般只有两个组件(Transfrom和Animation),所以我们要整理的就是这两个组件(记录、调整、添加组件(或动画)Transfrom和Animation(动画要统一))。
这里我们将Legacy动画为统一标准:
我们要将需要的动画补充完整(填充到模型上),并将需要的组件进行调试并记录下来:
调试完成之后,我们需要将调试信息记录在xml文本中。
后面是这次添加的碰撞器配置信息和脚本
//映射对象 + 字典 = save
public class BossCfg
{
public int ID;
public string Name;
public int Hp;
public AttackType AttackType;
//这次添加的脚本
public string Model;
public string ColliderCenter;
public float ColliderRadius;
public float ColliderHeight;
public int ColliderDirection;
public BossType BossType;
}
接下来我们在Boss类中进行代码编写
using UnityEngine;
using System.Collections;
public class Boss {
public Boss(BossCfg cfg)
{
_cfg = cfg;
//将外观中的模型以及碰撞器添加完整
_transform = GameObject.Instantiate(Resources.Load<GameObject>("Boss/" + _cfg.Model)).transform;
}
}
碰撞器配置信息添加完成之后我们需要添加模型和碰撞器
using UnityEngine;
using System.Collections;
public class Boss {
//记录碰撞器
private CapsuleCollider _collider;
public CapsuleCollider Collider { get { return _collider; } }
public Boss(BossCfg cfg)
{
_collider = _transform.GetComponent<CapsuleCollider>();
//判空操作防止重复添加
if (_collider == null)
{
_collider = _transform.gameObject.AddComponent<CapsuleCollider>();
}
//读取并初始化配置相关属性(因为这两者是不同的类型并且需要多次操作,所以我们可以在配置管理器(ConfigManager )写一个方法(GetVector3)(写在配置管理器中(ConfigManager)) _collider.center=_cfg.ColliderCenter)
_collider.center = ConfigManager.Instance.GetVector3(_cfg.ColliderCenter);
_collider.radius = _cfg.ColliderRadius;
_collider.height = _cfg.ColliderHeight;
_collider.direction = _cfg.ColliderDirection;
if(_machine == null)
{
_machine = new BossStateMachine();
}
//这个初始化可以统一执行关于值类型的数据。
Init();
}
}
字符串切割方法:
using UnityEngine;
using System.Collections;
using System.Xml;
using System.Collections.Generic;
using System;
using System.Reflection;
//逻辑相同 类型不同 ---- 泛型
//处理加载,缓存,获取配置的管理器
public class ConfigManager : Singleton<ConfigManager> {
//字符串转三位向量
public Vector3 GetVector3(string str)
{
string[] pos = str.Split(new char[] { ',' },System.StringSplitOptions.RemoveEmptyEntries);
return new Vector3(float.Parse(pos[0]), float.Parse(pos[1]), float.Parse(pos[2]));
}
}
对Init()方法的补充(对值类型数值的初始化):
using UnityEngine;
using System.Collections;
public class Boss {
public Boss(BossCfg cfg)
{
private int _hp;
public int Hp { get { return _hp; } }
public virtual void Init()
{
//不能直接对引用类型操作(所以要进行初始化并拷贝)
_hp = _cfg.Hp;
Debug.Log("初始化怪物属性");
}
//boss更新
public virtual void Update()
{
//对行为的更新我们暂时用Debug来描述,这里输出怪物name为了方便我们看出是哪个Boss在更新行为。
Debug.Log(_cfg.Name + "更新怪物相关行为");
}
}
此时我们可以添加一个BossManager
//我们先搭框架以后补充逻辑
using UnityEngine;
using System.Collections.Generic;
public class BossManager : Singleton<BossManager> {
private List<Boss> _bossList = new List<Boss>();
/// <summary>