06-物理系统与碰撞
程序员文章站
2024-03-16 19:50:40
...
Homework06
项目地址
演示视频
使用说明:创建一个空GameObject将FirstSceneController.cs
挂载到新建游戏对象即可
改进飞碟(Hit UFO)游戏
- 游戏内容要求:
- 按 adapter模式设计图修改飞碟游戏
- 使它同时支持物理运动与运动学(变换)运动
设计实现
设计结构和实现思路在作业5已经说明,以下只介绍和展示按要求改进部分
1. BaseCode.cs
新增mode使UFO同时支持物理运动与运动学运动
- 物理运动受重力影响,运动学运动不受重力影响,详见视频
- 增加一个ActionMode枚举类型
// v2-add
public enum ActionMode {PHYSICS, KINEMATIC}
IActionManager
接口,根据mode控制飞碟飞行属性
// v2-modify
public interface ISceneController { // 加载场景
void Init ();
SceneController getSceneController();
ActionMode getMode();
void setMode(ActionMode mode);
}
// v2-add
public interface IActionManager {
GameObject GetDisk(int round, ActionMode mode);
}
2. DiskFactory.cs
新增实现IActionManager接口的功能
- 移除UFO Prefabs的刚体组件
- 将原本设定的所有飞碟皆受重力作用给为仅当mode为PHYSICS时增加
Rigidbody
和重力作用
public class DiskFactory : MonoBehaviour, IActionManager {
public GameObject GetDisk(int round, ActionMode mode) {
// V2-add:如果为PHTSICS模式,增加rigidbody和重力作用
if(mode == ActionMode.PHYSICS) {
newDisk.AddComponent<Rigidbody>();
newDisk.GetComponent<Rigidbody>().AddForce(Vector3.down * 9.8f, ForceMode.Acceleration);
}
}
}
3. FirstSceneController.cs
增加mode作为成员变量
- 新增对应的
get
、set
方法- 并将其传递给
DiskFactory
的GetDisk()
方法生成所需的飞碟
// v2-add
public ActionMode mode; // 选择模式
public ActionMode getMode() {
return mode;
}
public void setMode(ActionMode m) {
mode = m;
}
// 初始化每个回合的飞碟队列,每个回合的飞碟属性不同
void initQueue() {
diskQueue.Clear();
// v2-modify
for(int i = 0; i < 10; i++)
diskQueue.Enqueue(Singleton<DiskFactory>.Instance.GetDisk(round, getMode()));
}
4. UserGUI.cs
新增模式选择功能
- 新增成员变量
ActionMode mode
- 在
Start
方法中对其进行初始化
mode = ActionMode.PHYSICS;
- 修改
OnGUI
方法增加选择模式按钮
private void OnGUI()
{
if(reset == 1){
// if(GUI.Button(new Rect(380, 250, 100, 80), "Reset",buttonStyle)){
// //userAction.Init();
// Director.getInstance().currentSceneController.Init();
// reset = 0;
// }
if(GUI.Button(new Rect(200, 250, 100, 80), "KINEMATIC",buttonStyle)){
mode = ActionMode.KINEMATIC;
Director.getInstance().currentSceneController.setMode(mode);
Director.getInstance().currentSceneController.Init();
reset = 0;
return;
}
if(GUI.Button(new Rect(400, 250, 100, 80), "PHYSICS",buttonStyle)){
mode = ActionMode.PHYSICS;
Director.getInstance().currentSceneController.setMode(mode);
Director.getInstance().currentSceneController.Init();
reset = 0;
return;
}
}
if(reset == 0) {
int round = Director.getInstance().currentSceneController.getSceneController().getRound();
int total = Director.getInstance().currentSceneController.getSceneController().getTotal();
int score = Director.getInstance().currentSceneController.getSceneController().getScore();
int miss = total - score;//未击中的飞碟数
//string text = "Round: " + userAction.getSceneController().GetRound().ToString() + "\nTotal: " + total.ToString() + "\nScores: " + score.ToString();
string text = "Round: " + round.ToString() + "\nMiss: " + miss.ToString() + "\nScores: " + score.ToString();
GUI.Label(new Rect(10, 10, Screen.width, 50),text,style);
}
}
5. 一些小修改(详见代码和视频展示)
- 上一个版本是点击运行直接开始游戏,本次实现由于可以选择模式,所以一开始出现选择按钮,点击按钮后再开始
- 上一个版本中显示的MISS数目直接由飞碟总数 - 击中飞碟数得到,产生新的UFO时即会加1,本次修复了这个小bug
上一篇: 绘制多边形并进行拉伸
下一篇: Unity 物理系统--碰撞、触发