前言
故事開始之先想先讓各位認識一下 2D Isometric Game,我想起兩個比較有名的遊戲:世紀帝國II和暗黑破壞神II其實它們是用了Isometric Tiled Map 就是用2D去模仿3D的感覺,例如你看下圖的地圖,每一個正方體(Cube)看似立體:
每一個正方體都是平面(2D)的!只是畫出來好像立體(3D)~
你看到的地圖其實只是一張平面的畫~以前是怎樣將一用2D的素材去模仿3D的環境?就像我們怎樣畫畫是怎樣畫出立體的感覺?
這就要說起透視投影(Perspective projection)和平行投影(Parallel projection),而Isometric Game用的是等軸測投影(Isometric Projection),這是源自Parallel projection
簡單點說就是假設光線是平行,物件不會因為遠了而縮小但也產生了3D的感覺
如果引發了大家對Isometric Projection/Game 興趣的話,可以參考一下以下網址
Isometric game 及譯法漫談:http://www.ituring.com.cn/article/788
或是問問偉大的Google大神!
插件介紹
好了故事開始了,事源是小弟要弄一個回合制的2D遊戲,有一天在Asset Store找到一個畫得好漂亮的Isometric Tile,而且還有小弟想用的六角形版本(Hexagonal)Golden Skull Studio出品的Tiles:
Hexagonal: https://www.assetstore.unity3d.com/en/#!/content/37170
Isometric Tile: https://www.assetstore.unity3d.com/en/#!/content/27944
然後想起之前買了GameLogic的Grids Pro
Grids Pro:https://www.assetstore.unity3d.com/en/#!/content/9968
希望可以用Isometric Tile 和Grids Pro 是開發這款遊戲~
可是,因為每一個Isometric Tile其實只是一個平面,用它們砌地圖的話會有重疊,配合Grids Pro的坐標系統比較麻煩(就是要自己計數呀~),或是地圖跟坐標是分開的,只是再把它們拼湊一齊......
就在我苦惱的時候,有天Gamelogic的大大們終於把它們合體了!
http://gamelogic.co.za/grids/golden-skull-studio-extension-for-grids/
好感動呀!!!它們真的計出來了!!!
然後就跟住以上網址的指示,把Grids Pro和Isometric Tile/Hexagonal 兩插件, GoldenSkullGridExtensions.unitypackage 戴入到專案就可以了~
順帶一提記得把所有Tiles的Pixels Per Unit設定為1 !
Package裏還提供Random, Patten 跟Height 三款地圖,不過暫時不先對它們再作研究
實現物件在地圖上移動
然後就想先試試讓物件在地圖上移動
首先,要給這個物件(Player)記住自己的位置:
public class Player : MonoBehaviour {
private FlatHexPoint _currentPointLocation;
public FlatHexPoint CurrentPointLocation
{
get;
set;
}
}
然後在遊戲開之先把Player的坐標位置設定為(0,0)
void Start () {
player.CurrentPointLocation = FlatHexPoint.Zero;
player.transform.position = new Vector3(Map[player.CurrentPointLocation].x, Map[player.CurrentPointLocation].y);
start = player.CurrentPointLocation;
}
public void OnClick(FlatHexPoint point)
{
Debug.Log (point.BasePoint); //return (x,y)
if(player.CurrentPointLocation != null)
{
start = player.CurrentPointLocation;
finish = point;
StartCoroutine(Move(start, finish));
}
}
然後就是要物件在實際的地圖的移動
public IEnumerator Move(FlatHexPoint currentPoint, FlatHexPoint endPoint){
float time = 0;
const float totalTime = .3f;
while (time < totalTime)
{
float x = Mathf.Lerp(Map[currentPoint].x, Map[endPoint].x, time / totalTime);
float y = Mathf.Lerp(Map[currentPoint].y, Map[endPoint].y, time / totalTime);
y -= 20;
player.transform.position = new Vector3(x, y);
time += Time.deltaTime;
}
player.CurrentPointLocation = endPoint;
yield return null;
}
然後就變成這樣了:
不知大家有沒有發現有甚麽問題?
無錯!比卡超其實不是逐格移動然後去到目標格,牠只是飄去目標格~
所以我們要用到Path-finding這東西,就是要格與格之間的最快路線:
http://gamelogic.co.za/grids/documentation-contents/quick-start-tutorial/path-finding-grids-for-unity/
無錯!比卡超其實不是逐格移動然後去到目標格,牠只是飄去目標格~
所以我們要用到Path-finding這東西,就是要格與格之間的最快路線:
http://gamelogic.co.za/grids/documentation-contents/quick-start-tutorial/path-finding-grids-for-unity/
Grids Pro 好用的地方就是讓很多代碼變得簡單易明,我們這要把開始點(start)和終點(finish)放進AStar裏就會出現路線了:
var path = Algorithms.AStar(Grid, start, finish);
拿了路線之後我們先建立MovePath這個function, 它會再call 我們剛才弄好的Move(FlatHexPoint currentPoint, FlatHexPoint endPoint) 讓比卡超逐格移動!
if(player.CurrentPointLocation != null)
{
start = player.CurrentPointLocation;
finish = point;
var path = Algorithms.AStar(Grid, start, finish);
StartCoroutine(MovePath(path));
}
public IEnumerator MovePath(IEnumerable path)
{
var pathList = path.ToList();
if(pathList.Count < 2) yield break; //Not a valid path
for(int i = 0; i < pathList.Count - 1; i++)
{
yield return StartCoroutine(Move (pathList[i], pathList[i+1]));
}
}
不知大家有沒有留意地圖在下雨!其實這是之前減價看上了的插件:
https://www.assetstore.unity3d.com/en/#!/content/33229
漂亮的東西總讓人忍不住買下來~
Map 是什么呀
回覆刪除求代码参考下
刪除Map是Grids Pro library裏的,會回傳物件實際的位置
刪除例如player.CurrentPointLocation是player的坐標,假設是(0,0)吧, 但我們不知道坐標(0,0)在環境上的位置(就是指transform裏的position)所以用Map
Map[player.CurrentPointLocation]就知道(0.0)的x,y,z是(-573,240,0)了
少年,真土豪!你这一篇下来买了不少插件
回覆刪除那時常常逛Asset Store留意特價~特價來了就忍王住買下來 XD
刪除