物理系统与碰撞-作业与练习(6)

1、改进飞碟(Hit UFO)游戏:

游戏内容要求:

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

新的设计:
在这里插入图片描述
可以看出,本次的目的在于不放弃 CCActionManager的条件下,引入PhysisActionManager,说白了就是加个开关来调节模式,为此引入IActionManager。上次作业中round的控制是在FirstController里完成的,理论上这次应该拿出来再给一个新的类,但是看了下貌似只需要加一个函数就完事了。虽然分出去代码结构更清晰

首先是对CCActionManager的改动,需要加入IActionManager的接口。
在这里插入图片描述
CCFlyAction中也要将飞碟的初始属性修改运动学运动。
在这里插入图片描述

之后是物理运动实现部分。
PhysisActionManager:

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

public class PhysisActionManager :SSActionManager, ISSActionCallback, IActionManager
{
    // Start is called before the first frame update
    public PhysisFlyAction flyAction;
    public FirstController controller;

    protected new void Start()
    {
        controller=SSDirector.getInstance().currentSceneController as FirstController;
    }

    public void Fly(GameObject obj, float speed, Vector3 direction){
        flyAction=PhysisFlyAction.GetSSAction(direction,speed);
        this.RunAction(obj,flyAction,this);
    }
    public void SSActionEvent(SSAction source,
        SSActionEventType events=SSActionEventType.Competed,
        int intParam=0,
        string strParam=null,
        Object objectParam=null){
            controller.ufoFactory.FreeUFO(source.gameObject);
        }
}

PhysisFlyAction:

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

public class PhysisFlyAction : SSAction
{
    float speed;            //水平速度
    Vector3 direction;      //飞行方向

    public static PhysisFlyAction GetSSAction(Vector3 direction, float speed)
    {
        PhysisFlyAction action = ScriptableObject.CreateInstance<PhysisFlyAction>();
        action.speed = speed;
        action.direction = direction;
        return action;
    }
    public override void Start()
    {
        gameObject.GetComponent<Rigidbody>().isKinematic  = false;
        //为物体增加水平初速度
        gameObject.GetComponent<Rigidbody>().velocity = speed * direction;
    }

    public override void Update()
    {
        if (this.transform.position.y < -8)
        {
            this.destroy = true;
            this.enable = false;
            this.callback.SSActionEvent(this);
        }

    }
}

FirstController中需要加入模式切换的函数,具体修改如下:

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

public class FirstController : MonoBehaviour, ISceneController, IUserAction {

	private bool isRuning;

	public UFOFactory ufoFactory;
	private int[] roundUFOs;
	private int score;
	private int round;
	private float sendTime;
	private bool model;
	int sendCnt;
	private IActionManager actionManager;
	// the first scripts
	void Awake () {
		SSDirector director = SSDirector.getInstance ();
		director.currentSceneController = this;
		director.currentSceneController.LoadResources ();
		this.gameObject.AddComponent<UserGUI>();
        this.gameObject.AddComponent<CCActionManager>();
		this.gameObject.AddComponent<PhysisActionManager>();
		ufoFactory=UFOFactory.getInstance();
		roundUFOs=new int[]{3,5,9,11,15};
		score=round=sendCnt=0;
		sendTime=0;
		sendCnt =0;
		model = true;
		actionManager=this.gameObject.GetComponent<CCActionManager>();
	}
	 
	// loading resources for the first scence
	public void LoadResources () {
		isRuning=true;
	}

	public void SendUFO(){
        GameObject ufo=ufoFactory.GetUFO(round);
        ufo.transform.position=new Vector3(-ufo.GetComponent<UFOData>().direction.x * 7, UnityEngine.Random.Range(0f, 8f), 0);
        ufo.SetActive(true);
        actionManager.Fly(ufo,ufo.GetComponent<UFOData>().speed,ufo.GetComponent<UFOData>().direction);
    }

	public bool GetIsRuning(){
		return isRuning;
	}

	public void JudgeCallback(bool isRuning,int score){
		this.score+=score;
        this.gameObject.GetComponent<UserGUI>().score=this.score;
        this.isRuning=isRuning;
    }
	public void ChangeMode(){
		model=!model;
		if(model){
			actionManager=this.gameObject.GetComponent<CCActionManager>();
		}
		else{
			actionManager=this.gameObject.GetComponent<PhysisActionManager>();
		}
	}
	public void Pause ()
	{
		throw new System.NotImplementedException ();
	}

	public void Resume ()
	{
		throw new System.NotImplementedException ();
	}

	#region IUserAction implementation
	public void Restart ()
	{
		isRuning=true;
		this.gameObject.GetComponent<UserGUI>().gameMessage="";
		this.gameObject.GetComponent<UserGUI>().score=0;
		score=round=sendCnt=0;
		sendTime=0;
		ufoFactory.FreeALL();
	}
	#endregion


	void Start () {

	}
	
	void Update () {

		
			sendTime+=Time.deltaTime;
			if(sendTime>2){
				sendTime=0;
				
				for(int i = 0; i < 5 && sendCnt < roundUFOs[round]; i++){
				  	sendCnt++;	
					SendUFO();
				}
				if(sendCnt == roundUFOs[round]&&round==roundUFOs.Length-1){
					isRuning=false;
					gameObject.GetComponent<UserGUI>().gameMessage = "Time Out!";
				}
				if(sendCnt == roundUFOs[round] && round < roundUFOs.Length - 1){
					sendCnt = 0;
                	round++;
				}
				
			
			}
			
	}

}

最后在UserGUI中在加入一个按钮就好
在这里插入图片描述
值得一提的是,要在预制体飞碟上加上刚体属性,由于选择了默认使用重力,在运动轨迹控制那里只需要加上水平速度即可。并且加上了刚体属性后,模型之间会产生碰撞,使得运动看起来更真实了一些。
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值