unity3d-5

unity3d 打飞碟之升级版
应用Adapter设计模式统一物体运动接口.

Hit UFO v2

仓库地址

视频地址_p2


先看一下这次设计的结构:
UML

在我的设计中, RoundController 就是 FirstController.
在v1中, 由 FirstController 设置位置并执行运动.
而在v2这里, FirstController 需要 Disk 飞出时, 调用 IActionManager.PlayDisk() 就 OK 了, 实现封装的同时还能根据不同的需要(运动学, 动力学)来使飞碟运动.

当然啦, 大部分游戏过程的控制, 如, 计时, 下一回合等等, 还是由 FirstController 处理的.
具体在游戏中选择那个方式运动, 是在这里决定的:
IAM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// FirstController 控制的回合结束
private void RoundOver()
{
while(Disks.Count > 0)
{
Factory.FreeDisk(Disks.Dequeue());
}
this.Round++;
this.time = 0;
this.Playing = false;
if (Round > 10)
{
userGUI.status = 0;
}
}

IActionManager 接口类就只定义了一个函数, 不知道以后会不会扩展

1
2
3
4
public interface IActionManager
{
void PlayDisk(GameObject disk, Vector3 initPosition);
}

PhysisActionManager 类, 就是原来的重力+初速度, 没什么变化..

1
2
3
4
5
6
7
public void PlayDisk(GameObject disk, Vector3 initPosition)
{
Debug.Log(disk);
disk.transform.GetComponent<Rigidbody>().useGravity = true;
disk.transform.position = initPosition;
disk.transform.GetComponent<Rigidbody>().velocity = disk.GetComponent<Disk>().direction * disk.GetComponent<Disk>().speed;
}

而运动学部分就不太一样, 我这里新建了一个 UFOAction 类, 继承了 SSAction.
这个类就是来定义 UFO 的运动的, 并由 SSActionManager 管理.

具体动作是每帧都往速度方向移动, 添加向下的力.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class UFOAction : SSAction
{
public Vector3 speed;
public Vector3 force;

public static UFOAction GetUFOAction(Vector3 t, Vector3 s)
{
UFOAction action = ScriptableObject.CreateInstance<UFOAction>();
action.speed = t;
action.force = s;
return action;
}

public override void Start()
{
this.enable = true;
}

public override void Update()
{
if (gameobject != null && gameobject.activeInHierarchy == true)
{
gameobject.transform.Translate(speed * Time.deltaTime);
gameobject.transform.GetComponent<Rigidbody>().AddForce(force);
}
else
{
this.enable = false;
this.destroy = true;
gameobject.transform.GetComponent<Rigidbody>().velocity = Vector3.zero;
}
}
}

然后让 CCActionManager 作为回调处理类, 但实际没有执行任何操作.
同时 CCActionManager 也是 IActionManager 的一个实现, 调用 PlayDisk 方法时让 SSActionManager 运行 UFOAction.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class CCActionManager : SSActionManager, ISSActionCallback, IActionManager
{
//public FirstController SceneController;
//private GameObject d;

public void SSActionEvent(SSAction source, SSActionEventType events = SSActionEventType.Competeted,
int intParam = 0, string strParam = null, Object objectParam = null)
{

}

public void PlayDisk(GameObject disk, Vector3 initPosition)
{
disk.transform.position = initPosition;
disk.transform.GetComponent<Rigidbody>().useGravity = false;
//this.Update();
UFOAction ac = UFOAction.GetUFOAction(disk.GetComponent<Disk>().direction * disk.GetComponent<Disk>().speed, Vector3.down * 9.8f);
RunAction(disk, ac, this);
}

protected new void Start()
{
//SceneController = (FirstController)Director.GetInstance().CurrentScenceController;
//SceneController.actionManager = this;
}

protected new void Update()
{
base.Update();
}
}

大概就是这样, 射箭初步有一些思路, 若时间充裕到时会完成.