【遊戲開發】unity教程3 遊戲對象與圖形基礎 牧師與魔鬼動作分離版

github傳送門:https://github.com/dongzizhu/unity3DLearning

Fantasy Skybox FREE的使用

首先我們在Asset Store下載好Fantasy Skybox Free,然後import。

接着只需要在materials文件夾中創建一個新的material,然後將其shader選擇成Skybox/6 sided,然後對六個方向分別選擇對應位置的圖片即可。

接下來直接點擊運行既可以看到我們天空盒的效果。

 

總結遊戲對象的使用

遊戲對象是面向對象變成思想的一種發展,在Unity3D裏,每一個遊戲中用到的單位都可以是一個遊戲對象,然後通過統一的方式來管理。遊戲對象可以是unity自帶的正方體、球體等三維物體,甚至camera也可以是遊戲對象;每個遊戲對象都有屬性和組件,其中最重要的屬性就是transform,用來管理其位置,然後組件可以是腳本,來實現該遊戲對象的行爲邏輯,也可以是紋理材質等,來完善遊戲的畫面。通過這樣的方式,遊戲的運行被強行解耦合,是代碼邏輯更加清晰,也是所有的對象和行爲更加便於管理。

 

牧師與魔鬼動作分離版

設計一個裁判類,當遊戲達到結束條件時,通知場景控制器遊戲結束。

我們直接在上次的代碼上進行改進。增加一個動作管理器來管理船和人物的移動,然後增加一個Referee類,來判別是否結束當前遊戲。在之前的MVC模型中,我們直接由一個Movable類來管理移動的代碼,然後在兩種對象中寫出了相應的方法;這次要實現所謂動作分離,就是指將管理動作的部分從這些controller中分離,單獨抽象出來,其實就是將movable進一步抽象,變成一個MoveController的感覺。所以原本是有controller直接調用model的方法來管理action,現在轉爲調用ActionManager中的相應代碼。

Referee也是類似的感覺,直接將原本的check()分離出來形成一個referee類即可。

ActionController的核心部分是繼承了SSActionManager的ActionManager類。

public class ActionManager : SSActionManager
{   
    public void MoveBoat(BoatController boatCtrl) {
        SSMoveToAction action;
        Vector3 from = new Vector3(5, 1, 0);
        Vector3 to = new Vector3(-5, 1, 0);
        float speed = 50;

        if (boatCtrl.get_to_or_from() == -1) 
            action = SSMoveToAction.GetSSMoveToAction(from, speed);
        else action = SSMoveToAction.GetSSMoveToAction(to, speed);
        boatCtrl.set_to_or_from();
        AddAction(boatCtrl.getGameobj(), action, this);
    }

    public void MoveCharacter(MyCharacterController itemCtrl, Vector3 finalDes) {
        float time = 3;
        float g = -3;
        Vector3 v0;
        float vy_ByGravity = 0;
        float stepTime = 0.1f;
        Vector3 currentDes = itemCtrl.getPosition();

        List<SSAction> divide = new List<SSAction>();

        // the des here is the final destination
        v0 = new Vector3((finalDes.x - itemCtrl.getPosition().x) / time,
            (finalDes.y - itemCtrl.getPosition().y) / time - 0.5f * g * time, (finalDes.z - itemCtrl.getPosition().z) / time);


        // divide the curve to many parts
        for (int i = 0; i < time / stepTime - 1; i++) {
            // change the vy
            vy_ByGravity += g * stepTime;
            // set current des
            currentDes += v0 * stepTime;
            currentDes.y += vy_ByGravity * stepTime;
            // get the current speed
            float currentSpeed = Mathf.Sqrt(v0.x * v0.x + (v0.y + vy_ByGravity) * (v0.y + vy_ByGravity));
            // add one of the movements
            SSAction temp = SSMoveToAction.GetSSMoveToAction(currentDes, currentSpeed * 10);
            divide.Add(temp);
        }
        SSAction seqAction = SequenceAction.GetSequenceAction(1, 0, divide);
        AddAction(itemCtrl.getGameobj(), seqAction, this);
    }
}

其餘的部分大多照抄ppt上的代碼就行,這裏就不一一貼出了,具體請見github項目。然後就是Referee類,我們讓其也在boat上進行實例化。

public class Referee {
		
		private BoatController boat;

		public Referee(BoatController b){
			boat = b;
		}
		
		
		public int Check(CoastController fromCoast, CoastController toCoast, BoatController boat)
		{
			int from_priest = 0;
			int from_devil = 0;
			int to_priest = 0;
			int to_devil = 0;

			int[] fromCount = fromCoast.getCharacterNum ();
			from_priest += fromCount[0];
			from_devil += fromCount[1];

			int[] toCount = toCoast.getCharacterNum ();
			to_priest += toCount[0];
			to_devil += toCount[1];

			if (to_priest + to_devil == 6)		// win
				return 2;

			int[] boatCount = boat.getCharacterNum ();
			if (boat.get_to_or_from () == -1) {	// boat at toCoast
				to_priest += boatCount[0];
				to_devil += boatCount[1];
			} else {	// boat at fromCoast
				from_priest += boatCount[0];
				from_devil += boatCount[1];
			}
			if (from_priest < from_devil && from_priest > 0) {		// lose
				return 1;
			}
			if (to_priest < to_devil && to_priest > 0) {
				return 1;
			}
			return 0;			// not finish
		}
	}

這裏我還添加了天空盒,最終的實現效果如圖所示。因爲遊戲過程和之前的版本一樣,只是代碼的架構稍有變化,所以這裏就不再上傳一個視頻了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章