物理系统与碰撞

8 篇文章 0 订阅
8 篇文章 0 订阅

实践内容

改进飞碟(Hit UFO)游戏:

实践要求:

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

分析

  • Adapter 模式设计
    Adapter
    Adapter模式可以将一个类的接口转换成客户希望的一个接口,使得原本由于接口不兼容的类能一起工作。
    在本次实践中,将原来方便场记调用动作的动作管理类改为了FirstActionManager改为适配器接口IActionManager,并用这个接口来兼容SSActionManager和PhysicActionManager动作管理类,从而同时支持运动学运动和物理运动。

  • 动力学的相关知识(Dynamics)
    1)考虑外部力对物体运动的影响 ,包括重力、阻力、摩擦力等,
    2)考虑物体的重量和形状, 甚至弹性物体
    3)通常模拟物体在现实世界中的运动
    4)通常将一个物体当作刚体
    在unity中主要是通过

    • 向物体添加刚体组件(包括质量 mass 、阻力 Drag 、角阻力 、重力 等属性)component →physics → rigidbody
    • 添加力(包含力和力矩属性) component → physics → constant force
      等方式实现

代码

  • IActionManager
    定义接口来兼容SSActionManager和PhysicActionManager动作管理类,从而同时支持运动学运动和物理运动
public interface IActionManager
{
    void diskFly(GameObject disk, float angle, float power);
}
  • 运动学运动SSActionManager
    和上次作业相比,直接把FirstActionManager里面的飞碟飞行功能添加进来了,使它能直接匹配适配器的接口
public class SSActionManager : MonoBehaviour, ISSActionCallback, IActionManager	//继承IActionManager
{
    private Dictionary<int, SSAction> actions = new Dictionary<int, SSAction>();    
    private List<SSAction> waitingAdd = new List<SSAction>();                       
    private List<int> waitingDelete = new List<int>();                                            

    public DiskFlyAction fly;                            //添加部分
    public FirstController scene_controller;             //添加部分

    protected void Start()
    {
        scene_controller = (FirstController)Director.GetInstance().currentSceneController;
        scene_controller.actionManager = this;

    }

    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();
            }
        }

        foreach (int key in waitingDelete)
        {
            SSAction ac = actions[key];
            actions.Remove(key);
            DestroyObject(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.Completed,
        int intParam = 0, string strParam = null, Object objectParam = null)
    {
    }

    public void diskFly(GameObject disk, float angle, float power)//添加部分
    {
        fly = DiskFlyAction.GetSSAction(angle, power);
        this.RunAction(disk, fly, this);
    }
}
  • 物理学运动PhysicActionManager

在本次实验中,向飞碟添加Rigidbody实现运动,
每个飞碟会被赋予一个随机的初速度velocity,关闭使用重力,让飞碟运动的更自由,添加阻力drag,阻力根据出入的power来设置,drag越小,飞行速度越快。

public class PhysicActionManager : MonoBehaviour, IActionManager
{
    private Dictionary<int, SSAction> actions = new Dictionary<int, SSAction>();    
    private List<SSAction> waitingAdd = new List<SSAction>();                       
    private List<int> waitingDelete = new List<int>();                                 

    public DiskFlyAction fly;                            
    public FirstController scene_controller;             

    protected void Start()
    {
        scene_controller = (FirstController)Director.GetInstance().currentSceneController;
        scene_controller.actionManager = this;

    }

    protected void FixedUpdate()
    {
        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();
            }
        }

        foreach (int key in waitingDelete)
        {
            SSAction ac = actions[key];
            actions.Remove(key);
            DestroyObject(ac);
        }
        waitingDelete.Clear();
    }

    public void diskFly(GameObject disk, float angle, float power)
    {
        disk.GetComponent<Rigidbody>().velocity = new Vector3(Random.Range(-10, 10), Random.Range(-10, 10), Random.Range(-10, 10));
        disk.GetComponent<Rigidbody>().useGravity = false;
        disk.GetComponent<Rigidbody>().drag = (30 - power) / 20;
    }

    public void SSActionEvent(SSAction source, SSActionEventType events = SSActionEventType.Completed,
        int intParam = 0, string strParam = null, Object objectParam = null)
    {
    } 
}
  • FirstController
    将原来的FirstActionManager组件换为动作管理器Adapter接口,添加管理器时使用具体的SSActionManager或PhysicActionManager来实例化
public class FirstController : MonoBehaviour, ISceneController, UserAction
{

    public int round;
    public int trial;
    public float interval;
    public int score;
    private UserGUI userGUI;
    private Ruler ruler;
    //public FirstActionManager actionManager;      //删除部分
    public IActionManager actionManager;            //添加部分

    public GameObject cam;
    private Queue<GameObject> disksQueue = new Queue<GameObject>();
    private bool isRestart;
    void Awake()
    {
        Director director = Director.GetInstance();
        director.currentSceneController = this;
        director.currentSceneController.loadResources();

        userGUI = gameObject.AddComponent<UserGUI>() as UserGUI;
        //actionManager = gameObject.AddComponent<FirstActionManager>() as FirstActionManager;      //删除部分
        
        actionManager = gameObject.AddComponent<SSActionManager>() as IActionManager;               //添加部分
        //actionManager = gameObject.AddComponent<PhysicActionManager>() as IActionManager;         //添加物理运动管理器
        ruler = gameObject.AddComponent<Ruler>() as Ruler;
        cam.transform.position = new Vector3(0,-2,-15);
    }
    //...
}    

游戏效果:

运动控制的效果和上次一样,物理控制的效果会有些抛体运动的效果
游戏界面
物理运动版视频

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值