根据老师的uml图,在之前的打飞碟游戏的代码的基础上进行修改,这里只贴修改了的代码。
对场记的Start函数进行修改,场记中有一个bool变量决定是否使用物理系统,当为真的时候,动作管理器就使用物理系统,否则就使用原来的运动管理器。
// Use this for initialization
void Start () {
diskFac = Singleton.Instance;
if (ifPhysicManager) {
actionManager = gameObject.AddComponent();
} else {
actionManager = gameObject.AddComponent();
}
}
同时可以在场景中看到在main这个空对象可以选择是否使用物理运动
新添加一个物理运动的管理器,由于是物理运动,因此运动都是要使用FixedUpdate,那么物理运动的管理器也同样是在FixedUpdate的时候更新每一个运动,这一个物理运动的管理器与之前的运动管理器的代码基本上相似。
public class physicActionManager : SSActionManager,ISSActionCallback {
public void SSActionEvent(SSAction source, SSActionEventType events = SSActionEventType.Competeted,
int intParam = 0, string strParam = null, Object objectParam = null){
}
//清除所有action,
public void reset(){
actions.Clear ();
}
public void FixedUpdate(){
if (roundCtrl.status == "pause") //停止玩就不更新action了
return;
foreach (SSAction ac in waitingAdd) actions[ac.GetInstanceID()] = ac;
waitingAdd.Clear();
foreach (KeyValuePair<int, SSAction> kv in actions)
{
SSAction ac = kv.Value;
if (ac.gameobject.active == false || ac.destroy)//gameobject的active是false就不更新action了
{
waitingDelete.Add(ac.GetInstanceID());
}
else if ( ac.enable)
{
ac.FixedUpdate();
}
}
foreach (int key in waitingDelete)
{
SSAction ac = actions[key]; actions.Remove(key); DestroyObject(ac);
}
waitingDelete.Clear();
}
}
没有直接新写一个物理运动类,只是改写了一下原来的运动类diskMove,当使用物理运动的时候,将随机一个运动的方向,同时新添加一个FixedUpdate的函数,用于物理运动,物理运动的时候,取消了重力,因为有重力的时候发现下坠太快了,尽可能把新增加的物理运动和原来的运动一样,因此取消了重力。而且因为原来的运动就是恒速的运动,因此没有给物体直接加一个恒力,而是给物体直接加一个速度的变化VelocityChange。
public class diskMove : SSAction {
public Vector3 aim;
public float speed;
public diskInfo thisDisk;
public float time = 0;
public Vector3 dirction ;
public override void Start () {
}
public static diskMove getDiskMove( diskInfo disk , int lever , bool ifPhysicManager){
diskMove action = ScriptableObject.CreateInstance ();
action.thisDisk = disk;
switch (lever) {
case 1:
action.speed = 6f;
break;
case 2:
action.speed = 8f;
break;
case 3:
action.speed = 10f;
break;
}
if (!ifPhysicManager) {
action.aim = new Vector3 (Random.Range (-2f, 2f), Random.Range (-2f, 2f), Random.Range (4f, 10f));
} else {
action.aim = Vector3.zero;
float xPositionOfMax ,xPositionOfMin , yPositionOfMax , yPositionOfMin;
if (disk.disk.transform.position.x > 0) {
xPositionOfMax = 0.2f;
xPositionOfMin = 0f;
}
else {
xPositionOfMax = 0f;
xPositionOfMin = -0.2f;
}
if (disk.disk.transform.position.y > 0) {
yPositionOfMax = 0.2f;
yPositionOfMin = 0f;
} else {
yPositionOfMax = 0f;
yPositionOfMin = -0.2f;
}
action.dirction = new Vector3 (Random.Range (xPositionOfMin, xPositionOfMax)
, Random.Range (yPositionOfMin, yPositionOfMax), Random.Range (0.2f, 1f));
Rigidbody rigid = action.thisDisk.disk.GetComponent ();
rigid.AddForce (action.dirction * action.speed , ForceMode.VelocityChange);
rigid.useGravity = false;
}
return action;
}
// Update is called once per frame
public override void Update () {
gameobject.transform.position = Vector3.MoveTowards (gameobject.transform.position, aim, speed * Time.deltaTime);
if (this.transform.position == aim) {
this.destroy = true;
this.enable = false;
Singleton.Instance.freeDisk (thisDisk);
}
}
//
public override void FixedUpdate(){
time += Time.fixedDeltaTime;
if (time > 2) {
time = 0;
this.destroy = true;
this.destroy = false;
Singleton.Instance.freeDisk (thisDisk);
}
}
}
同时如果要用物理运动管理器的话,物理运动是要加刚体的,因此在飞碟的类diskInfo初始化要加刚体。
public class diskInfo{
public GameObject disk;
public int diskId;
public int lever;
public diskInfo(int id , int lever ,bool ifPhysicManager){
this.diskId = id;
disk = GameObject.Instantiate(Resources.Load("prefabs/disk" ), Vector3.zero , Quaternion.identity);
disk.name = "disk" + id.ToString ();
if (ifPhysicManager && disk.GetComponents() != null ) {
disk.AddComponent ();
}
reset (lever);
}
public void reset(int lever){
disk.transform.rotation = Quaternion.identity;
disk.transform.position = new Vector3 (Random.Range (-10f, 10f), Random.Range (-10f, 10f), Random.Range (0f, 2f));
switch (lever) {
case 1:
disk.GetComponent ().material.color = Color.red;
disk.transform.localScale = new Vector3 (3f, 0.3f, 3f);
break;
case 2:
disk.GetComponent ().material.color = Color.yellow;
disk.transform.localScale = new Vector3 (2f, 0.2f, 2f);
break;
default:
disk.GetComponent ().material.color = Color.grey;
disk.transform.localScale = new Vector3 (1f, 0.1f, 1f);
break;
}
this.lever = lever;
disk.SetActive(true);
}
}
跟随着老师的模式设计学习后,再添加新的东西修改不用很多,也就修改几个类,以前写过的几个类也不用做大的修改,就能轻松添加新的功能,由此可见好的设计模式对于程序的扩展是非常重要的。