任务要求
- 按adapter模式设计修改飞碟游戏
- 同时支持物理运动和运动学运动
实现过程
由于这次是在之前一次作业的基础上完成的,所以首先将之前的代码copy一份,然后对其进行修改。由于之前做的飞碟游戏并没有采用老师提供的动作分离的结构,所以这次的更改也没有采用老师提供的架构,就导致代码的结构非常的混乱,由此可见一个好的代码结构是多么的重要。
这次的实验主要目的是添加一个物理运动,然后还可以在物理运动与运动学运动之间转换。为了尽可能少的更改之前的代码,所以只在局部采用了adapter的模式,主要就是对于物理运动的实现。首先定义一个物理运动的接口,然后使用一个类来继承这个接口,并把它实现,然后再在控制类里面调用,从而实现物理学运动。
设置物理学运动的接口:
public interface grativity
{
void setGrativity(GameObject obj, Vector3 dir);
void removeGrativity(GameObject obj);
}
然后使用一个类来继承并实现这个接口:
public class adapter : MonoBehaviour, grativity {
/*void setGrativity(GameObject obj)
{
obj.gameObject.GetComponent<Rigidbody>().AddForce(Vector3.down * 9.8f);
}*/
public void setGrativity(GameObject obj, Vector3 dir)
{
//obj.gameObject.AddComponent<Rigidbody>();
//obj.gameObject.GetComponent<Rigidbody>().AddForce(dir * 9.8f);
obj.gameObject.AddComponent<Rigidbody>();
obj.gameObject.GetComponent<Rigidbody>().AddForce(dir);
obj.gameObject.GetComponent<Rigidbody>().useGravity = false;
//throw new System.NotImplementedException();
}
public void removeGrativity(GameObject obj)
{
obj.AddComponent<Rigidbody>();
//u.GetComponent<Rigidbody>().AddForce(-dir[num]);
Destroy(obj.GetComponent<Rigidbody>());
}
public void setmoveable(GameObject obj)
{
if (obj.gameObject.GetComponent<Rigidbody>() != null)
{
Destroy(obj.gameObject.GetComponent<Rigidbody>());
}
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
在控制类中就可以直接调用这个类来使用这些方法
控制其移动中:
移除时:
其他的一些改进
在之前版本的打飞碟游戏中由于飞碟是没有添加刚体属性的,所以在生成物体的时候都是将他们在同一个地方生成的,然后每个trial同时发射。这点在物理学运动时添加刚体后是有问题的,如果刚体生成时出现了重合,那么在让其运动的时候就会出现剧烈的弹飞,导致飞碟飞行的路径不好设置,所以为了改进这一点对于飞碟的生成发射方式进行了一个改进。
在每个trial,飞碟是一个一个生成并发射出去的,这样就避免了两个飞碟重合的情况,具体实现如下:
每当到达一个trial的时候控制变量create设置为1表示可以生成飞碟了,然后每隔0.2f的时间从工厂中拿出一个飞碟发射,达到依次发射飞碟的目的。
对于两种模式的切换问题
题目中有说到同时实现两个运动,所以就需要一个变量来控制现在到底使用的是哪种运动方式,而这个变量是可以在运行时被更改的。为了更加的简单,所以我没有设计一个专门的按钮来实现切换,而是直接使用一个public的变量来进行控制,这样就算在游戏运动场景中也可以进行变换。
然后在控制飞碟运动的时候就进行判断,并调用不同的函数来实现
运行截图
在空对象中就可以看到一个mod的选项,这里就可以对模式进行切换。
项目地址