Unity 3D游戏六:打飞碟物理引擎

前言

中山大学数据科学与计算机学院3D游戏课程学习记录博客。
游戏代码: gitee
游戏视频: bilibili
参考师兄的博客: 师兄博客

游戏要求

  • 按 adapter模式设计图修改飞碟游戏。
  • 使它同时支持物理运动与运动学(变换)运动。

游戏分析

重用游戏五的代码,需要增加物理运动的相关代码,即PhysisDiskFlyAction.cs;
然后在FirstController.cs中根据情况选择调用物理运动和运动学运动两种运动方式,就可以实现adapter模式。

adapter模式:
将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。

游戏实现

  • PhysisDiskFlyAction.cs的实现:
    PhysisDiskFlyAction.cs的实现模仿DiskFlyAction.cs,继承自SSAction;
    因为要使用物理引擎,所以通过FixedUpdate来实现位置更新;
    在Start()函数中给飞碟施加一个冲击力。
public class PhysisDiskFlyAction : SSAction
{
    private Vector3 start_vector;                              
    public float power;
    private PhysisDiskFlyAction() { }
    public static PhysisDiskFlyAction GetSSAction(int lor, float power) {
        PhysisDiskFlyAction action = CreateInstance<PhysisDiskFlyAction>();
        if (lor == -1) {
            action.start_vector = Vector3.left * power;
        }
        else {
            action.start_vector = Vector3.right * power;
        }
        action.power = power;
        return action;
    }

    public override void Update() { }

	//物理引擎更新
    public override void FixedUpdate() {
        if (transform.position.y <= -10f) {
            gameobject.GetComponent<Rigidbody>().velocity = new Vector3(0, 0, 0);
            this.destroy = true;
            this.callback.SSActionEvent(this);
        }
    }

    public override void Start() {
        gameobject.GetComponent<Rigidbody>().AddForce(start_vector*3, ForceMode.Impulse);
    }
}
  • SSAction.cs和SSActionManager.cs的改进:
    SSAction.cs应该添加FixedUpdate函数,以便PhysisDiskFlyAction从SSAction中继承;
    SSActionManager.cs在调用Update的时候也应该调用FixedUpdate,以便物理运动更新。
public class SSAction : ScriptableObject {
    //物理引擎配置
    public virtual void FixedUpdate() {
        throw new System.NotImplementedException();
    }
}

public class SSActionManager : MonoBehaviour, ISSActionCallback {            
    protected void Update() {
        foreach (KeyValuePair<int, SSAction> kv in actions) {
            SSAction ac = kv.Value;
            if (ac.destroy) {
                waitingDelete.Add(ac.GetInstanceID());
            }
            else if (ac.enable) {
                ac.Update();
                ac.FixedUpdate();//添加物理运动
            }
        }
}

  • FlyActionManager.cs的改进:
    对应物理学运动,增加一个physicsDiskFly函数,来使用物理引擎。
public class FlyActionManager : SSActionManager {
    
    public void DiskFly(GameObject disk, float angle, float power) {
        //运动学运动
    }

    public void physicsDiskFly(GameObject disk,float power){
        //物理引擎运动
    }
}
  • UserGUI.cs的改进:
    UserGUI.cs应该支持一个改变模式按钮来改变模式;
    模式使用mode表示,通过mode^1来改变模式;
    0代表运动学运动,1代表物理学运动。
public class UserGUI : MonoBehaviour {
    private int mode=0;
	
	void OnGUI () {
        if (game_start) {
            //游戏运行操作
        }
        else {
			//游戏未开始操作
			//如果想全程支持切换功能,可以把“改变模式”的生成代码放到if(game_start)外面
            if(GUI.Button(new Rect(Screen.width / 2 - 30, Screen.height / 2 - 180, 80, 20), "改变模式")){
                mode=mode^1;
            }
        }
    }

    public int getMode(){
        return mode;
    }
}
  • FirstController.cs的改进:
    FirstController.cs从UserGUI.cs中得到mode值,并且调用对应的函数。
public class FirstController : MonoBehaviour, ISceneController, IUserAction {
    private void SendDisk(int type) {
        if(user_gui.getMode()==1){
            action_manager.physicsDiskFly(disk,power);
        }else{
            action_manager.DiskFly(disk, angle, power);
        }
    }
}
  • 给预制增加刚体组件:
    物理引擎需要预制具有刚体组件。
    通过AddComponent->Rigidbody来增加。

至此,游戏设计完成。

总结

本次实验主要了解了物理引擎的使用,使用物理引擎就不用进行复杂的公式计算,还是比较方便的。

选做题:打靶游戏

博客链接:打靶游戏

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值