鼠标打飞碟(物理引擎)

改进鼠标打飞碟

1. 游戏要求

1.按照adapter模式设计图修改飞碟游戏。

2.使它同时支持物理运动与运动学运动。

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

其UML图如下所示:

在这里插入图片描述

就是改变原先的项目的接口,使得其能够支持物理运动和运动学运动。

2. 游戏实现

​ 要使得飞碟支持物理运动和运动学运动就需要用到刚体Rightbody组件,这样我们就能够向对象施加力,以逼真的物理效果控制飞碟,同时也使飞碟有碰撞响应,更加逼真。

​ 而且Rightbody不能够用Update函数进行更新,需要用到Fixedupdate函数更新,FixedUpdate 在每次进行物理更新前调用,因此在该函数中做出的任何更改都将直接处理。

3. 具体实现

下面只展示与上次作业相比不同的代码。

  1. 首先要将飞盘预制加上刚体(Rightbody)组件。

在这里插入图片描述

  1. PhysicsDiskFlyAction

    扫描二维码关注公众号,回复: 15868169 查看本文章

    规定了飞碟飞行的动作,当飞碟从左边飞入屏幕就给飞碟向左的力,当飞碟从右边飞入屏幕就给飞碟向右的力,当飞碟飞出屏幕外时,将飞碟速度置为0并摧毁该飞碟。与上次作业的主要区别是加入了刚体组件,并且用fixupdate函数更新飞碟的状态。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    // 模拟飞行
    public class PhysicsDiskFlyAction : SSAction {
     private Vector3 start_vector;                              
     public float power;
     private PhysicsDiskFlyAction() { }
     public static PhysicsDiskFlyAction GetSSAction(int lor, float power) {
         PhysicsDiskFlyAction action = CreateInstance<PhysicsDiskFlyAction>();
         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);
     }
    }
    
    
  2. SSAction

    加上FixedUpdate函数,使其适配物理引擎。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    //动作基类
    public class SSAction : ScriptableObject {
        public bool enable = true;                      
        public bool destroy = false;                    
    
        public GameObject gameobject;                   
        public Transform transform;                     
        public ISSActionCallback callback;              
    
        
        protected SSAction() { }
    
        public virtual void Start() {
            throw new System.NotImplementedException();
        }
    
        public virtual void Update() {
            throw new System.NotImplementedException();
        }
        public virtual void FixedUpdate() {
            throw new System.NotImplementedException();
        }
    }
    

4.SSActionManager

​ 在update函数中加入FixedUpdate函数,使其适配物理引擎。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/*动作管理基类*/
public class SSActionManager : MonoBehaviour, ISSActionCallback {
    private Dictionary<int, SSAction> actions = new Dictionary<int, SSAction>();    
    private List<SSAction> waitingAdd = new List<SSAction>();                      
    private List<int> waitingDelete = new List<int>();                                             

    protected void Update() {
        foreach (SSAction ac in waitingAdd) {
            actions[ac.GetInstanceID()] = ac;
        }
        waitingAdd.Clear();

        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();
            }
        }
        
        foreach (int key in waitingDelete) {
            SSAction ac = actions[key];
            actions.Remove(key);
            Object.Destroy(ac);
        }
        waitingDelete.Clear();
    }

    public void RunAction(GameObject gameobject, SSAction action, ISSActionCallback manager) {
        action.gameobject = gameobject;
        action.transform = gameobject.transform;
        action.callback = manager;
        waitingAdd.Add(action);
        action.Start();
    }

    public void SSActionEvent(
        SSAction source, SSActionEventType events = SSActionEventType.Competeted,
        int intParam = 0, string strParam = null, Object objectParam = null) {
    }
}

5.DiskFlyActionManager

管理飞碟动作,引入上面所写的PhisicsDiskFlyAction动作并重新写DiskFly函数。用于管理飞碟的动作。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DiskFlyActionManager : SSActionManager
{
    public PhysicsDiskFlyAction ph_fly;
    public FirstController scene_controller;
    protected void Start()
    {
        scene_controller = (FirstController)SSDirector.GetInstance().CurrentScenceController;
        scene_controller.myactionmanager = this;
    }
    

    public void DiskFly(GameObject disk, float power)
    {
        disk.GetComponent<Rigidbody>().isKinematic = false;
        int loc = disk.transform.position.x < 0 ? 1 : -1;
        ph_fly = PhysicsDiskFlyAction.GetSSAction(loc, power);
        this.RunAction(disk, ph_fly, this);
    }
}

代码及演示

代码位置 将hw6的assets拖到项目中,然后打开Resources中的myscene,运行即可。

演示视频

猜你喜欢

转载自blog.csdn.net/weixin_52801288/article/details/128104839
今日推荐