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