欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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作为成员变量

  • 新增对应的getset方法
  • 并将其传递给DiskFactoryGetDisk()方法生成所需的飞碟
// 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
相关标签: 3D游戏