改进飞碟(Hit UFO)游戏
要求
- 按 adapter模式 设计图修改飞碟游戏
- 使它同时支持物理运动与运动学(变换)运动
实现
原项目:3D编程与游戏设计做业五
仅仅对其中的一些类进行改动就能实现。
git
飞碟预设
因为要求支持物理运动,所以飞碟的预设须要在原来的基础上加上刚体:
github
Adapter的实现
adapter是经过不一样的状态选择不一样的接口,在本做业中是选择不一样的动做实现方式(物理/运动学),发现与以前的flyActionController的功能相似,所以把它改写成Adapter:编程
public class Adapter : SSActionManager { public DiskFlyAction fly; public PhysisFlyAction fly_; public void DiskFly(GameObject disk, int mode, mes information) { int leftOrRight = 1; if (disk.transform.position.x > 0){ leftOrRight = -1; } if(mode == 2){ fly = DiskFlyAction.GetSSAction(leftOrRight, information.angle, information.speed); this.StartAction(disk, fly); } else{ fly_ = PhysisFlyAction.GetSSAction(leftOrRight, information.speed); this.StartAction(disk, fly_); } } }
经过mode控制运动类型,而后分别调用DiskFlyAction和PhysisFlyAction,这里用到的information是自定义类型,用于存储相关信息。ide
public struct mes{ public float speed; public float angle; }
PhysisFlyAction && SSAction && DiskFlyAction
PhysisFlyAction类,代码以下:函数
public class PhysisFlyAction : SSAction { private bool start_position; public float force; public static PhysisFlyAction GetSSAction(int pos, float force_){ PhysisFlyAction action = CreateInstance<PhysisFlyAction>(); if(pos == 1){ action.start_position = true; } else{ action.start_position = false; } action.force = force_; return action; } // Start is called before the first frame update public override void Start() { Rigidbody disk = gameobject.GetComponent<Rigidbody>(); gameobject.GetComponent<Rigidbody>().useGravity = true; if(gameobject.GetComponent<Rigidbody>().position.y <= 3){ if(start_position){ gameobject.GetComponent<Rigidbody>().AddForce(new Vector3(0.4f,0.2f,0)*force*15f, ForceMode.Impulse); } else{ gameobject.GetComponent<Rigidbody>().AddForce(new Vector3(-0.4f,0.2f,0)*force*15f, ForceMode.Impulse); } } } // Update is called once per frame public override void Update() { } public override void FixedUpdate() { if (transform.position.y <= -10f) { Debug.Log(transform.position.y); gameobject.GetComponent<Rigidbody>().useGravity = false; gameobject.GetComponent<Rigidbody>().velocity = new Vector3(0, 0, 0); this.enable = false; } } }
整体与物理学运动实现相似,可是这里用到了FixedUpdate。
这个类设计的小细节有对重力的改变,在start中,开启了重力,在一个初始力和重力的做用下,飞碟进行抛体运动,当飞碟运动到咱们摄像机视线以外(这里是FixedUpdate中提到的-10f)时,则关闭重力。由于若是不关闭重力,飞碟仍然会继续下落,而后等到DiskFactory回收该飞碟进行下一次使用的时候会具备很大的速度,影响游戏体验,以下图(能够看到第三次绿色飞碟出如今右下角的时候具备很大的竖直速度,一闪而过):
this
因为physic增长了FixedUpdate,所以SSAction、DiskFlyAction也增长了一个空的FixedUpdate:spa
public class SSAction : ScriptableObject { …… public virtual void FixedUpdate() { throw new System.NotImplementedException(); } …… } public class DiskFlyAction : SSAction { …… public override void FixedUpdate() { } …… }
FirstController && Interfaces
FirstController的改动有:
增长了一个bool变量,用于记录是物理运动仍是运动学变换运动,为了经过UserGUI改变这个变量,还增长了一个setPhysic函数,而且同时在Interfaces中加上方便UserGUI修改。
.net
private bool physic = false; …… public void setPhysic(bool physic_){ physic = physic_; }
SSActionManager
增长FixedUpdate:设计
…… if (action.enable) { action.Update(); action.FixedUpdate(); } ……
UserGUI
在第一个界面增长了两个按钮,用于选择是不是physic模式。3d
效果
physic模式:
本来运动学模式仍然正常运行: