ããŒã1ã3ïŒã°ãªãããè²ãã»ã«ã®é«ãããŒã4ã7ïŒç²ããå·ãããã³éè·¯ããŒã8-11ïŒæ°Žãå°åœ¢ãåå£ããŒã12ã15ïŒä¿åãšèªã¿èŸŒã¿ããã¯ã¹ãã£ãè·é¢ããŒã16ã19ïŒéãèŠã€ããããã¬ã€ã€ãŒããŒã ãã¢ãã¡ãŒã·ã§ã³ããŒã20-23ïŒæŠäºã®é§ãå°å³èª¿æ»ãæç¶ãçæããŒã24ã27ïŒæ°ŽåŸªç°ã䟵é£ããã€ãªãŒã ãåæ±å°å³ããŒã12ïŒä¿åãšèªã¿èŸŒã¿
- è²ã§ã¯ãªãå°åœ¢ã®ã¿ã€ãã远跡ããŸãã
- ãã¡ã€ã«ãäœæããŸãã
- ããŒã¿ããã¡ã€ã«ã«æžã蟌ãã§ããèªã¿åããŸãã
- ã»ã«ããŒã¿ãã·ãªã¢ã«åããŸãã
- ãã¡ã€ã«ãµã€ãºãå°ããããŠãã ããã
ããªãè峿·±ãããããäœæããæ¹æ³ã¯ãã§ã«ç¥ã£ãŠããŸãã ä»ãããªãã¯ããããä¿åããæ¹æ³ãåŠã¶å¿
èŠããããŸãã
test.mapãã¡ã€ã«ããããŒããããŸããå°åœ¢ã¿ã€ã
å°å³ãä¿åãããšããã¢ããªã±ãŒã·ã§ã³äžã«è¿œè·¡ãããã¹ãŠã®ããŒã¿ãä¿åããå¿
èŠã¯ãããŸããã ããšãã°ãã»ã«ã®é«ãã¬ãã«ãèŠããã ãã§ãã ãã®åçŽäœçœ®èªäœã¯ãã®ããŒã¿ããååŸããããããä¿åããå¿
èŠã¯ãããŸããã å®éããããã®èšç®ãããææšãä¿åããªãæ¹ãè¯ãã§ãã ãããã£ãŠãåŸã§é«ããªãã»ããã倿Žããããšã«ããå Žåã§ãããããããŒã¿ã¯æ£ãããŸãŸã§ãã ããŒã¿ã¯ãã¬ãŒã³ããŒã·ã§ã³ãšã¯å¥ã®ãã®ã§ãã
åæ§ã«ãã»ã«ã®æ£ç¢ºãªè²ãä¿åããå¿
èŠã¯ãããŸããã ã»ã«ãç·è²ã§ããããšãæžãããšãã§ããŸãã ããããèŠèŠã¹ã¿ã€ã«ãå€ãããšãæ£ç¢ºãªç·ã®è²åããå€ããå¯èœæ§ããããŸãã ãããè¡ãããã«ãè²ãã®ãã®ã§ã¯ãªããè²ã®ã€ã³ããã¯ã¹ãä¿åã§ããŸãã å®éãå®è¡æã«ã»ã«ã«å®éã®è²ã®ä»£ããã«ãã®ã€ã³ããã¯ã¹ãä¿åããã°ååãããããŸããã ããã«ãããåŸã§ã¬ãªãŒãã®ããè€éãªèŠèŠåã«é²ãããšãã§ããŸãã
è²ã®é
åãç§»åãã
ã»ã«ã«ã«ã©ãŒããŒã¿ããªããªã£ãå Žåã¯ãå¥ã®å Žæã«ä¿åããå¿
èŠããããŸãã
HexMetrics
ã«ä¿åããã®ãæã䟿å©
HexMetrics
ã è²ã®é
åã远å ããŠã¿ãŸãããã
public static Color[] colors;
ãã€ãºãªã©ã®ä»ã®ãã¹ãŠã®ã°ããŒãã«ããŒã¿ãšåæ§ã«ããããã®è²ã
HexGrid
åæåã§ããŸãã
public Color[] colors; ⊠void Awake () { HexMetrics.noiseSource = noiseSource; HexMetrics.InitializeHashGrid(seed); HexMetrics.colors = colors; ⊠} ⊠void OnEnable () { if (!HexMetrics.noiseSource) { HexMetrics.noiseSource = noiseSource; HexMetrics.InitializeHashGrid(seed); HexMetrics.colors = colors; } }
ãŸããã»ã«ã«çŽæ¥è²ãå²ãåœãŠãªãã®ã§ãããã©ã«ãã®è²ãåãé€ããŸãã
å
è§ããããšãã£ã¿ãŒã®äžè¬çãªé
åã«äžèŽããããã«æ°ããè²ãèšå®ããŸãã
ã°ãªããã«è¿œå ãããè²ãã»ã«ãªãã¡ã¯ã¿ãªã³ã°
HexCell
ããã«ã©ãŒãã£ãŒã«ããåé€ããŸãã 代ããã«ãã€ã³ããã¯ã¹ãä¿åããŸãã ã«ã©ãŒã€ã³ããã¯ã¹ã®ä»£ããã«ãããäžè¬çãªã¬ãªãŒãã¿ã€ãã€ã³ããã¯ã¹ã䜿çšããŸãã
colorããããã£ã¯ã察å¿ããè²ãååŸããããã«ã®ã¿ãã®ã€ã³ããã¯ã¹ã䜿çšã§ããŸãã çŸåšã¯çŽæ¥èšå®ãããŠããªãããããã®éšåãåé€ããŸãã ãã®å Žåãã³ã³ãã€ã«ãšã©ãŒãçºçããŸãããããã«ä¿®æ£ããŸãã
public Color Color { get { return HexMetrics.colors[terrainTypeIndex]; }
æ°ããããããã£ã远å ããŠãæ°ããæšé«ã¿ã€ãã®ã€ã³ããã¯ã¹ãååŸããã³èšå®ããŸãã
public int TerrainTypeIndex { get { return terrainTypeIndex; } set { if (terrainTypeIndex != value) { terrainTypeIndex = value; Refresh(); } } }
ãšãã£ã¿ãŒã®ãªãã¡ã¯ã¿ãªã³ã°
HexMapEditor
å
ã§ãè²ã«é¢ãããã¹ãŠã®ã³ãŒã
HexMapEditor
åé€ããŸãã ããã«ãããã³ã³ãã€ã«ãšã©ãŒãä¿®æ£ãããŸãã
次ã«ãã¢ã¯ãã£ããªæšé«ã¿ã€ãã€ã³ããã¯ã¹ãå¶åŸ¡ãããã£ãŒã«ããšã¡ãœããã远å ããŸãã
int activeTerrainTypeIndex; ⊠public void SetTerrainTypeIndex (int index) { activeTerrainTypeIndex = index; }
ãã®ã¡ãœããã¯ãçŸå𿬠èœããŠãã
SelectColor
ã¡ãœããã®ä»£ãããšããŠäœ¿çšããŸãã UIã®ã«ã©ãŒãŠã£ãžã§ããã
SetTerrainTypeIndex
ã§æ¥ç¶ããä»ã®ãã¹ãŠã倿ŽããªããŸãŸã«ããŸãã ããã¯ãè² ã®ã€ã³ããã¯ã¹ããŸã 䜿çšäžã§ãããè²ãå€ãããªãããšãæå³ããŸãã
ç·šéã»ã«ã倿ŽããŠãç·šéäžã®ã»ã«ã«æšé«ã¿ã€ãã®ã€ã³ããã¯ã¹ãå²ãåœãŠãŸãã
void EditCell (HexCell cell) { if (cell) { if (activeTerrainTypeIndex >= 0) { cell.TerrainTypeIndex = activeTerrainTypeIndex; } ⊠} }
ã»ã«ããè²ããŒã¿ãåé€ããŸãããããããã¯ä»¥åãšåãããã«æ©èœããã¯ãã§ãã å¯äžã®éãã¯ãããã©ã«ãã®è²ãé
åã®æåã«ãªã£ãããšã§ãã ç§ã®å Žåã¯é»è²ã§ãã
é»è²ãæ°ããããã©ã«ãã®è²ã§ãããŠããã£ããã±ãŒãžããŒã¿ããã¡ã€ã«ã«ä¿åãã
ãããã®ä¿åãšèªã¿èŸŒã¿ãå¶åŸ¡ããã«ã¯ã
HexMapEditor
ã䜿çšã
HexMapEditor
ã ãããè¡ã2ã€ã®ã¡ãœãããäœæããä»ã¯ç©ºã®ãŸãŸã«ããŸãã
public void Save () { } public void Load () { }
UIã«2ã€ã®ãã¿ã³ã远å ããŸãïŒ
GameObject / UI / Button ïŒã ãããããã¿ã³ã«æ¥ç¶ããé©åãªã©ãã«ãä»ããŸãã ããããå³ããã«ã®äžéšã«é
眮ããŸããã
[ä¿å]ãã¿ã³ãš[èªã¿èŸŒã¿]ãã¿ã³ããã¡ã€ã«ã®å Žæ
ã«ãŒããä¿åããã«ã¯ãã©ããã«ä¿åããå¿
èŠããããŸãã ã»ãšãã©ã®ã²ãŒã ã§è¡ãããŠããããã«ããã¡ã€ã«ã«ããŒã¿ãä¿åããŸãã ãããããã®ãã¡ã€ã«ããã¡ã€ã«ã·ã¹ãã ã®ã©ãã«çœ®ãã®ã§ããããïŒ çãã¯ãã²ãŒã ãå®è¡ãããŠãããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã«ãã£ãŠç°ãªããŸãã åOSã«ã¯ãã¢ããªã±ãŒã·ã§ã³ã«é¢é£ãããã¡ã€ã«ãä¿åããããã®ç¬èªã®æšæºããããŸãã
ãããã®æšæºãç¥ãå¿
èŠã¯ãããŸããã Unityã¯ã
Application.persistentDataPath
ååŸã§ããæ£ãããã¹ãç¥ã£ãŠã
Application.persistentDataPath
ã
Save
ã¡ãœããã§ãã³ã³ãœãŒã«ã«è¡šç€ºããPlayã¢ãŒãã§ãã¿ã³ãæŒããšãã©ã®ããã«ãªããã確èªã§ããŸãã
public void Save () { Debug.Log(Application.persistentDataPath); }
ãã¹ã¯ãããã·ã¹ãã ã§ã¯ããã¹ã«ã¯äŒç€Ÿãšè£œåã®ååãå«ãŸããŸãã ãšãã£ã¿ãŒãšã¢ã»ã³ããªã®äž¡æ¹ããã®ãã¹ã䜿çšããŸãã ååã¯ã
ç·šé/ãããžã§ã¯ãèšå®/ãã¬ãŒã€ãŒã§èšå®ã§ããŸãã
äŒç€Ÿãšè£œåã®ååãMacã§ã©ã€ãã©ãªãã©ã«ããŒãèŠã€ãããªãã®ã¯ãªãã§ããïŒå€ãã®å Žåã ã©ã€ãã©ãªãã©ã«ããŒã¯é衚瀺ã§ãã è¡šç€ºæ¹æ³ã¯OS Xã®ããŒãžã§ã³ã«ãã£ãŠç°ãªããŸããå€ãããŒãžã§ã³ããªãå Žåã¯ãFinderã§ããŒã ãã©ã«ããŒãéžæãã[ 衚瀺ãªãã·ã§ã³ã衚瀺]ã«é²ã¿ãŸã ã ã©ã€ãã©ãªãã©ã«ãã®ãã§ãã¯ããã¯ã¹ããããŸãã
WebGLã¯ã©ãã§ããïŒWebGLã²ãŒã ã¯ãŠãŒã¶ãŒã®ãã¡ã€ã«ã·ã¹ãã ã«ã¢ã¯ã»ã¹ã§ããŸããã 代ããã«ããã¹ãŠã®ãã¡ã€ã«æäœãã¡ã¢ãªå
ã«ãããã¡ã€ã«ã·ã¹ãã ã«ãªãã€ã¬ã¯ããããŸãã 圌女ã¯ç§ãã¡ã«éæã§ãã ãã ããããŒã¿ãä¿åããã«ã¯ãWebããŒãžãæåã§æ³šæããŠããã©ãŠã¶ã¹ãã¬ãŒãžã«ããŒã¿ããã³ãããå¿
èŠããããŸãã
ãã¡ã€ã«äœæ
ãã¡ã€ã«ãäœæããã«ã¯ã
System.IO
åå空éã®ã¯ã©ã¹ã䜿çšããå¿
èŠããããŸãã ãããã£ãŠã
HexMapEditor
ã¯ã©ã¹ã®äžã«
using
ã¹ããŒãã¡ã³ãã远å ããŸãã
using UnityEngine; using UnityEngine.EventSystems; using System.IO; public class HexMapEditor : MonoBehaviour { ⊠}
ãŸãããã¡ã€ã«ãžã®ãã«ãã¹ãäœæããå¿
èŠããããŸãã ãã¡ã€ã«
åãšããŠ
test.mapã䜿çšããŸãã ä¿åãããããŒã¿ã®ãã¹ã«è¿œå ããå¿
èŠããããŸãã ã¹ã©ãã·ã¥ãŸãã¯ããã¯ã¹ã©ãã·ã¥ïŒã¹ã©ãã·ã¥ãŸãã¯ããã¯ã¹ã©ãã·ã¥ïŒãæ¿å
¥ããå¿
èŠããããã©ããã¯ããã©ãããã©ãŒã ã«ãã£ãŠç°ãªããŸãã
Path.Combine
ã¡ãœããã
Path.Combine
ã
Path.Combine
ã
public void Save () { string path = Path.Combine(Application.persistentDataPath, "test.map"); }
次ã«ããã®å Žæã«ãããã¡ã€ã«ã«ã¢ã¯ã»ã¹ããå¿
èŠããããŸãã ããã¯
File.Open
ã¡ãœããã䜿çšããŠ
File.Open
ãŸãã ãã®ãã¡ã€ã«ã«ããŒã¿ãæžã蟌ããããäœæã¢ãŒãã䜿çšããå¿
èŠããããŸãã ãã®å Žåãæå®ãããã¹ã«æ°ãããã¡ã€ã«ãäœæãããããæ¢åã®ãã¡ã€ã«ã眮ãæããããŸãã
string path = Path.Combine(Application.persistentDataPath, "test.map"); File.Open(path, FileMode.Create);
ãã®ã¡ãœãããåŒã³åºããçµæã¯ããã®ãã¡ã€ã«ã«é¢é£ä»ãããããªãŒãã³ããŒã¿ã¹ããªãŒã ã«ãªããŸãã ããã䜿çšããŠãããŒã¿ããã¡ã€ã«ã«æžã蟌ãããšãã§ããŸãã ãããŠãã¹ããªãŒã ãäžèŠã«ãªã£ããšãã«éããããšãå¿ããŠã¯ãªããŸããã
string path = Path.Combine(Application.persistentDataPath, "test.map"); Stream fileStream = File.Open(path, FileMode.Create); fileStream.Close();
ãã®æ®µéã§[
ä¿å ]ãã¿ã³ãã¯ãªãã¯ãããšã
ä¿åãããããŒã¿ãžã®ãã¹ãšããŠæå®ããããã©ã«ããŒã«
test.mapãã¡ã€ã«ãäœæãããŸãã ãã®ãã¡ã€ã«ã調ã¹ããšã空ã«ãªãããµã€ãºã0ãã€ãã«ãªããŸãããããŸã§ã®ãšããäœãæžã蟌ãã§ããŸããã
ãã¡ã€ã«ã«æžã蟌ã
ãã¡ã€ã«ã«ããŒã¿ãæžã蟌ãã«ã¯ãããŒã¿ãã¹ããªãŒãã³ã°ããæ¹æ³ãå¿
èŠã§ãã ãããè¡ãæãç°¡åãªæ¹æ³ã¯ã
BinaryWriter
ã§ãã ãããã®ãªããžã§ã¯ãã䜿çšãããšãããªããã£ãããŒã¿ãä»»æã®ã¹ããªãŒã ã«æžã蟌ãããšãã§ããŸãã
æ°ãã
BinaryWriter
ãªããžã§ã¯ããäœæãããšããã¡ã€ã«ã¹ããªãŒã ãåŒæ°ã«ãªããŸãã ã©ã€ã¿ãŒãéãããšã䜿çšããã¹ã¬ãããéããããŸãã ãããã£ãŠãã¹ããªãŒã ãžã®çŽæ¥ãªã³ã¯ãä¿åããå¿
èŠããªããªããŸããã
string path = Path.Combine(Application.persistentDataPath, "test.map"); BinaryWriter writer = new BinaryWriter(File.Open(path, FileMode.Create)); writer.Close();
ããŒã¿ãã¹ããªãŒã ã«è»¢éããã«ã¯ã
BinaryWriter.Write
ã¡ãœããã䜿çšã§ããŸãã æŽæ°ãæµ®åå°æ°ç¹æ°ãªã©ããã¹ãŠã®ããªããã£ãåã«å¯ŸããŠ
Write
ã¡ãœããã®ããªã¢ã³ãããããŸãã è¡ãèšé²ããããšãã§ããŸãã æŽæ°123ãæžããŸãããã
BinaryWriter writer = new BinaryWriter(File.Open(path, FileMode.Create)); writer.Write(123); writer.Close();
[
ä¿å ]ãã¿ã³ãã¯ãªãã¯ããŠã
test.mapãããäžåºŠèª¿ã¹
ãŸã ã æŽæ°ãµã€ãºã4ãã€ãã§ããããããµã€ãºã¯4ãã€ãã«ãªããŸããã
ãã¡ã€ã«ãããŒãžã£ãŒãããã¡ã€ã«ãããå€ãã®ã¹ããŒã¹ãå æããããšã瀺ãã®ã¯ãªãã§ããïŒãã¡ã€ã«ã·ã¹ãã ã¯ã¹ããŒã¹ããã€ããããã¯ã«åå²ããããã§ãã åã
ã®ãã€ãã远跡ããŸããã test.mapã¯ãããŸã§4ãã€ããã䜿çšããªãããã1ãããã¯ã®ã¹ãã¬ãŒãžã¹ããŒã¹ãå¿
èŠã§ãã
人éãèªããããã¹ãã§ã¯ãªãããã€ããªããŒã¿ãæ ŒçŽããããšã«æ³šæããŠãã ããã ãããã£ãŠãããã¹ããšãã£ã¿ãŒã§ãã¡ã€ã«ãéããšãäžæçãªæåã®ã»ããã衚瀺ãããŸãã ããããã·ã³ãã«
{ã«ç¶ããŠãäœããªããã¬ãŒã¹ãã«ããŒãããã€ã衚瀺ãããŸãã
16é²ãšãã£ã¿ãŒã§ãã¡ã€ã«ãéãããšãã§ããŸãã ãã®å Žåã
7b 00 00 00ã衚瀺ãããŸãã ãããã¯16é²è¡šèšã§ãããã³ã°ããã4ãã€ãã®æŽæ°ã§ãã éåžžã®10鲿°ã§ã¯ãããã¯
123 0 0 0ã§ãã ãã€ããªã§ã¯ãæåã®ãã€ãã¯
01111011ã®ããã«
ãªããŸãã
{ã®ASCIIã³ãŒãã¯123ã§ããããããã®æåã¯ããã¹ããšãã£ã¿ãŒã§è¡šç€ºã§ããŸãã ASCII 0ã¯ã衚瀺ãããæåãšäžèŽããªããã«æåã§ãã
æ®ãã®3ãã€ãã¯ã256æªæºã®æ°åãæžã蟌ãã ããããŒãã«çãããªããŸãã256ãæžã蟌ãã å Žåã16é²ãšãã£ã¿ãŒã«
00 01 00 00ã衚瀺ãããŸãã
123ã¯00 00 00 7bãšããŠä¿åãããã¹ãã§ã¯ãããŸãããïŒBinaryWriter
ã¯ããªãã«ãšã³ãã£ã¢ã³åœ¢åŒã䜿çšããŠæ°å€ãä¿åããŸãã ã€ãŸããæäžäœãã€ããæåã«æžã蟌ãŸããŸãã ãã®åœ¢åŒã¯ãMicrosoftã.Netãã¬ãŒã ã¯ãŒã¯ã®éçºã«äœ¿çšãããã®ã§ãã Intel CPUããªãã«ãšã³ãã£ã¢ã³åœ¢åŒã䜿çšããŠãããããããããéžæãããŸããã
ããã«ä»£ãããã®ã¯ããã°ãšã³ãã£ã¢ã³ã§ãæäžäœãã€ããæåã«ä¿åãããŸãã ããã¯ãæ°åã®éåžžã®æ°åã®é åºã«å¯Ÿå¿ããŸãã 123ã¯ããã°ãšã³ãã£ã¢ã³ã¬ã³ãŒããæå³ããããã123ã§ãã ãªãã«ãšã³ãã£ã¢ã³ã®å Žåã123ã¯312ãæå³ããŸãã
ãªãœãŒã¹ãè§£æŸãã
äœå®¶ãéããããšãéèŠã§ãã ãã¡ã€ã«ã·ã¹ãã ãéããŠããéããã¡ã€ã«ã·ã¹ãã ã¯ãã¡ã€ã«ãããã¯ããä»ã®ããã»ã¹ããã¡ã€ã«ã«æžã蟌ã¿ã§ããªãããã«ããŸãã ãããéããã®ãå¿ãããšãèªåèªèº«ããããã¯ããŸãã ä¿åãã¿ã³ã2åæŒããšã2åç®ã¯ã¹ããªãŒã ãéãããšãã§ããŸããã
ã©ã€ã¿ãŒãæåã§éãã代ããã«ããã®ããã«
using
ãããã¯ãäœæã§ããŸãã ã©ã€ã¿ãŒãæå¹ãªç¯å²ãå®çŸ©ããŸãã å®è¡å¯èœã³ãŒãããã®ç¯å²ãè¶
ãããšãã©ã€ã¿ãŒãåé€ãããã¹ã¬ãããéããããŸãã
using ( BinaryWriter writer = new BinaryWriter(File.Open(path, FileMode.Create)) ) { writer.Write(123); }
ããã¯ãã©ã€ã¿ãŒã¯ã©ã¹ãšãã¡ã€ã«ã¹ããªãŒã ã¯ã©ã¹ã
IDisposable
ã€ã³ã¿ãŒãã§ã€ã¹ãå®è£
ããŠããããæ©èœããŸãã ãããã®ãªããžã§ã¯ãã«ã¯
Dispose
ã¡ãœããããããŸãããã®ã¡ãœããã¯ã
using
ã®ç¯å²å€ã«ãªããšéæ¥çã«åŒã³åºãããŸãã
䜿çšã®å€§ããªå©ç¹ã¯ãããã°ã©ã ãã©ã®ããã«ã¹ã³ãŒãå€ã§å®è¡ãããŠãåäœããããšã§ãã æ©æã®è¿åãäŸå€ããšã©ãŒã¯åœŒãæ©ãŸããŸããã ããã«ã圌ã¯éåžžã«ç°¡æœã§ãã
ããŒã¿æ€çŽ¢
以åã«æžã蟌ãŸããããŒã¿ãèªã¿åãã«ã¯ã
Load
ã¡ãœããã«ã³ãŒããæ¿å
¥ããå¿
èŠããããŸãã ä¿åã®å Žåãšåæ§ã«ããã¹ãäœæããŠãã¡ã€ã«ã¹ããªãŒã ãéãå¿
èŠããããŸãã éãã¯ããã¡ã€ã«ãæžã蟌ã¿çšã§ã¯ãªãèªã¿åãçšã«éãããšã§ãã ãããŠãã©ã€ã¿ãŒã®ä»£ããã«
BinaryReader
ãå¿
èŠã§ãã
public void Load () { string path = Path.Combine(Application.persistentDataPath, "test.map"); using ( BinaryReader reader = new BinaryReader(File.Open(path, FileMode.Open)) ) { } }
ãã®å Žåã
File.OpenRead
ã¡ãœããã䜿çšããŠãèªã¿åãçšã«ãã¡ã€ã«ãéãããšãã§ããŸãã
using (BinaryReader reader = new BinaryReader(File.OpenRead(path))) { }
æžãèŸŒã¿æã«File.OpenWriteã䜿çšã§ããªãã®ã¯ãªãã§ããïŒãã®ã¡ãœããã¯ãæ¢åã®ãã¡ã€ã«ã眮ãæããã®ã§ã¯ãªããæ¢åã®ãã¡ã€ã«ã«ããŒã¿ã远å ããã¹ããªãŒã ãäœæããŸãã
èªã¿åãæã«ã¯ãåä¿¡ããããŒã¿ã®ã¿ã€ããæç€ºçã«ç€ºãå¿
èŠããããŸãã ã¹ããªãŒã ããæŽæ°ãèªã¿åãã«ã¯ã
BinaryReader.ReadInt32
ã䜿çšããå¿
èŠã
BinaryReader.ReadInt32
ãŸãã ãã®ã¡ãœããã¯ã32ãããæŽæ°ãã€ãŸã4ãã€ããèªã¿åããŸãã
using (BinaryReader reader = new BinaryReader(File.OpenRead(path))) { Debug.Log(reader.ReadInt32()); }
123ãåä¿¡ãããš
ã 1ãã€ããèªã¿åãã ãã§ååã§ããããšã«æ³šæããŠãã ããã ãã ããåæã«ããã®æŽæ°ã«å±ãã3ãã€ããã¹ããªãŒã ã«æ®ããŸãã ãŸããããã¯ã0ã255ã®ç¯å²å€ã®æ°å€ã§ã¯æ©èœããŸããã ãããã£ãŠãããããªãã§ãã ããã
ãŠããã£ããã±ãŒãžå°å³ããŒã¿ã®æžã蟌ã¿ãšèªã¿åã
ããŒã¿ãä¿åããéã®éèŠãªè³ªåã¯ã人éãèªãã圢åŒã䜿çšãããã©ããã§ãã éåžžã人éãèªãã圢åŒã§ã¯ãJSONãXMLãããã³äœããã®æ§é ã®ãã¬ãŒã³ASCIIã䜿çšããŸãã ãã®ãããªãã¡ã€ã«ã¯ãããã¹ããšãã£ã¿ãŒã§éããããè§£éããããç·šéãããã§ããŸãã ããã«ãç°ãªãã¢ããªã±ãŒã·ã§ã³éã®ããŒã¿äº€æãç°¡çŽ åããŸãã
ãã ãããã®ãããªåœ¢åŒã«ã¯ç¬èªã®èŠä»¶ããããŸãã ãã¡ã€ã«ã¯ããã€ããªããŒã¿ã䜿çšãããããå€ãã®ã¹ããŒã¹ïŒå Žåã«ãã£ãŠã¯ãã以äžïŒãå æããŸãã ãŸããã©ã³ã¿ã€ã ãšã¡ã¢ãªãããããªã³ãã®äž¡æ¹ã®ç¹ã§ãããŒã¿ã®ãšã³ã³ãŒããšãã³ãŒãã®ã³ã¹ãã倧å¹
ã«å¢å ãããå¯èœæ§ããããŸãã
察ç
§çã«ããã€ããªããŒã¿ã¯ã³ã³ãã¯ãã§é«éã§ãã ããã¯ã倧éã®ããŒã¿ãèšé²ããå Žåã«éèŠã§ãã ããšãã°ãã²ãŒã ã®åã¿ãŒã³ã§å€§ããªããããèªåä¿åããå Žåã ã ãã
ãã€ããªåœ¢åŒã䜿çšããŸãã ãããåŠçã§ããã°ããã詳现ãªåœ¢åŒã§äœæ¥ã§ããŸãã
èªåã·ãªã¢ã«åã¯ã©ãã§ããïŒUnityããŒã¿ãã·ãªã¢ã«åããããã»ã¹ã®çŽåŸã«ãã·ãªã¢ã«åãããã¯ã©ã¹ãã¹ããªãŒã ã«çŽæ¥æžã蟌ãããšãã§ããŸãã åã
ã®ãã£ãŒã«ãã®èšé²ã®è©³çްã¯é衚瀺ã«ãªããŸãã ãã ããã»ã«ãçŽæ¥ã·ãªã¢ã«åããããšã¯ã§ããŸããã ãããã¯ä¿åããå¿
èŠã®ãªãããŒã¿ãå«ãMonoBehaviour
ã¯ã©ã¹ã§ãã ãããã£ãŠããªããžã§ã¯ãã®å¥ã®éå±€ã䜿çšããå¿
èŠããããŸãããããã¯èªåã·ãªã¢ã«åã®åçŽããç Žå£ããŸãã ããã«ãå°æ¥ã®ã³ãŒã倿ŽããµããŒãããããšã¯ããå°é£ã«ãªããŸãã ãããã£ãŠãæåã®ã·ãªã¢ã«åã§å®å
šãªå¶åŸ¡ãç¶æããŸãã ããã«ãäœãèµ·ãã£ãŠããã®ããæ¬åœã«çè§£ãããŠãããŸãã
ããããã·ãªã¢ã«åããã«ã¯ãåã»ã«ã®ããŒã¿ãä¿åããå¿
èŠããããŸãã åäžã®ã»ã«ãä¿åããã³ããŒãããã«ã¯ã
Save
ããã³
Load
ã¡ãœããã
HexCell
远å ã
Save
ã ã©ã€ã¿ãŒãŸãã¯ãªãŒããŒãå¿
èŠãªããããã©ã¡ãŒã¿ãŒãšããŠè¿œå ããŸãã
using UnityEngine; using System.IO; public class HexCell : MonoBehaviour { ⊠public void Save (BinaryWriter writer) { } public void Load (BinaryReader reader) { } }
Save
ããã³
Load
ã¡ãœããã
HexGrid
远å ã
Save
ã ãããã®ã¡ãœããã¯ã
Load
ã¡ãœãããš
Save
ã¡ãœãããåŒã³åºãããšã«ããããã¹ãŠã®ã»ã«ãåçŽã«ãã€ãã¹ã
Save
ã
using UnityEngine; using UnityEngine.UI; using System.IO; public class HexGrid : MonoBehaviour { ⊠public void Save (BinaryWriter writer) { for (int i = 0; i < cells.Length; i++) { cells[i].Save(writer); } } public void Load (BinaryReader reader) { for (int i = 0; i < cells.Length; i++) { cells[i].Load(reader); } } }
ããããããŠã³ããŒãããå Žåãã»ã«ããŒã¿ã倿ŽãããåŸã«ããããæŽæ°ããå¿
èŠããããŸãã ãããè¡ãã«ã¯ããã¹ãŠã®ãã©ã°ã¡ã³ããæŽæ°ããã ãã§ãã
public void Load (BinaryReader reader) { for (int i = 0; i < cells.Length; i++) { cells[i].Load(reader); } for (int i = 0; i < chunks.Length; i++) { chunks[i].Refresh(); } }
æåŸã«ã
HexMapEditor
ãã¹ãã³ãŒãããã°ãªããã®
Save
ã¡ãœãããš
Load
ã¡ãœããã®åŒã³åºãã«çœ®ãæããã©ã€ã¿ãŒãŸãã¯ãªãŒããŒãæž¡ããŸãã
public void Save () { string path = Path.Combine(Application.persistentDataPath, "test.map"); using ( BinaryWriter writer = new BinaryWriter(File.Open(path, FileMode.Create)) ) { hexGrid.Save(writer); } } public void Load () { string path = Path.Combine(Application.persistentDataPath, "test.map"); using (BinaryReader reader = new BinaryReader(File.OpenRead(path))) { hexGrid.Load(reader); } }
å°åœ¢ã¿ã€ãã®ä¿å
çŸåšã®æ®µéã§ã¯ãåä¿åã¯ç©ºã®ãã¡ã€ã«ãäœæããããŠã³ããŒãã¯äœãããŸããã
HexCell
ãšã¬ããŒã·ã§ã³ã¿ã€ãã€ã³ããã¯ã¹ã®ã¿ãèšè¿°ããã³ããŒãããããšããå§ããŸãããã
å€ãterrainTypeIndexãã£ãŒã«ãã«çŽæ¥å²ãåœãŠãŸãã ããããã£ã¯äœ¿çšããŸããã ãã¹ãŠã®ãã©ã°ã¡ã³ããæç€ºçã«æŽæ°ããããã
Refresh
ããããã£ã®åŒã³åºãã¯å¿
èŠãããŸããã ããã«ãæ£ãããããã®ã¿ãä¿åãããããããŠã³ããŒããããã¹ãŠã®ããããæ£ãããšæ³å®ããŸãã ãããã£ãŠãããšãã°ãå·ãéè·¯ãèš±å¯ãããŠãããã©ããã¯ãã§ãã¯ããŸããã
public void Save (BinaryWriter writer) { writer.Write(terrainTypeIndex); } public void Load (BinaryReader reader) { terrainTypeIndex = reader.ReadInt32(); }
ãã®ãã¡ã€ã«ã«ä¿åãããšããã¹ãŠã®ã»ã«ã®ææžã¿ã€ãã®ã€ã³ããã¯ã¹ã次ã
ãšæžã蟌ãŸããŸãã ã€ã³ããã¯ã¹ã¯æŽæ°ãªã®ã§ããµã€ãºã¯4ãã€ãã§ãã ç§ã®ã«ãŒãã«ã¯300åã®ã»ã«ãå«ãŸããŠããŸããã€ãŸãããã¡ã€ã«ãµã€ãºã¯1200ãã€ãã«ãªããŸãã
ããŒãã¯ãã€ã³ããã¯ã¹ãæžã蟌ãŸããã®ãšåãé åºã§ã€ã³ããã¯ã¹ãèªã¿åããŸãã ä¿ååŸã«ã»ã«ã®è²ã倿Žããå ŽåãããããããŒããããšè²ãä¿åæã®ç¶æ
ã«æ»ããŸãã ããäœãä¿åããªããããæ®ãã®ã»ã«ããŒã¿ã¯åããŸãŸã§ãã ã€ãŸããããŒãã«ãã£ãŠå°åœ¢ã®ã¿ã€ãã¯å€ãããŸããããã®é«ããæ°Žäœãå°åœ¢ã®ç¹åŸŽãªã©ã¯å€ãããŸããã
ãã¹ãŠã®æŽæ°ãä¿åãã
ã¬ãªãŒãã¿ã€ãã®ã€ã³ããã¯ã¹ãä¿åããã ãã§ã¯ååã§ã¯ãããŸããã ä»ã®ãã¹ãŠã®ããŒã¿ãä¿åããå¿
èŠããããŸãã ãã¹ãŠã®æŽæ°ãã£ãŒã«ãããå§ããŸãããã ããã¯ãèµ·äŒã®ã¿ã€ããã»ã«ã®é«ããæ°Žäœãéœåžã¬ãã«ãèŸ²å Žã¬ãã«ãæ€çã¬ãã«ãããã³ç¹å¥ãªãªããžã§ã¯ãã®ã€ã³ããã¯ã¹ã®ã€ã³ããã¯ã¹ã§ãã ãããã¯ãèšé²ãããã®ãšåãé åºã§èªãå¿
èŠããããŸãã
public void Save (BinaryWriter writer) { writer.Write(terrainTypeIndex); writer.Write(elevation); writer.Write(waterLevel); writer.Write(urbanLevel); writer.Write(farmLevel); writer.Write(plantLevel); writer.Write(specialIndex); } public void Load (BinaryReader reader) { terrainTypeIndex = reader.ReadInt32(); elevation = reader.ReadInt32(); waterLevel = reader.ReadInt32(); urbanLevel = reader.ReadInt32(); farmLevel = reader.ReadInt32(); plantLevel = reader.ReadInt32(); specialIndex = reader.ReadInt32(); }
ãããã®æäœã®éã«å€æŽãå ããŠãããããä¿åããŠããŒãããŠã¿ãŠãã ããã ã»ã«ã®é«ããé€ããŠãä¿åãããããŒã¿ã«å«ãŸãããã¹ãŠã®ãã®ããå¯èœãªéã埩å
ãããŸããã ããã¯ãé«ãã¬ãã«ã倿Žãããšãã«ãã»ã«ã®åçŽäœçœ®ãæŽæ°ããå¿
èŠãããããã«çºçããŸããã ããã¯ããã£ãŒã«ãã§ã¯ãªããããŒããããé«ãã®å€ã«ããããã£ã«å²ãåœãŠãããšã§å®è¡ã§ããŸãã ãã ãããã®ããããã£ã¯å¿
èŠã®ãªã远å ã®äœæ¥ãè¡ããŸãã ãããã£ãŠãã»ã«ã®äœçœ®ãæŽæ°ããã³ãŒãã
Elevation
ã»ãã¿ãŒããæœåºããå¥ã®
RefreshPosition
ã¡ãœããã«è²Œãä»ããŸãããã ããã§ã®å¯äžã®å€æŽã¯ã
value
elevation
ãã£ãŒã«ããžã®åç
§ã«çœ®ãæããããš
value
ã
void RefreshPosition () { Vector3 position = transform.localPosition; position.y = elevation * HexMetrics.elevationStep; position.y += (HexMetrics.SampleNoise(position).y * 2f - 1f) * HexMetrics.elevationPerturbStrength; transform.localPosition = position; Vector3 uiPosition = uiRect.localPosition; uiPosition.z = -position.y; uiRect.localPosition = uiPosition; }
ããã§ãããããã£ãèšå®ãããšããããã³é«ãããŒã¿ãèªã¿èŸŒãã åŸã«ã¡ãœãããåŒã³åºãããšãã§ããŸãã
public int Elevation { ⊠set { if (elevation == value) { return; } elevation = value; RefreshPosition(); ValidateRivers(); ⊠} } ⊠public void Load (BinaryReader reader) { terrainTypeIndex = reader.ReadInt32(); elevation = reader.ReadInt32(); RefreshPosition(); ⊠}
ãã®å€æŽåŸãã»ã«ã¯ããŒãæã«èŠããã®é«ããæ£ãã倿ŽããŸãã
ãã¹ãŠã®ããŒã¿ãä¿åãã
ã»ã«å
ã®å£ãšæµå
¥/æµåºæ²³å·ã®ååšã¯ãããŒã«ãã£ãŒã«ãã«æ ŒçŽãããŸãã åçŽã«æŽæ°ãšããŠæžãããšãã§ããŸãã ããã«ãéè·¯ããŒã¿ã¯ãã«ãŒãã§æžã蟌ãããšãã§ãã6ã€ã®ããŒã«å€ã®é
åã§ãã
public void Save (BinaryWriter writer) { writer.Write(terrainTypeIndex); writer.Write(elevation); writer.Write(waterLevel); writer.Write(urbanLevel); writer.Write(farmLevel); writer.Write(plantLevel); writer.Write(specialIndex); writer.Write(walled); writer.Write(hasIncomingRiver); writer.Write(hasOutgoingRiver); for (int i = 0; i < roads.Length; i++) { writer.Write(roads[i]); } }
æµå
¥æ²³å·ãšæµåºæ²³å·ã®æ¹åã¯ã
HexDirection
ãã£ãŒã«ãã«ä¿åãããŸãã
HexDirection
åã¯ãè€æ°ã®æŽæ°å€ãšããŠå
éšçã«ä¿åãããåæã§ãã ãããã£ãŠãæç€ºçãªå€æã䜿çšããŠæŽæ°ãšããŠã·ãªã¢ã«åããããšãã§ããŸãã
writer.Write(hasIncomingRiver); writer.Write((int)incomingRiver); writer.Write(hasOutgoingRiver); writer.Write((int)outgoingRiver);
ããŒã«å€ã¯
BinaryReader.ReadBoolean
ã¡ãœããã䜿çšããŠèªã¿åãããŸãã å·ã®æ¹åã¯æŽæ°ã§ããããã
HexDirection
倿ãçŽãå¿
èŠããããŸãã
public void Load (BinaryReader reader) { terrainTypeIndex = reader.ReadInt32(); elevation = reader.ReadInt32(); RefreshPosition(); waterLevel = reader.ReadInt32(); urbanLevel = reader.ReadInt32(); farmLevel = reader.ReadInt32(); plantLevel = reader.ReadInt32(); specialIndex = reader.ReadInt32(); walled = reader.ReadBoolean(); hasIncomingRiver = reader.ReadBoolean(); incomingRiver = (HexDirection)reader.ReadInt32(); hasOutgoingRiver = reader.ReadBoolean(); outgoingRiver = (HexDirection)reader.ReadInt32(); for (int i = 0; i < roads.Length; i++) { roads[i] = reader.ReadBoolean(); } }
次ã«ããããã®å®å
šãªä¿åãšåŸ©å
ã«å¿
èŠãªãã¹ãŠã®ã»ã«ããŒã¿ãä¿åããŸãã
ããã«ã¯ãã»ã«ããšã«9ã€ã®æŽæ°ãš9ã€ã®ããŒã«å€ãå¿
èŠã§ããåããŒã«å€ã¯1ãã€ãã䜿çšãããããã»ã«ããšã«åèš45ãã€ãã䜿çšããŸããã€ãŸãã300ã»ã«ã®ã«ãŒãã«ã¯åèš13,500ãã€ããå¿
èŠã§ãããŠããã£ããã±ãŒãžãã¡ã€ã«ãµã€ãºãå°ãããã
300ã»ã«ã®å Žåã13,500ãã€ãã¯ããã»ã©å€ããªãããã«èŠããŸããããããããã£ãšå°ãªãéã§å®è¡ã§ããŸããæçµçã«ãããŒã¿ã®ã·ãªã¢ã«åæ¹æ³ãå®å
šã«å¶åŸ¡ã§ããŸããããããä¿åããããã³ã³ãã¯ããªæ¹æ³ããããã©ãããèŠãŠã¿ãŸããããæ°å€ééã®åæž
ç°ãªãã»ã«ã¬ãã«ãšã€ã³ããã¯ã¹ã¯æŽæ°ãšããŠä¿åãããŸãããã ãã䜿çšããå€ã®ç¯å²ã¯ãããããã§ããããããã0ã255ã®ç¯å²ã«ç¢ºå®ã«çãŸããŸããããã¯ãåæŽæ°ã®æåã®ãã€ãã®ã¿ã䜿çšãããããšãæå³ããŸããä»ã®3ã€ã¯åžžã«ãŒãã«ãªããŸãããããã®ç©ºã®ãã€ããä¿åããããšã¯æå³ããããŸãããã¹ããªãŒã ã«æžã蟌ãåã«æŽæ°ããã€ãã«æžã蟌ãããšã«ãããããããç Žæ£ã§ããŸãã writer.Write((byte)terrainTypeIndex); writer.Write((byte)elevation); writer.Write((byte)waterLevel); writer.Write((byte)urbanLevel); writer.Write((byte)farmLevel); writer.Write((byte)plantLevel); writer.Write((byte)specialIndex); writer.Write(walled); writer.Write(hasIncomingRiver); writer.Write((byte)incomingRiver); writer.Write(hasOutgoingRiver); writer.Write((byte)outgoingRiver);
ããŠããããã®æ°å€ãè¿ãã«ã¯ãã䜿çšããå¿
èŠããããŸãBinaryReader.ReadByte
ããã€ãããæŽæ°ãžã®å€æã¯æé»çã«è¡ããããããæç€ºçãªå€æã远å ããå¿
èŠã¯ãããŸããã terrainTypeIndex = reader.ReadByte(); elevation = reader.ReadByte(); RefreshPosition(); waterLevel = reader.ReadByte(); urbanLevel = reader.ReadByte(); farmLevel = reader.ReadByte(); plantLevel = reader.ReadByte(); specialIndex = reader.ReadByte(); walled = reader.ReadBoolean(); hasIncomingRiver = reader.ReadBoolean(); incomingRiver = (HexDirection)reader.ReadByte(); hasOutgoingRiver = reader.ReadBoolean(); outgoingRiver = (HexDirection)reader.ReadByte();
ãããã£ãŠãæŽæ°ããšã«3ãã€ããåãé€ããã»ã«ããšã«27ãã€ããç¯çŽããŸããã»ã«ããã18ãã€ãã300ã»ã«ãããããã5,400ãã€ãã䜿çšããŸãããã®æ®µéã§å€ãã«ãŒãã®ããŒã¿ãç¡æå³ã«ãªãããšã¯æ³šç®ã«å€ããŸããå€ãã»ãŒããããŒããããšãããŒã¿ãæ··åšããŠããããšãããããã»ã«ãæ··ä¹±ããŸããããã¯ãçŸåšèªã¿åãäžã®ããŒã¿ãå°ãªãããã§ãã以åãããå€ãã®ããŒã¿ãèªã¿åããšããã¡ã€ã«ã®æ«å°Ÿãè¶
ããŠèªã¿åãããšãããšãšã©ãŒãçºçããŸããå€ãããŒã¿ãåŠçã§ããªãããšã¯ãç§ãã¡ã«é©ããŠããŸãããªããªããç§ãã¡ã¯ãã©ãŒããããæ±ºå®ããéçšã«ããããã§ãããã ããä¿å圢åŒã決å®ãããšãã¯ãå°æ¥ã®ã³ãŒãã§åžžã«ä¿å圢åŒãèªã¿åããããã«ããå¿
èŠããããŸãã圢åŒã倿ŽããŠããçæ³çã«ã¯å€ã圢åŒãèªã¿åãããšãã§ããã¯ãã§ããRiver Byte Union
ãã®æ®µéã§ã¯ã4ãã€ãã䜿çšããŠå·ã®ããŒã¿ãä¿åããŸãïŒæ¹åããšã«2ãã€ãïŒãæ¹åããšã«ãå·ã®ååšãšæµããæ¹åãä¿åããŸãããå·ã®æ¹åãä¿åããå¿
èŠããªãã®ã¯æããã§ããããã¯ãå·ã®ãªãã»ã«ã«å¿
èŠãªãã€ãæ°ã2ãã€ãå°ãªãããšãæå³ããŸããå®éããã®ååšã«é¢ä¿ãªããå·ã®æ¹åã«1ãã€ãããã°ååã§ããå¯èœãªæ¹åã¯6ã€ããã0ã5ã®ééã§æ°å€ãšããŠä¿åãããŸããããã«ã¯3ãããã§ååã§ããããã¯ããã€ããªåœ¢åŒã§ã¯0ã5ã®æ°å€ã000ã001ã010ã011ã100ã101ã110ã®ããã«èŠããããã§ããã€ãŸãã1ãã€ãã§ããã«5ãããã䜿çšãããŸããããããã®1ã€ã䜿çšããŠãå·ãååšãããã©ããã瀺ãããšãã§ããŸããããšãã°ãæ°å€128ã«å¯Ÿå¿ãã8çªç®ã®ãããã䜿çšã§ããŸãããããè¡ãã«ã¯ãæ¹åããã€ãã«å€æããåã«128ã远å ããŸããã€ãŸããåè¥¿ã«æµããå·ãããå Žåã133ãæžã蟌ã¿ãŸããå·ããªãå Žåã¯ããŒããã€ããæžã蟌ãã ãã§ããåæã«ãããã«4ããããæªäœ¿çšã®ãŸãŸã§ãããããã¯æ£åžžã§ããå·ã®äž¡æ¹åã1ãã€ãã«ãŸãšããããšãã§ããŸãããããã¯æ¢ã«æ··ä¹±ããããŸãã
riverããŒã¿ããã³ãŒãããã«ã¯ãæåã«ãã€ããèªã¿æ»ãå¿
èŠããããŸããå€ã128以äžã®å Žåãããã¯å·ãããããšãæå³ããŸããæ¹åãååŸããã«ã¯ã128ãæžç®ããŠããã«å€æãHexDirection
ãŸãã
ãã®çµæãã»ã«ããšã«16ãã€ããåŸãŸãããæ¹åã¯ããã»ã©å€§ãããªãããã«èŠããŸãããããã¯ãã€ããªããŒã¿ã®ãµã€ãºãå°ããããããã«äœ¿çšãããããªãã¯ã®1ã€ã§ããéè·¯ã1ãã€ãã§ä¿åãã
åæ§ã®ææ³ã䜿çšããŠãéè·¯ããŒã¿ãå§çž®ã§ããŸãããã€ãã®æåã®6ãããã«æ ŒçŽã§ãã6ã€ã®ããŒã«å€ããããŸããã€ãŸããéè·¯ã®åæ¹åã¯2ã®çޝä¹ã®æ°å€ã§è¡šãããŸãããããã¯ã1ã2ã4ã8ã16ã32ããŸãã¯ãã€ããªåœ¢åŒã®1ã10ã100ã1000ã10000ã100000ã§ãã宿ãããã€ããäœæããã«ã¯ãéè·¯ã®äœ¿çšæ¹åã«å¯Ÿå¿ããããããèšå®ããå¿
èŠããããŸããæ¹åã®æ£ããæ¹åãååŸããã«ã¯ãæŒç®åã䜿çšã§ããŸã<<
ãæ¬¡ã«ããããããšã®ORæŒç®åã䜿çšããŠããããçµåããŸããããšãã°ã1çªç®ã2çªç®ã3çªç®ã6çªç®ã®éè·¯ã䜿çšãããŠããå Žåã宿ãããã€ãã¯100111ã«ãªããŸãã int roadFlags = 0; for (int i = 0; i < roads.Length; i++) {
<<ã¯ã©ã®ããã«æ©èœããŸããïŒããã¯ãããåäœã®å·Šã·ããæŒç®åã§ããå·ŠåŽã«æŽæ°ãåããåèšããããå·ŠåŽã«ã·ããããŸãããªãŒããŒãããŒã¯ç Žæ£ãããŸãããã·ããã¹ãããã®æ°ã¯ãå³åŽã®æŽæ°ã«ãã£ãŠæ±ºãŸããŸããæ°å€ã¯2鲿°ã§ããããããã¹ãŠã®ãããã1ã¹ãããå·Šã«ã·ãããããšãæ°å€ã®å€ã2åã«ãªããŸããã€ãŸãã1 << n
2 nãåŸããããããå¿
èŠã§ãã
éè·¯ã®ããŒã«å€ãååŸããã«ã¯ãããããèšå®ãããŠãããã©ããã確èªããå¿
èŠããããŸãããã®å Žåããããåäœã®ANDæŒç®åãé©åãªæ°ã§äœ¿çšããŠãä»ã®ãã¹ãŠã®ãããããã¹ã¯ããŸããçµæããŒãã«çãããªãå Žåãããããèšå®ãããéè·¯ãååšããŸãã int roadFlags = reader.ReadByte(); for (int i = 0; i < roads.Length; i++) { roads[i] = (roadFlags & (1 << i)) != 0; }
6ãã€ãã1ã€ã«å§çž®ãããšãã»ã«ããšã«11ãã€ããåãåããŸããã300ã»ã«ã®å Žåãããã¯ããã3,300ãã€ãã§ããã€ãŸãããã€ããå°ã䜿çšããŠããã¡ã€ã«ãµã€ãºã75ïŒ
åæžããŸãããæªæ¥ãžã®æºå
ä¿å圢åŒã®å®äºã宣èšããåã«ããã1ã€ã®è©³çްã远å ããŸãããããããŒã¿ãä¿åããåã«HexMapEditor
ãæŽæ°ã®ãŒãã匷å¶çã«æžã蟌ã¿ãŸãã public void Save () { string path = Path.Combine(Application.persistentDataPath, "test.map"); using ( BinaryWriter writer = new BinaryWriter(File.Open(path, FileMode.Create)) ) { writer.Write(0); hexGrid.Save(writer); } }
ããã«ãããããŒã¿ã®å
é ã«4ã€ã®ç©ºã®ãã€ãã远å ãããŸããã€ãŸããã«ãŒããããŒãããåã«ããããã®4ãã€ããèªã¿åãå¿
èŠããããŸãã public void Load () { string path = Path.Combine(Application.persistentDataPath, "test.map"); using (BinaryReader reader = new BinaryReader(File.OpenRead(path))) { reader.ReadInt32(); hexGrid.Load(reader); } }
ãããã®ãã€ãã¯ãããŸã§ã®ãšãã圹ã«ç«ããªãããå°æ¥çã«åŸæ¹äºææ§ãæäŸããããããŒãšããŠäœ¿çšãããŸãããããã®ãã«ãã€ãã远å ããŠããªãå Žåãæåã®æ°ãã€ãã®å
容ã¯ãããã®æåã®ã»ã«ã«äŸåããŠããŸããããããã£ãŠãå°æ¥ãã©ã®ããŒãžã§ã³ã®ä¿å圢åŒãæ±ã£ãŠããããææ¡ããããšã¯ããå°é£ã«ãªããŸããããã§ãæåã®4ãã€ãã確èªã§ããŸãããããã空ã®å Žåããã©ãŒããã0ã®ããŒãžã§ã³ãæ±ã£ãŠããŸããå°æ¥ã®ããŒãžã§ã³ã§ã¯ãããã«äœãä»ã®ãã®ã远å ããããšãå¯èœã«ãªããŸããã€ãŸããã¿ã€ãã«ããŒã以å€ã®å ŽåãäžæãªããŒãžã§ã³ãåŠçããŠããŸããã©ã®ããŒã¿ãããã®ãââããããªãããããããã®ããŠã³ããŒããæåŠããå¿
èŠããããŸãã using (BinaryReader reader = new BinaryReader(File.OpenRead(path))) { int header = reader.ReadInt32(); if (header == 0) { hexGrid.Load(reader); } else { Debug.LogWarning("Unknown map format " + header); } }
ãŠããã£ããã±ãŒãžããŒã13ïŒã«ãŒã管ç
- ãã¬ã€ã¢ãŒãã§æ°ããã«ãŒããäœæããŸãã
- ããŸããŸãªã«ãŒããµã€ãºã®ãµããŒãã远å ããŸãã
- ä¿åããããŒã¿ã«ãããã®ãµã€ãºã远å ããŸãã
- ä»»æã®ããããä¿åããã³ããŒãããŸãã
- ã«ãŒãã®ãªã¹ãã衚瀺ããŸãã
ãã®ããŒãã§ã¯ãããŸããŸãªãµã€ãºã®ã«ãŒãã®ãµããŒãã远å ããããŸããŸãªãã¡ã€ã«ãä¿åããŸãããã®ããŒãããå§ããŠããã¥ãŒããªã¢ã«ã¯Unity 5.5.0ã§äœæãããŸãããããã©ã€ãã©ãªã®å§ãŸããæ°ããããããäœæãã
ãããŸã§ã§ãå
è§åœ¢ã®ã°ãªãããäžåºŠã ãäœæããŸãã-ã·ãŒã³ãããŒããããšããããã§ããã€ã§ãæ°ããããããéå§ã§ããããã«ãªããŸããæ°ããã«ãŒãã¯ãåã«çŸåšã®ã«ãŒãã眮ãæããŸããAwake HexGrid
ã§ã¯ãããã€ãã®ã¡ããªãã¯ãåæåãããæ¬¡ã«ã»ã«ã®æ°ã決å®ãããå¿
èŠãªãã©ã°ã¡ã³ããšã»ã«ãäœæãããŸãããã©ã°ã¡ã³ããšã»ã«ã®æ°ããã»ãããäœæããŠãæ°ããããããäœæããŸããHexGrid.Awake
åæåãœãŒã¹ã³ãŒããšäžè¬çãªã¡ãœããã®2ã€ã®éšåã«åããŸãããCreateMap
ã void Awake () { HexMetrics.noiseSource = noiseSource; HexMetrics.InitializeHashGrid(seed); HexMetrics.colors = colors; CreateMap(); } public void CreateMap () { cellCountX = chunkCountX * HexMetrics.chunkSizeX; cellCountZ = chunkCountZ * HexMetrics.chunkSizeZ; CreateChunks(); CreateCells(); }
UIã«ãã¿ã³ã远å ããŠãæ°ããããããäœæããŸãã倧ããããŠãä¿åãã¿ã³ãšèªã¿èŸŒã¿ãã¿ã³ã®äžã«é
眮ããŸãããæ°ããããããã¿ã³ã ãã®ãã¿ã³ã®On Clickã€ãã³ããobjectã®ã¡ãœããã«æ¥ç¶ããŸããããã€ãŸããHex Map Editorã䜿çšããã®ã§ã¯ãªããHex Gridãªããžã§ã¯ãã¡ãœãããçŽæ¥åŒã³åºããŸããCreateMap
HexGrid
ã¯ãªãã¯ããŠå°å³ãäœæããŸããå€ãããŒã¿ãæ¶å»ãã
æ°ããããããã¿ã³ãã¯ãªãã¯ãããšãæ°ãããã©ã°ã¡ã³ããšã»ã«ã®ã»ãããäœæãããŸãããã ããå€ããã®ã¯èªåçã«åé€ãããŸããããããã£ãŠãçµæãšããŠãè€æ°ã®ãããã¡ãã·ã¥ãçžäºã«éããããŸãããããåé¿ããã«ã¯ãæåã«å€ããªããžã§ã¯ããåé€ããå¿
èŠããããŸããããã¯ãæåã«ãã¹ãŠã®çŸåšã®ãã©ã°ã¡ã³ããç Žæ£ããããšã§å®è¡ã§ããŸãCreateMap
ã public void CreateMap () { if (chunks != null) { for (int i = 0; i < chunks.Length; i++) { Destroy(chunks[i].gameObject); } } ⊠}
æ¢åã®ãªããžã§ã¯ããåå©çšã§ããŸããïŒå¯èœã§ãããæ°ãããã©ã°ã¡ã³ããšã»ã«ããå§ããæãç°¡åãªæ¹æ³ã§ããããã¯ãããŸããŸãªãµã€ãºã®ã«ãŒãã®ãµããŒãã远å ããå Žåã«ç¹ã«åœãŠã¯ãŸããŸããããã«ãæ°ãããããã®äœæã¯æ¯èŒçãŸããªã¢ã¯ã·ã§ã³ã§ãããæé©åã¯ããã§ã¯ããŸãéèŠã§ã¯ãããŸããã
ãã®ãããªåèŠçŽ ãã«ãŒãã§ç Žæ£ããããšã¯å¯èœã§ããïŒãã¡ããã .
ãã©ã°ã¡ã³ãã§ã¯ãªãã»ã«ã§ãµã€ãºãæå®ããŸã
ãã£ãŒã«ãchunkCountX
ãšchunkCountZ
ãªããžã§ã¯ãã䜿çšããŠãããã®ãµã€ãºãèšå®ããŸãHexGrid
ããã ããã»ã«ã®ãããã®ãµã€ãºãç€ºãæ¹ãã¯ããã«äŸ¿å©ã§ããåæã«ãã«ãŒãã®ãµã€ãºã倿Žããã«ããã©ã°ã¡ã³ãã®ãµã€ãºãå°æ¥å€æŽããããšãã§ããŸãããããã£ãŠãã»ã«æ°ãšãã©ã°ã¡ã³ããã£ãŒã«ãæ°ã®åœ¹å²ã亀æããŸãããã
ããã¯ãHexMapCamera
ãã©ã°ã¡ã³ããµã€ãºã䜿çšããŠäœçœ®ãå¶éãããããã³ã³ãã€ã«ãšã©ãŒãçºçããŸããHexMapCamera.ClampPosition
圌ããŸã å¿
èŠãªæ°ã®ã»ã«ãçŽæ¥äœ¿çšããããã«å€æŽããŸãã Vector3 ClampPosition (Vector3 position) { float xMax = (grid.cellCountX - 0.5f) * (2f * HexMetrics.innerRadius); position.x = Mathf.Clamp(position.x, 0f, xMax); float zMax = (grid.cellCountZ - 1) * (1.5f * HexMetrics.outerRadius); position.z = Mathf.Clamp(position.z, 0f, zMax); return position; }
ãã©ã°ã¡ã³ãã®ãµã€ãºã¯5 x 5ã»ã«ã§ãããã©ã«ãã®ãããã®ãµã€ãºã¯4 x 3ãã©ã°ã¡ã³ãã§ãããããã£ãŠãã«ãŒããåããŸãŸã«ããã«ã¯ã20 x 15ã»ã«ã®ãµã€ãºã䜿çšããå¿
èŠããããŸãããŸããã³ãŒãå
ã§ããã©ã«ãå€ãå²ãåœãŠãŸãããããã£ãŒã«ãã¯ãã§ã«ååšããããã©ã«ãã§0ã«èšå®ãããŠãããããã°ãªãããªããžã§ã¯ãã¯ãŸã ããããèªåçã«äœ¿çšããŸãããããã©ã«ãã§ã¯ãã«ãŒãã®ãµã€ãºã¯20 x 15ã§ããã«ã¹ã¿ã ã«ãŒããµã€ãº
次ã®ã¹ãããã¯ãããã©ã«ãã®ãµã€ãºã ãã§ãªãããããããµã€ãºã®ã«ãŒãã®äœæããµããŒãããããšã§ãããããè¡ãã«ã¯ãHexGrid.CreateMap
ãã©ã¡ãŒã¿ãŒã«XãšZ ã远å ãããšãæ¢åã®ã»ã«æ°ã眮ãæããããŸããå
éšã§Awake
ã¯ãçŸåšã®ã»ã«æ°ã§åŒã³åºããŸãã void Awake () { HexMetrics.noiseSource = noiseSource; HexMetrics.InitializeHashGrid(seed); HexMetrics.colors = colors; CreateMap(cellCountX, cellCountZ); } public void CreateMap (int x, int z) { ⊠cellCountX = x; cellCountZ = z; chunkCountX = cellCountX / HexMetrics.chunkSizeX; chunkCountZ = cellCountZ / HexMetrics.chunkSizeZ; CreateChunks(); CreateCells(); }
ãã ããããã¯ããã©ã°ã¡ã³ããµã€ãºã®åæ°ã§ããã»ã«ã®æ°ã§ã®ã¿æ£ããæ©èœããŸããããããªããšãæŽæ°é€ç®ã§äœæããããã©ã°ã¡ã³ããå°ãªãããŸããã»ã«ã§éšåçã«æºãããããã©ã°ã¡ã³ãã®ãµããŒãã远å ã§ããŸããããã©ã°ã¡ã³ãã«å¯Ÿå¿ããªããµã€ãºã®äœ¿çšãçŠæ¢ããŠã¿ãŸããããæŒç®å%
ã䜿çšããŠãã»ã«ã®æ°ããã©ã°ã¡ã³ãã®æ°ã§å²ã£ãäœããèšç®ã§ããŸãããŒãã«çãããªãå ŽåãççŸããããæ°ããããããäœæããŸããããããŠããããè¡ã£ãŠããéã«ããŒãããã³è² ã®ãµã€ãºã«å¯Ÿããä¿è·ã远å ããŸãããã public void CreateMap (int x, int z) { if ( x <= 0 || x % HexMetrics.chunkSizeX != 0 || z <= 0 || z % HexMetrics.chunkSizeZ != 0 ) { Debug.LogError("Unsupported map size."); return; } ⊠}
æ°ããã«ãŒãã¡ãã¥ãŒ
çŸåšã®æ®µéã§ã¯ãã¡ãœããã«ã¯2ã€ã®ãã©ã¡ãŒã¿ãŒãããããã[ æ°ããããã ]ãã¿ã³ã¯æ©èœããªããªããŸããHexGrid.CreateMap
ã Unityã€ãã³ãããã®ãããªã¡ãœããã«çŽæ¥æ¥ç¶ããããšã¯ã§ããŸãããããã«ãããŸããŸãªãµã€ãºã®ã«ãŒãããµããŒãããã«ã¯ãããã€ãã®ãã¿ã³ãå¿
èŠã§ããããããã¹ãŠã®ãã¿ã³ãã¡ã€ã³UIã«è¿œå ãã代ããã«ãåå¥ã®ãããã¢ããã¡ãã¥ãŒãäœæããŸããããã·ãŒã³ã«æ°ãããã£ã³ãã¹ã远å ããŸãïŒGameObject / UI / CanvasïŒãæ¢åã®ãã£ã³ãã¹ãšåãèšå®ã䜿çšããŸãããäžŠã¹æ¿ãé åºã¯1ã«ããå¿
èŠããããŸããããã«ãããã¡ã€ã³ãšãã£ã¿ãŒã®UIã®äžéšã«è¡šç€ºãããŸããæ°ããUIãªããžã§ã¯ãã®ãã£ã³ãã¹ãšã€ãã³ãã·ã¹ãã ã®äž¡æ¹ã®åãäœæããŠãã·ãŒã³ã®éå±€ããããã«ä¿ãããããã«ããŸããããã£ã³ãã¹ã¡ãã¥ãŒã®æ°ãããããã ç»é¢å
šäœãéããããã«ãæ°ãããããã¡ãã¥ãŒã«è¿œå ããŸããèæ¯ãæãããŠãã¡ãã¥ãŒãéããŠãããšãã«ã«ãŒãœã«ãä»ã®ãã¹ãŠãšå¯Ÿè©±ã§ããªãããã«ããå¿
èŠããããŸããSource Imageãã¯ãªã¢ããŠåäžãªè²ãäžããColorãšããŠïŒ0ã0ã0ã200ïŒãèšå®ããŸãããèæ¯ç»åã®èšå®ã 16é²ããããšãã£ã¿ãŒã®ããã«ãšåæ§ã«ããã£ã³ãã¹ã®äžå€®ã«ã¡ãã¥ãŒããŒã远å ããŸãã圌女ã®å°ãäžã倧ã®ã«ãŒãçšã®æç¢ºãªã©ãã«ãšãã¿ã³ãäœæããŸãããããã¬ã€ã€ãŒãæ°ãå€ãã£ãå Žåã«åããŠããã£ã³ã»ã«ãã¿ã³ã远å ããŸãããã¶ã€ã³ã®äœæãå®äºããããæ°ãããããã¡ãã¥ãŒå
šäœãç¡å¹ã«ããŸããæ°ãããããã¡ãã¥ãŒãã¡ãã¥ãŒã管çããã«ã¯ãã³ã³ããŒãã³ãNewMapMenu
ãäœæãããã£ã³ãã¹ã®æ°ãããããã¡ãã¥ãŒãªããžã§ã¯ãã«è¿œå ããŸããæ°ããããããäœæããã«ã¯ãHex Gridãªããžã§ã¯ãã«ã¢ã¯ã»ã¹ããå¿
èŠããããŸãããããã£ãŠãå
±éãã£ãŒã«ãã远å ããŠæ¥ç¶ããŸãã using UnityEngine; public class NewMapMenu : MonoBehaviour { public HexGrid hexGrid; }
æ°ãããããã¡ãã¥ãŒã®ã³ã³ããŒãã³ããéé
ãã£ã³ãã¹ãªããžã§ã¯ããã¢ã¯ãã£ãåããã³éã¢ã¯ãã£ãåããã ãã§ããããã¢ããã¡ãã¥ãŒãéãããéãããã§ããŸããNewMapMenu
ãããè¡ãããã®2ã€ã®äžè¬çãªã¡ãœããã远å ããŸãããã public void Open () { gameObject.SetActive(true); } public void Close () { gameObject.SetActive(false); }
次ã«ããšãã£ã¿ãŒã®[ æ°ããããã UI ]ãã¿ã³ã[æ°ãããããã¡ãã¥ãŒ]Open
ãªããžã§ã¯ãã®ã¡ãœããã«æ¥ç¶ããŸãããæŒããŠã¡ãã¥ãŒãéããŸãããŸãã[ ãã£ã³ã»ã« ]ãã¿ã³ãã¡ãœããã«æ¥ç¶ããŸãClose
ãããã«ããããããã¢ããã¡ãã¥ãŒãéãããéãããã§ããŸããæ°ããããããäœæãã
æ°ããããããäœæããã«ã¯ãHex Gridãªããžã§ã¯ãã®ã¡ãœãããåŒã³åºãå¿
èŠããããŸãCreateMap
ãããã«ããã®åŸããããã¢ããã¡ãã¥ãŒãéããå¿
èŠããããŸããNewMapMenu
ä»»æã®ãµã€ãºãèæ
®ããŠãããã«å¯ŸåŠããã¡ãœããã«è¿œå ããŸãã void CreateMap (int x, int z) { hexGrid.CreateMap(x, z); Close(); }
ãã®ã¡ãœããã¯ããã¿ã³ã€ãã³ãã«çŽæ¥æ¥ç¶ã§ããªããããäžè¬çã§ã¯ãããŸããã代ããã«ãCreateMap
æå®ããããµã€ãºã§åŒã³åºããã¿ã³ããšã«1ã€ã®ã¡ãœãããäœæããŸããå°ããªãããã®å Žåããããã®ããã©ã«ããµã€ãºã«å¯Ÿå¿ãã20 x 15ã®ãµã€ãºã䜿çšããŸãããäžå€®ã®ã«ãŒãã«ã€ããŠã¯ããã®ãµã€ãºã2åã«ããŠ40 x 30ã«ãã倧ããªã«ãŒãã®å Žåã¯åã³2åã«ããããšã«ããŸãããé©åãªæ¹æ³ã§ãã¿ã³ãæ¥ç¶ããŸãã public void CreateSmallMap () { CreateMap(20, 15); } public void CreateMediumMap () { CreateMap(40, 30); } public void CreateLargeMap () { CreateMap(80, 60); }
ã«ã¡ã©ããã¯
ããã§ããããã¢ããã¡ãã¥ãŒã䜿çšããŠã3ã€ã®ç°ãªããµã€ãºã®æ°ããã«ãŒããäœæã§ããŸãããã¹ãŠããŸããããŸãããå°ãè©³çŽ°ã«æ³šæããå¿
èŠããããŸãããšãã«æ°èŠãããã¡ãã¥ãŒãã¢ã¯ãã£ãã«ãªã£ãŠãç§ãã¡ã¯UIãšãã£ã¿ããã³ç·šé现èãšããã¯ã察話ããããšãã§ããŸãããã ããã«ã¡ã©ãå¶åŸ¡ããããšã¯ã§ããŸããçæ³çã«ã¯ãã¡ãã¥ãŒãéããç¶æ
ã§ã«ã¡ã©ãããã¯ããå¿
èŠããããŸããã«ã¡ã©ã¯1å°ãããªããããç°¡åã§å®çšçãªè§£æ±ºçã¯ãéçããããã£ã远å ããããšLocked
ã§ããåºç¯å²ã«äœ¿çšããå Žåããã®ãœãªã¥ãŒã·ã§ã³ã¯ããŸãé©ããŠããŸããããã·ã³ãã«ãªã€ã³ã¿ãŒãã§ã€ã¹ã§ã¯ååã§ããããã«ã¯ãå
éšã®éçã€ã³ã¹ã¿ã³ã¹ã远跡ããå¿
èŠããããŸãHexMapCamera
ãããã¯ãAwakeã«ã¡ã©ãèšå®ããããšãã«èšå®ãããŸãã static HexMapCamera instance; ⊠void Awake () { instance = this; swivel = transform.GetChild(0); stick = swivel.GetChild(0); }
ããããã£Locked
ã¯ãã»ãã¿ãŒã®ã¿ã䜿çšããåçŽãªéçããŒã«ããããã£ã«ããããšãã§ããŸããHexMapCamera
ããã¯ããããšã€ã³ã¹ã¿ã³ã¹ããªãã«ãªããããã¯ãè§£é€ããããšãªã³ã«ãªããŸãã public static bool Locked { set { instance.enabled = !value; } }
ããã§NewMapMenu.Open
ã«ã¡ã©ããããã¯ã§ããNewMapMenu.Close
ããã¯ãè§£é€ã§ããŸãã public void Open () { gameObject.SetActive(true); HexMapCamera.Locked = true; } public void Close () { gameObject.SetActive(false); HexMapCamera.Locked = false; }
æ£ããã«ã¡ã©äœçœ®ãç¶æãã
ã«ã¡ã©ã«å¥ã®åé¡ãããå¯èœæ§ããããŸããçŸåšã®ããããããå°ããæ°ããããããäœæãããšãã«ã¡ã©ããããã®å¢çã®å€åŽã«è¡šç€ºãããå ŽåããããŸãããã¬ãŒã€ãŒãã«ã¡ã©ãåããããšãããŸã§ã圌女ã¯ããã«æ®ããŸãããããŠãæ°ãããããã®å¶éã«ãã£ãŠå¶éãããŸãããã®åé¡ã解決ããããã«ãHexMapCamera
éçã¡ãœããã«è¿œå ã§ãValidatePosition
ãŸããAdjustPosition
ãŒããªãã»ããã§ã€ã³ã¹ã¿ã³ã¹ã¡ãœãããåŒã³åºããšãã«ã¡ã©ããããã®å¢çã«åŒ·å¶çã«ç§»åããŸããã«ã¡ã©ãæ¢ã«æ°ãããããã®å¢çå
ã«ããå Žåãã«ã¡ã©ã¯æå®ã®äœçœ®ã«æ®ããŸãã public static void ValidatePosition () { instance.AdjustPosition(0f, 0f); }
NewMapMenu.CreateMap
æ°ããããããäœæããåŸãå
éšã§ã¡ãœãããåŒã³åºããŸãã void CreateMap (int x, int z) { hexGrid.CreateMap(x, z); HexMapCamera.ValidatePosition(); Close(); }
ãŠããã£ããã±ãŒãžããããµã€ãºã®ä¿å
ããŸããŸãªãµã€ãºã®ã«ãŒããäœæã§ããŸãããä¿åãèªã¿èŸŒã¿ã®éã«ã¯èæ
®ãããŸãããããã¯ãçŸåšã®ãããã®ãµã€ãºãããŒãããããããã®ãµã€ãºãšäžèŽããªãå ŽåãããããããŒããããšãšã©ãŒãŸãã¯èª€ã£ãããããçºçããããšãæå³ããŸãããã®åé¡ã解決ããã«ã¯ãã»ã«ããŒã¿ãèªã¿èŸŒãåã«ãé©åãªãµã€ãºã®æ°ããããããäœæããå¿
èŠããããŸããå°ããªå°å³ãä¿åãããŠãããšããŸãããã®å Žåãæåã«HexGrid.Load
20 x 15ã®ããããäœæããã°ããã¹ãŠããŸããããŸãã public void Load (BinaryReader reader) { CreateMap(20, 15); for (int i = 0; i < cells.Length; i++) { cells[i].Load(reader); } for (int i = 0; i < chunks.Length; i++) { chunks[i].Refresh(); } }
ã«ãŒããµã€ãºã®ä¿ç®¡
ãã¡ãããã©ããªãµã€ãºã®ã«ãŒãã§ãä¿åã§ããŸãããããã£ãŠãäžè¬çãªè§£æ±ºçã¯ããããã®ã»ã«ã®åã«ãããã®ãµã€ãºãä¿åããããšã§ãã public void Save (BinaryWriter writer) { writer.Write(cellCountX); writer.Write(cellCountZ); for (int i = 0; i < cells.Length; i++) { cells[i].Save(writer); } }
次ã«ãå®éã®ãµã€ãºãååŸããããã䜿çšããŠæ£ãããµã€ãºã®ããããäœæã§ããŸãã public void Load (BinaryReader reader) { CreateMap(reader.ReadInt32(), reader.ReadInt32()); ⊠}
ããŸããŸãªãµã€ãºã®ããããããŒãã§ããããã«ãªã£ããããã«ã¡ã©ã®äœçœ®ã®åé¡ã«åã³çŽé¢ããŠããŸããHexMapEditor.Load
å°å³ãèªã¿èŸŒãã åŸããã®äœçœ®ããã§ãã¯ã€ã³ããããšã§è§£æ±ºããŸãã public void Load () { string path = Path.Combine(Application.persistentDataPath, "test.map"); using (BinaryReader reader = new BinaryReader(File.OpenRead(path))) { int header = reader.ReadInt32(); if (header == 0) { hexGrid.Load(reader, header); HexMapCamera.ValidatePosition(); } else { Debug.LogWarning("Unknown map format " + header); } } }
æ°ãããã¡ã€ã«åœ¢åŒ
ãã®ã¢ãããŒãã¯ãä»åŸä¿æããã«ãŒãã§æ©èœããŸãããå€ãã«ãŒãã§ã¯æ©èœããŸããããŸããã®é-ãã¥ãŒããªã¢ã«ã®åã®éšåã®ã³ãŒãã¯ãæ°ããããããã¡ã€ã«ãæ£ããããŒãã§ããŸãããå€ã圢åŒãšæ°ãã圢åŒãåºå¥ããããã«ãããããŒã®æŽæ°å€ãå¢ãããŸããããããµã€ãºã®ãªãå€ãä¿å圢åŒã¯ããŒãžã§ã³0ã§ãããããããµã€ãºã®æ°ãã圢åŒã¯ããŒãžã§ã³1ã«ãªããŸãããããã£ãŠãèšé²ãããšãHexMapEditor.Save
ã0ã§ã¯ãªã1ãæžã蟌ãå¿
èŠããããŸãã public void Save () { string path = Path.Combine(Application.persistentDataPath, "test.map"); using ( BinaryWriter writer = new BinaryWriter(File.Open(path, FileMode.Create)) ) { writer.Write(1); hexGrid.Save(writer); } }
ãã以éããããã¯ããŒãžã§ã³1ãšããŠä¿åãããŸããåã®ãã¥ãŒããªã¢ã«ã®ã¢ã»ã³ããªã§ããããéãããšãããšãäžæãªããã圢åŒã®ããŒããšã¬ããŒããæåŠãããŸããå®éããã®ãããªã«ãŒããæ¢ã«ããŒãããããšãããšããããçºçããŸããHexMapEditor.Load
æ°ããããŒãžã§ã³ãåãå
¥ããããã«ã¡ãœããã倿Žããå¿
èŠããããŸãã public void Load () { string path = Path.Combine(Application.persistentDataPath, "test.map"); using (BinaryReader reader = new BinaryReader(File.OpenRead(path))) { int header = reader.ReadInt32(); if (header == 1) { hexGrid.Load(reader); HexMapCamera.ValidatePosition(); } else { Debug.LogWarning("Unknown map format " + header); } } }
äžäœäºææ§
å®éãå¿
èŠã«å¿ããŠãããŒãžã§ã³0ã®ããããããŠã³ããŒãã§ããŸãããããã®ãµã€ãºã¯ãã¹ãŠ20 x 15ã§ãããšä»®å®ããŸããã€ãŸããã¿ã€ãã«ã¯1ã§ããå¿
èŠã¯ãªãããŒãã§ãããŸããŸãããåããŒãžã§ã³ã«ã¯ç¬èªã®ã¢ãããŒããå¿
èŠã§ããããHexMapEditor.Load
ãããããŒãmethodã«æž¡ãå¿
èŠãããHexGrid.Load
ãŸãã if (header <= 1) { hexGrid.Load(reader, header); HexMapCamera.ValidatePosition(); }
HexGrid.Load
ãã©ã¡ãŒã¿ã«ã¿ã€ãã«ã远å ããããã䜿çšããŠãããã«ã¢ã¯ã·ã§ã³ã決å®ããŸããããããŒã1以äžã®å Žåãã«ãŒããµã€ãºããŒã¿ãèªã¿åãå¿
èŠããããŸãããã以å€ã®å Žåã20 x 15ã®å€ãåºå®ã«ãŒããµã€ãºã䜿çšãããµã€ãºããŒã¿ã®èªã¿åããã¹ãããããŸãã public void Load (BinaryReader reader, int header) { int x = 20, z = 15; if (header >= 1) { x = reader.ReadInt32(); z = reader.ReadInt32(); } CreateMap(x, z); ⊠}
ããããã¡ã€ã«ããŒãžã§ã³0ã«ãŒããµã€ãºã®ç¢ºèª
æ°ãããããã®äœæãšåæ§ã«ããã©ã°ã¡ã³ãã®ãµã€ãºãšäºææ§ã®ãªãããããããŒãããå¿
èŠãããå¯èœæ§ãçè«çã«ãããŸãããã®å Žåãã«ãŒãã®ããŠã³ããŒããäžæããå¿
èŠããããŸããHexGrid.CreateMap
ãã§ã«ãããã®äœæãæåŠããã³ã³ãœãŒã«ã«ãšã©ãŒã衚瀺ããŸãããããã¡ãœããã®åŒã³åºãå
ã«äŒããããã«ãããããäœæããããã©ãããäŒããããŒã«å€ãè¿ããŸãããã public bool CreateMap (int x, int z) { if ( x <= 0 || x % HexMetrics.chunkSizeX != 0 || z <= 0 || z % HexMetrics.chunkSizeZ != 0 ) { Debug.LogError("Unsupported map size."); return false; } ⊠return true; }
ããŠHexGrid.Load
ãããŸãã«ããããããäœæããã«ã¯ã倱æããå Žåã«å®è¡ã忢ããããšãã§ããŸãã public void Load (BinaryReader reader, int header) { int x = 20, z = 15; if (header >= 1) { x = reader.ReadInt32(); z = reader.ReadInt32(); } if (!CreateMap(x, z)) { return; } ⊠}
ããŒããããšæ¢åã®ã»ã«ã®ãã¹ãŠã®ããŒã¿ãäžæžãããããããåããµã€ãºã®ããããããŒããããå Žåãæ°ããããããäœæããå¿
èŠã¯ãããŸããããããã£ãŠããã®æé ã¯ã¹ãããã§ããŸãã if (x != cellCountX || z != cellCountZ) { if (!CreateMap(x, z)) { return; } }
ãŠããã£ããã±ãŒãžãã¡ã€ã«ç®¡ç
ãµã€ãºã®ç°ãªãã«ãŒããä¿åããã³ããŒãã§ããŸãããåžžã«test.mapãèªã¿æžãããŸããæ¬¡ã«ãããŸããŸãªãã¡ã€ã«ã®ãµããŒãã远å ããŸããããããçŽæ¥ä¿åãŸãã¯ããŒããã代ããã«ãé«åºŠãªãã¡ã€ã«ç®¡çãæäŸããå¥ã®ãããã¢ããã¡ãã¥ãŒã䜿çšããŸããNew Map Menuã®ããã«å¥ã®ãã£ã³ãã¹ãäœæããŸãããä»åã¯Save Load MenuãšåŒã³ãŸãããã®ã¡ãã¥ãŒã¯ãããããéããŠæŒããã¿ã³ã«å¿ããŠãããããä¿åããã³ããŒãããŸããSave Load Menuãã¶ã€ã³ãäœæããŸããä¿åã¡ãã¥ãŒã®ããã«ãåŸã§ããŒãã¡ãã¥ãŒã«åçã«å€æŽããŸããå¥ã®ã¡ãã¥ãŒãšåæ§ã«ãèæ¯ãšã¡ãã¥ãŒããŒãã¡ãã¥ãŒã©ãã«ããã£ã³ã»ã«ãã¿ã³ãå¿
èŠã§ããæ¬¡ã«ãã¡ãã¥ãŒã«ã¹ã¯ããŒã«ãã¥ãŒïŒGameObject / UI / Scroll ViewïŒã远å ããŠããã¡ã€ã«ã®ãªã¹ãã衚瀺ããŸãã以äžã«å
¥åãã£ãŒã«ãïŒGameObject / UI / Input FieldïŒãæ¿å
¥ããŠãæ°ããã«ãŒãã®ååã瀺ããŸããããããä¿åããããã®ã¢ã¯ã·ã§ã³ãã¿ã³ãå¿
èŠã§ãããããŠæåŸã«ãåé€ãã¿ã³ã远å ããŠãäžèŠãªã«ãŒããåé€ããŸãã[ä¿åã¡ãã¥ãŒã®ä¿å]ãèšèšããŸããããã©ã«ãã§ã¯ãã¹ã¯ããŒã«ãã¥ãŒã§ã¯æ°Žå¹³ã¹ã¯ããŒã«ãšåçŽã¹ã¯ããŒã«ã®äž¡æ¹ãå¯èœã§ãããå¿
èŠãªã®ã¯åçŽã¹ã¯ããŒã«ã®ãªã¹ãã®ã¿ã§ãããã®ãããç¡å¹ã«ã¹ã¯ããŒã«æ°Žå¹³ããã³æ°Žå¹³ã¹ã¯ããŒã«ããŒæããŠãã ããããŸããMovement Typeãclampedã«èšå®ããInertiaãç¡å¹ã«ããŠãªã¹ãã®å¶éã匷åããŸãããã¡ã€ã«ãªã¹ããªãã·ã§ã³ã File Listãªããžã§ã¯ãããScrollbar Horizoâântalåãåé€ããŸããããã¯å¿
èŠãªãããã§ããæ¬¡ã«ãScrollbar Verticalã®ãµã€ãºã倿ŽããŠããªã¹ãã®äžéšã«å°éããŸããName Inputãªããžã§ã¯ãã®ãã¬ãŒã¹ãã«ããŒããã¹ãã¯ããã®åPlaceholderã§å€æŽã§ããŸãã説æããã¹ãã䜿çšããŸãããã空çœã®ãŸãŸã«ããŠãã¬ãŒã¹ãã«ããŒãåé€ã§ããŸããã¡ãã¥ãŒã®ãã¶ã€ã³ã倿ŽããŸããããã¶ã€ã³ãå®äºããããã©ã«ãã§ã¡ãã¥ãŒãé衚瀺ã«ãªãããã«ã¡ãã¥ãŒãç¡å¹ã«ããŸããã¡ãã¥ãŒç®¡ç
ã¡ãã¥ãŒãæ©èœãããã«ã¯ãå¥ã®ã¹ã¯ãªããããã®å Žå-ãå¿
èŠSaveLoadMenu
ã§ããã®ããNewMapMenu
ã«ãã°ãªãããžã®ãªã³ã¯ãã¡ãœããOpen
ãããã³ãå¿
èŠClose
ã§ãã using UnityEngine; public class SaveLoadMenu : MonoBehaviour { public HexGrid hexGrid; public void Open () { gameObject.SetActive(true); HexMapCamera.Locked = true; } public void Close () { gameObject.SetActive(false); HexMapCamera.Locked = false; } }
ãã®ã³ã³ããŒãã³ããSaveLoadMenuã«è¿œå ããã°ãªãããªããžã§ã¯ããžã®ãªã³ã¯ãäžããŸããã³ã³ããŒãã³ãSaveLoadMenuãä¿åãŸãã¯ããŒãããã¡ãã¥ãŒãéããŸããäœæ¥ãç°¡çŽ åããã«ã¯ãOpen
ããŒã«ãã©ã¡ãŒã¿ãmethodã«è¿œå ããŸããã¡ãã¥ãŒãä¿åã¢ãŒãã«ãããã©ãããæ±ºå®ããŸãããã®ã¢ãŒãããã£ãŒã«ãã§è¿œè·¡ããŠãåŸã§å®è¡ããã¢ã¯ã·ã§ã³ã確èªããŸãã bool saveMode; public void Open (bool saveMode) { this.saveMode = saveMode; gameObject.SetActive(true); HexMapCamera.Locked = true; }
ä»ãããã¿ã³çµã¿åãããä¿åãšèªã¿èŸŒã¿ãªããžã§ã¯ãããã¯ã¹ããããšãã£ã¿ãã¡ãœããã§Open
ãªããžã§ã¯ãã®ä¿åã¯ãã¡ãã¥ãŒãããŒãããŸãã[ ä¿å ]ãã¿ã³ã®ã¿ã®ããŒã«ãã©ã¡ãŒã¿ã確èªããŸããä¿åã¢ãŒãã§ã¡ãã¥ãŒãéããŸãããŸã è¡ã£ãŠããªãå Žåã¯ããã£ã³ã»ã«ãã¿ã³ã€ãã³ããã¡ãœããã«æ¥ç¶ããŸãClose
ãä»ã»ãŒãããŒãã¡ãã¥ãŒãééããããšãã§ããŸããå€èгã®å€å
ã¡ãã¥ãŒãä¿åã¡ãã¥ãŒãšããŠäœæããŸããããã¢ãŒãã¯ãã¿ã³ãæŒããŠéãããšã§æ±ºå®ãããŸããã¢ãŒãã«å¿ããŠã¡ãã¥ãŒã®å€èгã倿Žããå¿
èŠããããŸããç¹ã«ãã¡ãã¥ãŒã©ãã«ãšã¢ã¯ã·ã§ã³ãã¿ã³ã©ãã«ã倿Žããå¿
èŠããããŸããããã¯ããããã®ã¿ã°ãžã®ãªã³ã¯ãå¿
èŠã«ãªãããšãæå³ããŸãã using UnityEngine; using UnityEngine.UI; public class SaveLoadMenu : MonoBehaviour { public Text menuLabel, actionButtonLabel; ⊠}
ã¿ã°ãšã®æ¥ç¶ãã¡ãã¥ãŒãä¿åã¢ãŒãã§éããšãæ¢åã®ã©ãã«ãã€ãŸããã¡ãã¥ãŒã®ãããã®ä¿åãšã¢ã¯ã·ã§ã³ãã¿ã³ã®ä¿åã䜿çšãããŸãããã以å€ã®å Žåã¯ãããŒãã¢ãŒãã«ãªããŸããã€ãŸããLoad MapãšLoadã䜿çšããŸãã public void Open (bool saveMode) { this.saveMode = saveMode; if (saveMode) { menuLabel.text = "Save Map"; actionButtonLabel.text = "Save"; } else { menuLabel.text = "Load Map"; actionButtonLabel.text = "Load"; } gameObject.SetActive(true); HexMapCamera.Locked = true; }
ã«ãŒãåãå
¥åããŠãã ãã
ãã¡ã€ã«ã®ãªã¹ãã¯ä»ã®ãšããæ®ããŠãããŸãããããŠãŒã¶ãŒã¯ãå
¥åãã£ãŒã«ãã«ã«ãŒãã®ååãå
¥åããŠãä¿åãŸãã¯ããŠã³ããŒããããã¡ã€ã«ãæå®ã§ããŸãããã®ããŒã¿ãååŸããã«InputField
ã¯ãName Inputãªããžã§ã¯ãã®ã³ã³ããŒãã³ããžã®åç
§ãå¿
èŠã§ãã public InputField nameInput;
å
¥åãã£ãŒã«ããžã®æ¥ç¶ããŠãŒã¶ãŒã¯ãããããã¡ã€ã«ãžã®ãã«ãã¹ãå
¥åããå¿
èŠã¯ãããŸããã.mapæ¡åŒµåã®ãªããããåã®ã¿ã§ååã§ãããŠãŒã¶ãŒå
¥åãåãåãããã®æ£ãããã¹ãäœæããã¡ãœããã远å ããŸããããå
¥åã空ã®å Žåãããã¯äžå¯èœãªã®ã§ããã®å Žåã¯ãè¿ãnull
ãŸãã using UnityEngine; using UnityEngine.UI; using System.IO; public class SaveLoadMenu : MonoBehaviour { ⊠string GetSelectedPath () { string mapName = nameInput.text; if (mapName.Length == 0) { return null; } return Path.Combine(Application.persistentDataPath, mapName + ".map"); } }
ãŠãŒã¶ãŒãç¡å¹ãªæåãå
¥åãããšã©ããªããŸããïŒ, . , , .
Content Type . , - , . , , .
ä¿åãšèªã¿èŸŒã¿
ããã§ãä¿åãšèªã¿èŸŒã¿ãè¡ããSaveLoadMenu
ãŸãããããã£ãŠãæã
ã¯ãã¡ãœãããç§»åSave
ããŠLoad
ã®HexMapEditor
ã®äžã§SaveLoadMenu
ããããã¯ãã¯ãå
±æãããå¿
èŠããªããåºå®ãã¹ã®ä»£ããã«ãã¹ãã©ã¡ãŒã¿ã§åäœããŸãã void Save (string path) {
çŸåšãä»»æã®ãã¡ã€ã«ãã¢ããããŒãããŠããã®ã§ããã¡ã€ã«ãå®éã«ååšããããšã確èªããŠããããããèªã¿åãããšãããšããã§ããããããã§ãªãå Žåã¯ããšã©ãŒãã¹ããŒããŠæäœãçµäºããŸãã void Load (string path) { if (!File.Exists(path)) { Debug.LogError("File does not exist " + path); return; } ⊠}
次ã«ãäžè¬çãªã¡ãœããã远å ãAction
ãŸãããŠãŒã¶ãŒãéžæãããã¹ãååŸããããšããå§ãŸããŸãããã¹ãããå Žåã¯ãä¿åãŸãã¯ããŒãããŸããæ¬¡ã«ã¡ãã¥ãŒãéããŸãã public void Action () { string path = GetSelectedPath(); if (path == null) { return; } if (saveMode) { Save(path); } else { Load(path); } Close(); }
ãã®ã¡ãœããã«Action Buttonã€ãã³ããã¢ã¿ããããããšã«ãããä»»æã®ãããåã䜿çšããŠä¿åããã³ããŒãã§ããŸããå
¥åãã£ãŒã«ãããªã»ããããªããããéžæããååã¯æ¬¡ã®ä¿åãŸãã¯ããŒããŸã§æ®ããŸããããã¯ã1ã€ã®ãã¡ã€ã«ããé£ç¶ããŠè€æ°åä¿åãŸãã¯ããŒãããã®ã«äŸ¿å©ãªã®ã§ãäœã倿ŽããŸãããããããªã¹ãã¢ã€ãã
次ã«ããã¡ã€ã«ã®ãªã¹ãã«ãããŒã¿ã¹ãã¬ãŒãžãã¹äžã«ãããã¹ãŠã®ã«ãŒããå
¥åããŸãããªã¹ãå
ã®ããããã®ã¢ã€ãã ãã¯ãªãã¯ãããšãååå
¥åã®ããã¹ããšããŠäœ¿çšãããŸããSaveLoadMenu
ãã®ããã®äžè¬çãªæ¹æ³ã远å ããŸãã public void SelectItem (string name) { nameInput.text = name; }
ãªã¹ãã¢ã€ãã ãå¿
èŠã§ããéåžžã®ãã¿ã³ã§ã§ããŸããäœæããé«ãã20åäœã«æžãããŠãåçŽæ¹åã«å€ãã®ã¹ããŒã¹ãå æããªãããã«ããŸãããã¿ã³ã®ããã«èŠããã¹ãã§ã¯ãªãã®ã§ãImageã³ã³ããŒãã³ãã®Source Imageãªã³ã¯ãã¯ãªã¢ããŸãããã®å Žåãå®å
šã«çœã«ãªããŸããããã«ãã©ãã«ãå·Šã«æããããããã¹ããšãã¿ã³ã®å·ŠåŽã®éã«ã¹ããŒã¹ãããããšã確èªããŸãããã¿ã³ã®èšèšãå®äºããããããããã¬ããã«å€ããŸãããã¿ã³ã¯ãªã¹ãé
ç®ã§ãããã¿ã³ã€ãã³ããæ°ãããããã¡ãã¥ãŒã«çŽæ¥æ¥ç¶ããããšã¯ã§ããŸãããããã¯ããã¬ããã§ããããŸã ã·ãŒã³ã«ååšããªãããã§ãããããã£ãŠãã¯ãªãã¯ããSelectItem
ããšãã«ã¡ãœãããåŒã³åºãããšãã§ããããã«ãã¡ãã¥ãŒé
ç®ã«ã¯ã¡ãã¥ãŒãžã®ãªã³ã¯ãå¿
èŠã§ãã圌ã¯ãŸãã圌ã代衚ããã«ãŒãã®ååã远跡ããããã¹ããèšå®ããå¿
èŠããããŸãããã®ããã®å°ããªã³ã³ããŒãã³ããäœæããŸãããSaveLoadItem
ã using UnityEngine; using UnityEngine.UI; public class SaveLoadItem : MonoBehaviour { public SaveLoadMenu menu; public string MapName { get { return mapName; } set { mapName = value; transform.GetChild(0).GetComponent<Text>().text = value; } } string mapName; public void Select () { menu.SelectItem(mapName); } }
ã³ã³ããŒãã³ããã¡ãã¥ãŒé
ç®ã«è¿œå ãããã¿ã³ããã®ã¡ãœãããåŒã³åºãããã«ããŸãSelect
ãã¢ã€ãã ã³ã³ããŒãã³ãããªã¹ãå¡ãã€ã¶ã
ãªã¹ããäœæSaveLoadMenu
ããã«ã¯ããã¡ã€ã«ãªã¹ããªããžã§ã¯ãã®ãã¥ãŒããŒãå
ã®ã³ã³ãã³ããžã®ãªã³ã¯ãå¿
èŠã§ãããŸããã¢ã€ãã ã®ãã¬ãããžã®ãªã³ã¯ãå¿
èŠã§ãã public RectTransform listContent; public SaveLoadItem itemPrefab;
ãªã¹ãã®ã³ã³ãã³ããšãã¬ãããããã¯ã¹ããŸããæ°ããã¡ãœããã䜿çšããŠããã®ãªã¹ããäœæããŸããæåã®ã¹ãããã¯ãæ¢åã®ããããã¡ã€ã«ãèå¥ããããšã§ãããã£ã¬ã¯ããªå
ã®ãã¹ãŠã®ãã¡ã€ã«ãã¹ã®é
åãååŸããã«ã¯ãã¡ãœããã䜿çšã§ããŸãDirectory.GetFiles
ããã®ã¡ãœããã«ã¯ããã¡ã€ã«ããã£ã«ã¿ãŒã§ãã2çªç®ã®ãã©ã¡ãŒã¿ãŒããããŸãããã®å Žåã* .mapãã¹ã¯ã«äžèŽãããã¡ã€ã«ã®ã¿ãå¿
èŠã§ãã void FillList () { string[] paths = Directory.GetFiles(Application.persistentDataPath, "*.map"); }
æ®å¿µãªããããã¡ã€ã«ã®é åºã¯ä¿èšŒãããŠããŸãããããããã¢ã«ãã¡ãããé ã«è¡šç€ºããã«ã¯ãé
åãã§ãœãŒãããå¿
èŠããããŸãSystem.Array.Sort
ã using UnityEngine; using UnityEngine.UI; using System; using System.IO; public class SaveLoadMenu : MonoBehaviour { ⊠void FillList () { string[] paths = Directory.GetFiles(Application.persistentDataPath, "*.map"); Array.Sort(paths); } ⊠}
次ã«ãé
åã®åèŠçŽ ã«å¯ŸããŠãã¬ããã€ã³ã¹ã¿ã³ã¹ãäœæããŸããã¢ã€ãã ãã¡ãã¥ãŒã«ãã€ã³ããããããåãèšå®ããŠããªã¹ãã®ã³ã³ãã³ãã®åã«ããŸãã Array.Sort(paths); for (int i = 0; i < paths.Length; i++) { SaveLoadItem item = Instantiate(itemPrefab); item.menu = this; item.MapName = paths[i]; item.transform.SetParent(listContent, false); }
以æ¥Directory.GetFiles
ããã¡ã€ã«ãžã®ãã«ãã¹æ»ããç§ãã¡ã¯ãããããããã«ããå¿
èŠããããŸãã幞ããªããšã«ãããã¯ãŸãã«äŸ¿å©ãªã¡ãœãããäœããã®Path.GetFileNameWithoutExtension
ã§ãã item.MapName = Path.GetFileNameWithoutExtension(paths[i]);
ã¡ãã¥ãŒã衚瀺ããåã«ããªã¹ãã«èšå
¥ããå¿
èŠããããŸãããŸãããã¡ã€ã«ã¯å€æŽãããå¯èœæ§ãé«ããããã¡ãã¥ãŒãéããã³ã«ãããè¡ãå¿
èŠããããŸãã public void Open (bool saveMode) { ⊠FillList(); gameObject.SetActive(true); HexMapCamera.Locked = true; }
ãªã¹ããåå
¥åããå Žåãæ°ããã¢ã€ãã ã远å ããåã«å€ããã®ããã¹ãŠåé€ããå¿
èŠããããŸãã void FillList () { for (int i = 0; i < listContent.childCount; i++) { Destroy(listContent.GetChild(i).gameObject); } ⊠}
ã¢ã¬ã³ãžãªãã®ã¢ã€ãã ããã€ã³ãã®é
眮
ããã§ãªã¹ãã«é
ç®ã衚瀺ãããŸããããããã¯éãªã£ãŠäžé©åãªäœçœ®ã«ãããŸããããããåçŽãªã¹ãã«å€æããã«ã¯ãåçŽã¬ã€ã¢ãŠãã°ã«ãŒãã³ã³ããŒãã³ãïŒã³ã³ããŒãã³ã/ã¬ã€ã¢ãŠã/åçŽã¬ã€ã¢ãŠãã°ã«ãŒãïŒããªã¹ãã®ã³ã³ãã³ããªããžã§ã¯ãã«è¿œå ããŸããé
çœ®ãæ£ããæ©èœããããã«ããã«ã¯ããåã³ã³ãããŒã«ãµã€ãºããšãååŒ·å¶æ¡åŒµãã®äž¡æ¹ã®å¹
ãæå¹ã«ããŸããäž¡æ¹ã®é«ããªãã·ã§ã³ãç¡å¹ã«ããå¿
èŠããããŸããåçŽã¬ã€ã¢ãŠãã°ã«ãŒãã䜿çšããŸããçŸããã¢ã€ãã ã®ãªã¹ããå
¥æããŸããããã ãããªã¹ãã®ã³ã³ãã³ãã®ãµã€ãºã¯ã¢ã€ãã ã®å®éã®æ°ã«èª¿æŽãããŸããããããã£ãŠãã¹ã¯ããŒã«ããŒã®ãµã€ãºã¯å€æŽãããŸãããç§ãã¡ã¯ãäœãããšãã§ããã³ã³ãã³ããèªåçã«ã³ã³ããŒãã³ãå ããããšã«ããããµã€ãºå€æŽãã³ã³ãã³ãã®ãµã€ãºãã£ãã¿ãŒïŒã³ã³ããŒãã³ã/ã¬ã€ã¢ãŠã/ã³ã³ãã³ããµã€ãºãã£ãã¿ãïŒããã®åçŽãã£ããã¢ãŒããPreferred Sizeã«èšå®ããå¿
èŠããããŸããã³ã³ãã³ããµã€ãºãã£ãã¿ãŒã䜿çšããŸããå°æ°ã®ãã€ã³ãã§ãã¹ã¯ããŒã«ããŒãæ¶ããŸãããŸãããªã¹ãå
ã®ãã¥ãŒããŒãã«åãŸããªãã¢ã€ãã ãå€ãããå Žåãã¹ã¯ããŒã«ããŒã衚瀺ãããé©åãªãµã€ãºã«ãªããŸããã¹ã¯ããŒã«ããŒã衚瀺ãããŸããã«ãŒãã®åé€
ããã§ãå€ãã®ããããã¡ã€ã«ãç°¡åã«æäœã§ããŸãããã ããå Žåã«ãã£ãŠã¯äžéšã®ã«ãŒããåãé€ãå¿
èŠããããŸãããããè¡ãã«ã¯ãåé€ãã¿ã³ã䜿çšã§ããŸãããã®ããã®ã¡ãœãããäœæãããã¿ã³ããåŒã³åºããŠã¿ãŸããããéžæãããã¹ãããå Žåã¯ãåã«ã§åé€ãFile.Delete
ãŸãã public void Delete () { string path = GetSelectedPath(); if (path == null) { return; } File.Delete(path); }
ããã§ã¯ãå®éã«ååšãããã¡ã€ã«ã§äœæ¥ããŠããããšã確èªããå¿
èŠããããŸããããã§ãªãå Žåã¯ãåé€ããããšããã¹ãã§ã¯ãããŸãããããšã©ãŒã«ã¯ãªããŸããã if (File.Exists(path)) { File.Delete(path); }
ã«ãŒããåãå€ããåŸãã¡ãã¥ãŒãéããå¿
èŠã¯ãããŸãããããã«ãããäžåºŠã«è€æ°ã®ãã¡ã€ã«ãç°¡åã«åé€ã§ããŸãããã ããåé€åŸã¯ãååã®å
¥åãã¯ãªã¢ãããšãšãã«ããã¡ã€ã«ã®ãªã¹ããæŽæ°ããå¿
èŠããããŸãã if (File.Exists(path)) { File.Delete(path); } nameInput.text = ""; FillList();
ãŠããã£ããã±ãŒãžããŒã14ïŒã¬ãªãŒããã¯ã¹ãã£
- é ç¹ã«ã©ãŒã䜿çšããŠãã¹ãã©ããããããäœæããŸãã
- é
åãã¯ã¹ãã£ã¢ã»ããã®äœæã
- ã¡ãã·ã¥ã«æšé«ã€ã³ããã¯ã¹ã远å ããŸãã
- ã¬ãªãŒããã¯ã¹ãã£éã®é·ç§»ã
ãã®ç¬éãŸã§ãç§ãã¡ã¯ã«ãŒããçè²ããããã«åè²ã䜿çšããŠããŸãããæ¬¡ã«ããã¯ã¹ãã£ãé©çšããŸãããã¯ã¹ãã£ã®æç»ã3çš®é¡ã®æ··åç©
åäžãªè²ã¯æããã«èå¥å¯èœã§ãã¿ã¹ã¯ã«å®å
šã«å¯Ÿå¿ããŠããŸãããããŸãé¢çœãèŠããŸããããã¯ã¹ãã£ã䜿çšãããšããããã®é
åã倧å¹
ã«åäžããŸãããã¡ããããã®ããã«ã¯è²ã ãã§ãªããã¯ã¹ãã£ãæ··ããå¿
èŠããããŸããRendering 3ãã¥ãŒããªã¢ã«ããã¯ã¹ãã£ã®çµåã§ãã¹ãã©ãããããã䜿çšããŠè€æ°ã®ãã¯ã¹ãã£ãæ··åããæ¹æ³ã«ã€ããŠèª¬æããŸãããå
è§åœ¢ã®ãããã§ã¯ãåæ§ã®ã¢ãããŒãã䜿çšã§ããŸããRendering 3ãã¥ãŒããªã¢ã«4ã€ã®ãã¯ã¹ãã£ã®ã¿ãæ··åããã1ã€ã®ã¹ãã©ãããããã§æå€§5ã€ã®ãã¯ã¹ãã£ããµããŒãã§ããŸããçŸæç¹ã§ã¯5ã€ã®ç°ãªãè²ã䜿çšããŠãããããããã¯éåžžã«é©ããŠããŸãããã ããåŸã§ä»ã®ã¿ã€ãã远å ã§ããŸãããããã£ãŠãä»»æã®æ°ã®ææžã¿ã€ãã®ãµããŒããå¿
èŠã§ãããã¯ã¹ãã£ããããã£ãæç€ºçã«èšå®ããŠäœ¿çšããå Žåãããã¯äžå¯èœã§ããããããã¯ã¹ãã£ã®é
åã䜿çšããå¿
èŠããããŸããåŸã§äœæããŸãããã¯ã¹ãã£é
åã䜿çšããå Žåãã·ã§ãŒããŒã«æ··åãããã¯ã¹ãã£ãäœããã®æ¹æ³ã§äŒããå¿
èŠããããŸããæãé£ããããã·ã³ã°ã¯ãäžè§åœ¢ã®äžè§åœ¢ã«å¿
èŠã§ããäžè§åœ¢ã¯ãç¬èªã®ã¿ã€ãã®å°åœ¢ãæã€3ã€ã®ã»ã«ã®éã«ããå ŽåããããŸãããããã£ãŠãäžè§åœ¢ããšã«3ã€ã®ã¿ã€ãã®æ··åãµããŒããå¿
èŠã§ããã¹ãã©ããããããšããŠé ç¹ã«ã©ãŒã䜿çšãã
ã©ã®ãã¯ã¹ãã£ãæ··åããããäŒããããšãã§ãããšä»®å®ãããšãé ç¹ã«ã©ãŒã䜿çšããŠåäžè§åœ¢ã®ã¹ãã©ããããããäœæã§ããŸãããããã®å Žåãæå€§3ã€ã®ãã¯ã¹ãã£ã䜿çšããããããå¿
èŠãªã«ã©ãŒãã£ãã«ã¯3ã€ã ãã§ããèµ€ã¯æåã®ãã¯ã¹ãã£ãç·ã¯2çªç®ãéã¯3çªç®ã®ãã¯ã¹ãã£ã衚ããŸããäžè§åœ¢ã®ã¹ãã©ããããããäžè§åœ¢ã®ã¹ãã©ãããããã®åèšã¯åžžã«1ã«çããã§ããïŒã¯ã . . , (1, 0, 0) , (œ, œ, 0) (⅓, ⅓, ⅓) .
äžè§åœ¢ã«å¿
èŠãªãã¯ã¹ãã£ã1ã€ã ãã®å Žåãæåã®ãã£ãã«ã®ã¿ã䜿çšããŸããã€ãŸãããã®è²ã¯å®å
šã«èµ€ã«ãªããŸãã2ã€ã®ç°ãªãã¿ã€ããæ··åããå Žåãæåãš2çªç®ã®ãã£ãã«ã䜿çšããŸããã€ãŸããäžè§åœ¢ã®è²ã¯èµ€ãšç·ã®æ··åã«ãªããŸãããããŠã3ã€ã®ã¿ã€ããã¹ãŠãåºäŒããšãèµ€ãç·ãéã®æ··åç©ã«ãªããŸãã3ã€ã®ã¹ãã©ãããããæ§æãã©ã®ãã¯ã¹ãã£ãå®éã«ããã¯ã¹ããããã«é¢ä¿ãªãããããã®ã¹ãã©ãããããæ§æã䜿çšããŸããã€ãŸããã¹ãã©ãããããã¯åžžã«åãã«ãªããŸãããã¯ã¹ãã£ã®ã¿ã倿ŽãããŸãããããè¡ãæ¹æ³ã¯ãåŸã§ç¢ºèªããŸããã»ã«ã®è²ã䜿çšããã®ã§ã¯ãªãããããã®ã¹ãã©ããããããäœæããHexGridChunk
ããã«å€æŽããå¿
èŠããããŸãããã°ãã°3è²ã䜿çšããããããããã®éçãã£ãŒã«ããäœæããŸãã static Color color1 = new Color(1f, 0f, 0f); static Color color2 = new Color(0f, 1f, 0f); static Color color3 = new Color(0f, 0f, 1f);
ã»ã«ã»ã³ã¿ãŒ
ããã©ã«ãã§ã»ã«ã®äžå¿ã®è²ã眮ãæããããšããå§ããŸããããããã§ã¯ãã¬ã³ãã¯è¡ãããªããããæåã®è²ãã€ãŸãèµ€ã䜿çšããŸãã void TriangulateWithoutRiver ( HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e ) { TriangulateEdgeFan(center, e, color1); ⊠}
ã»ã«ã®èµ€ãäžå¿ãã»ã«ã®äžå¿ãèµ€ã«å€ãããŸãããããã¯ãã¹ãŠããã¯ã¹ãã£ãäœã§ãããã«é¢ä¿ãªãã3ã€ã®ãã¯ã¹ãã£ã®æåã®ãã®ã䜿çšããŸããã¹ãã©ãããããã¯ãã»ã«ãè²ä»ãããè²ã«é¢ä¿ãªãåãã§ããå·ã®è¿æ
ã»ã«ãæµããå·ã®ãªãã»ã«å
ã§ã®ã¿ã»ã°ã¡ã³ãã倿ŽããŸãããå·ã«é£æ¥ããã»ã°ã¡ã³ãã«ã€ããŠãåæ§ã«ããå¿
èŠããããŸããç§ãã¡ã®å Žåãããã¯ãªãã¹ããªãããšãªãã®äžè§åœ¢ã®æã®äž¡æ¹ã§ããããã§ããèµ€ã ãã§ååã§ãã void TriangulateAdjacentToRiver ( HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e ) { ⊠TriangulateEdgeStrip(m, color1, e, color1); TriangulateEdgeFan(center, m, color1); ⊠}
å·ã«é£æ¥ããèµ€ãã»ã°ã¡ã³ããå·
次ã«ãã»ã«å
ã®å·ã®åœ¢ç¶ã«æ³šæããå¿
èŠããããŸãããããããã¹ãŠèµ€ã«å€ãããŸãããŸããå·ã®å§ãŸããšçµãããèŠãŠã¿ãŸãããã void TriangulateWithRiverBeginOrEnd ( HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e ) { ⊠TriangulateEdgeStrip(m, color1, e, color1); TriangulateEdgeFan(center, m, color1); ⊠}
ãããŠãåæãšå·åºãæ§æãããžãªã¡ããªãã³ãŒããèªã¿ãããããããã«ãã«ã©ãŒã¡ãœããåŒã³åºããã°ã«ãŒãåããŸããã void TriangulateWithRiver ( HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e ) { ⊠TriangulateEdgeStrip(m, color1, e, color1); terrain.AddTriangle(centerL, m.v1, m.v2);
ã»ã«ã«æ²¿ã£ãã¬ãããªããŒããªã
ç°ãªãã¿ã€ãã®å°åœ¢ãæã€ããšãã§ããã»ã«ã®éã«ããããããã¹ãŠã®ãšããžã¯ç°ãªããŸããçŸåšã®ã»ã«ã¿ã€ãã«ã¯æåã®è²ã䜿çšãã飿¥ã»ã«ã¿ã€ãã«ã¯2çªç®ã®è²ã䜿çšããŸãããã®çµæãäž¡æ¹ã®ã»ã«ãåãã¿ã€ãã§ãã£ãŠããã¹ãã©ãããããã¯èµ€ç·ã®ã°ã©ããŒã·ã§ã³ã«ãªããŸããäž¡æ¹ã®ã»ã«ãåããã¯ã¹ãã£ã䜿çšããå Žåãããã¯äž¡åŽã®åããã¯ã¹ãã£ã®æ··åã«ãªããŸãã void TriangulateConnection ( HexDirection direction, HexCell cell, EdgeVertices e1 ) { ⊠if (cell.GetEdgeType(direction) == HexEdgeType.Slope) { TriangulateEdgeTerraces(e1, cell, e2, neighbor, hasRoad); } else { TriangulateEdgeStrip(e1, color1, e2, color2, hasRoad); } ⊠}
æ£ãé€ãèµ€ç·ã®ãªããèµ€ãšç·ã®æ¥æ¿ãªç§»è¡ã¯åé¡ãåŒãèµ·ãããŸãããïŒ, , . . splat map, . .
, .
åºã£åŒµãã®ãããšããžã¯ãé ç¹ã远å ãããŠãããããããå°ãè€éã§ãã幞ããªããšã«ãæ¢åã®è£éã³ãŒãã¯ãã¹ãã©ãããããã®è²ã«æé©ã§ããæåãšæåŸã®ã»ã«ã®è²ã§ã¯ãªããæåãš2çªç®ã®è²ã䜿çšããŠãã ããã void TriangulateEdgeTerraces ( EdgeVertices begin, HexCell beginCell, EdgeVertices end, HexCell endCell, bool hasRoad ) { EdgeVertices e2 = EdgeVertices.TerraceLerp(begin, end, 1); Color c2 = HexMetrics.TerraceLerp(color1, color2, 1); TriangulateEdgeStrip(begin, color1, e2, c2, hasRoad); for (int i = 2; i < HexMetrics.terraceSteps; i++) { EdgeVertices e1 = e2; Color c1 = c2; e2 = EdgeVertices.TerraceLerp(begin, end, i); c2 = HexMetrics.TerraceLerp(color1, color2, i); TriangulateEdgeStrip(e1, c1, e2, c2, hasRoad); } TriangulateEdgeStrip(e2, c2, end, color2, hasRoad); }
green骚ã®èµ€ç·ã®æ£ãè§åºŠ
ã»ã«è§åºŠã¯ã3ã€ã®ç°ãªããã¯ã¹ãã£ãæ··åããå¿
èŠããããããæãå°é£ã§ããäžã®ããŒã¯ã«èµ€ãå·Šã«ç·ãå³ã«éã䜿çšããŸãã1ã€ã®äžè§åœ¢ã®è§ããå§ããŸãããã void TriangulateCorner ( Vector3 bottom, HexCell bottomCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell ) { ⊠else { terrain.AddTriangle(bottom, left, right); terrain.AddTriangleColor(color1, color2, color3); } features.AddWall(bottom, bottomCell, left, leftCell, right, rightCell); }
æ£ãé€ãèµ€ãç·ãéã®è§ãããã§ããåºã£åŒµãã®ããã³ãŒããŒã«æ¢åã®ã«ã©ãŒè£éã³ãŒãã䜿çšã§ããŸããè£éã¯2è²ã§ã¯ãªã3è²ã®éã§è¡ãããŸããæåã«ãåŽã®è¿ãã«ãªãæ£ãèããŠãã ããã void TriangulateCornerTerraces ( Vector3 begin, HexCell beginCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell ) { Vector3 v3 = HexMetrics.TerraceLerp(begin, left, 1); Vector3 v4 = HexMetrics.TerraceLerp(begin, right, 1); Color c3 = HexMetrics.TerraceLerp(color1, color2, 1); Color c4 = HexMetrics.TerraceLerp(color1, color3, 1); terrain.AddTriangle(begin, v3, v4); terrain.AddTriangleColor(color1, c3, c4); for (int i = 2; i < HexMetrics.terraceSteps; i++) { Vector3 v1 = v3; Vector3 v2 = v4; Color c1 = c3; Color c2 = c4; v3 = HexMetrics.TerraceLerp(begin, left, i); v4 = HexMetrics.TerraceLerp(begin, right, i); c3 = HexMetrics.TerraceLerp(color1, color2, i); c4 = HexMetrics.TerraceLerp(color1, color3, i); terrain.AddQuad(v1, v2, v3, v4); terrain.AddQuadColor(c1, c2, c3, c4); } terrain.AddQuad(v3, v4, left, right); terrain.AddQuadColor(c3, c4, color2, color3); }
åŽã«æ²¿ã£ãæ£ãé€ããèµ€ç·éã®ã³ãŒããŒæ£ãåŽã«é¢ããŠã¯ãã¡ãœããã䜿çšããå¿
èŠããããŸãTriangulateBoundaryTriangle
ããã®ã¡ãœããã¯ãéå§ã»ã«ãšå·Šã»ã«ããã©ã¡ãŒã¿ãŒãšããŠåãåããŸããããã ããé©åãªã¹ãã©ããã«ã©ãŒãå¿
èŠã«ãªããŸãããããã¯ãããããžã«ãã£ãŠç°ãªãå ŽåããããŸãããããã£ãŠããããã®ãã©ã¡ãŒã¿ãŒãè²ã«çœ®ãæããŸãã void TriangulateBoundaryTriangle ( Vector3 begin, Color beginColor, Vector3 left, Color leftColor, Vector3 boundary, Color boundaryColor ) { Vector3 v2 = HexMetrics.Perturb(HexMetrics.TerraceLerp(begin, left, 1)); Color c2 = HexMetrics.TerraceLerp(beginColor, leftColor, 1); terrain.AddTriangleUnperturbed(HexMetrics.Perturb(begin), v2, boundary); terrain.AddTriangleColor(beginColor, c2, boundaryColor); for (int i = 2; i < HexMetrics.terraceSteps; i++) { Vector3 v1 = v2; Color c1 = c2; v2 = HexMetrics.Perturb(HexMetrics.TerraceLerp(begin, left, i)); c2 = HexMetrics.TerraceLerp(beginColor, leftColor, i); terrain.AddTriangleUnperturbed(v1, v2, boundary); terrain.AddTriangleColor(c1, c2, boundaryColor); } terrain.AddTriangleUnperturbed(v2, HexMetrics.Perturb(left), boundary); terrain.AddTriangleColor(c2, leftColor, boundaryColor); }
TriangulateCornerTerracesCliff
æ£ããè²ã䜿çšããããã«å€æŽããŠãã ããã void TriangulateCornerTerracesCliff ( Vector3 begin, HexCell beginCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell ) { ⊠Color boundaryColor = Color.Lerp(color1, color3, b); TriangulateBoundaryTriangle( begin, color1, left, color2, boundary, boundaryColor ); if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope) { TriangulateBoundaryTriangle( left, color2, right, color3, boundary, boundaryColor ); } else { terrain.AddTriangleUnperturbed( HexMetrics.Perturb(left), HexMetrics.Perturb(right), boundary ); terrain.AddTriangleColor(color2, color3, boundaryColor); } }
ãããŠãåãããšãè¡ãTriangulateCornerCliffTerraces
ãŸãã void TriangulateCornerCliffTerraces ( Vector3 begin, HexCell beginCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell ) { ⊠Color boundaryColor = Color.Lerp(color1, color2, b); TriangulateBoundaryTriangle( right, color3, begin, color1, boundary, boundaryColor ); if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope) { TriangulateBoundaryTriangle( left, color2, right, color3, boundary, boundaryColor ); } else { terrain.AddTriangleUnperturbed( HexMetrics.Perturb(left), HexMetrics.Perturb(right), boundary ); terrain.AddTriangleColor(color2, color3, boundaryColor); } }
å®å
šãªã¹ãã©ããã¬ãªãŒããããããŠããã£ããã±ãŒãžãã¯ã¹ãã£é
å
å°åœ¢ã«ã¹ãã©ããããããããã®ã§ããã¯ã¹ãã£ã³ã¬ã¯ã·ã§ã³ãã·ã§ãŒããŒã«æž¡ãããšãã§ããŸããé
åã¯åäžã®ãšã³ãã£ãã£ãšããŠGPUã¡ã¢ãªã«ååšããå¿
èŠããããããã·ã§ãŒããŒãCïŒãã¯ã¹ãã£ã®é
åã«å²ãåœãŠãããšã¯ã§ããŸãããTexture2DArray
ããŒãžã§ã³5.4以éãUnityã§ãµããŒããããŠããç¹å¥ãªãªããžã§ã¯ãã䜿çšããå¿
èŠããããŸãããã¹ãŠã®GPUã¯ãã¯ã¹ãã£é
åããµããŒãããŠããŸããïŒGPU , .
Unity .
- Direct3D 11/12 (Windows, Xbox One)
- OpenGL Core (Mac OS X, Linux)
- Metal (iOS, Mac OS X)
- OpenGL ES 3.0 (Android, iOS, WebGL 2.0)
- PlayStation 4
ãã¹ã¿ãŒ
æ®å¿µãªãããããŒãžã§ã³5.5ã§ã®ãã¯ã¹ãã£é
åã®Unityã®ãµããŒãã¯æå°éã§ãããã¯ã¹ãã£é
åã¢ã»ãããäœæããŠãã¯ã¹ãã£ãå²ãåœãŠãã ãã§ã¯ã§ããŸãããæåã§è¡ãå¿
èŠããããŸãããã¬ã€ã¢ãŒãã§ãã¯ã¹ãã£ã®é
åãäœæãããããšãã£ã¿ãŒã§ã¢ã»ãããäœæã§ããŸããã¢ã»ãããäœæããŸããããè³ç£ãäœæããçç±, Play . , .
, . Unity . , . , .
ãã¯ã¹ãã£ã®é
åãäœæããã«ã¯ãç¬èªã®ãã¹ã¿ãŒãçµã¿ç«ãŠãŸããã¹ã¯ãªããTextureArrayWizard
ãäœæããEditorãã©ã«ããŒå
ã«é
眮ããŸãã代ããã«ãåå空éããMonoBehaviour
åãæ¡åŒµããå¿
èŠãScriptableWizard
ãããŸãUnityEditor
ã using UnityEditor; using UnityEngine; public class TextureArrayWizard : ScriptableWizard { }
äžè¬çãªéçã¡ãœããã䜿çšããŠãŠã£ã¶ãŒããéãããšãã§ããŸãScriptableWizard.DisplayWizard
ããã®ãã©ã¡ãŒã¿ãŒã¯ããŠã£ã¶ãŒããŠã£ã³ããŠãšãã®äœæãã¿ã³ã®ååã§ãããã®ã¡ãœãããéçã¡ãœããã§åŒã³åºããŸãCreateWizard
ã static void CreateWizard () { ScriptableWizard.DisplayWizard<TextureArrayWizard>( "Create Texture Array", "Create" ); }
ãšãã£ã¿ãŒãããŠã£ã¶ãŒãã«ã¢ã¯ã»ã¹ããã«ã¯ããã®ã¡ãœãããUnityã¡ãã¥ãŒã«è¿œå ããå¿
èŠããããŸããããã¯ãã¡ãœããã«å±æ§ã远å ããããšã§å®è¡ã§ããŸãMenuItem
ããããAssetsã¡ãã¥ãŒã«ãå
·äœçã«ã¯Assets / Create / Texture Arrayã«è¿œå ããŸãããã [MenuItem("Assets/Create/Texture Array")] static void CreateWizard () { ⊠}
ã«ã¹ã¿ã ãŠã£ã¶ãŒããæ°ããã¡ãã¥ãŒé
ç®ã䜿çšããŠãã«ã¹ã¿ã ãŠã£ã¶ãŒãã®ãããã¢ããã¡ãã¥ãŒãéãããšãã§ããŸããããŸãçŸãããããŸããããåé¡ã®è§£æ±ºã«é©ããŠããŸãããã ãããŸã 空ã§ãããã¯ã¹ãã£ã®é
åãäœæããã«ã¯ããã¯ã¹ãã£ã®é
åãå¿
èŠã§ãããã¹ã¿ãŒã®äžè¬ãã£ãŒã«ãã远å ããŸãããŠã£ã¶ãŒãã®æšæºGUIã«ã¯ãæšæºã€ã³ã¹ãã¯ã¿ãŒã®ããã«è¡šç€ºãããŸãã public Texture2D[] textures;
ãã¯ã¹ãã£ã®ãã¹ã¿ãŒãäœããäœãã
ãŠã£ã¶ãŒãã®[ äœæ ]ãã¿ã³ãã¯ãªãã¯ãããšããŠã£ã¶ãŒããæ¶ããŸããããã«ãUnityã¯ã¡ãœããããªããšæå¥ãèšãOnWizardCreate
ãŸããããã¯ãäœæãã¿ã³ãã¯ãªãã¯ããããšãã«åŒã³åºãããã¡ãœãããªã®ã§ããŠã£ã¶ãŒãã«è¿œå ããå¿
èŠããããŸãã void OnWizardCreate () { }
ããã§ããã¯ã¹ãã£ã®é
åãäœæããŸããå°ãªããšãããŠãŒã¶ãŒããã¹ã¿ãŒã«ãã¯ã¹ãã£ã远å ããå Žåãããã§ãªãå Žåãäœæãããã®ã¯äœããªãã®ã§ãäœæ¥ã忢ããå¿
èŠããããŸãã void OnWizardCreate () { if (textures.Length == 0) { return; } }
次ã®ã¹ãããã¯ããã¯ã¹ãã£é
åã¢ã»ãããä¿åããå Žæããªã¯ãšã¹ãããããšã§ããã¡ãœããã䜿çšããŠããã¡ã€ã«ä¿åããã«ãéãããšãã§ããŸãEditorUtility.SaveFilePanelInProject
ããã®ãã©ã¡ãŒã¿ãŒã¯ãããã«åãããã©ã«ãã®ãã¡ã€ã«åããã¡ã€ã«æ¡åŒµåãããã³èª¬æãå®çŸ©ããŸãããã¯ã¹ãã£é
åã¯ãäžè¬çãªã¢ã»ãããã¡ã€ã«æ¡åŒµåã䜿çšããŸãã if (textures.Length == 0) { return; } EditorUtility.SaveFilePanelInProject( "Save Texture Array", "Texture Array", "asset", "Save Texture Array" );
SaveFilePanelInProject
ãŠãŒã¶ãŒãéžæãããã¡ã€ã«ãã¹ãè¿ããŸãããŠãŒã¶ãŒããã®ããã«ã§ãã£ã³ã»ã«ãã¯ãªãã¯ããå Žåããã¹ã¯ç©ºã®æååã«ãªããŸãããããã£ãŠããã®å Žåãäœæ¥ãäžæããå¿
èŠããããŸãã string path = EditorUtility.SaveFilePanelInProject( "Save Texture Array", "Texture Array", "asset", "Save Texture Array" ); if (path.Length == 0) { return; }
ãã¯ã¹ãã£ã®é
åãäœæãã
æ£ãããã¹ãããã°ã次ã«é²ã¿ãæ°ãããªããžã§ã¯ããäœæã§ããŸãTexture2DArray
ã圌ã®ã³ã³ã¹ãã©ã¯ã¿ãŒã¡ãœããã§ã¯ããã¯ã¹ãã£ã®å¹
ãšé«ããé
åã®é·ãããã¯ã¹ãã£ã®åœ¢åŒãããããã¯ã¹ãã£ãªã³ã°ã®å¿
èŠæ§ãæå®ããå¿
èŠããããŸãããããã®ãã©ã¡ãŒã¿ãŒã¯ãé
åå
ã®ãã¹ãŠã®ãã¯ã¹ãã£ã§åãã§ãªããã°ãªããŸããããªããžã§ã¯ããèšå®ããã«ã¯ãæåã®ãã¯ã¹ãã£ã䜿çšããŸãããŠãŒã¶ãŒã¯ããã¹ãŠã®ãã¯ã¹ãã£ãåã圢åŒã§ããããšã確èªããå¿
èŠããããŸãã if (path.Length == 0) { return; } Texture2D t = textures[0]; Texture2DArray textureArray = new Texture2DArray( t.width, t.height, textures.Length, t.format, t.mipmapCount > 1 );
ãã¯ã¹ãã£é
åã¯åäžã®GPUãªãœââãŒã¹ã§ããããããã¹ãŠã®ãã¯ã¹ãã£ã«åããã£ã«ã¿ãªã³ã°ã¢ãŒããšæãããã¿ã¢ãŒãã䜿çšããŸããããã§ããæåã®ãã¯ã¹ãã£ã䜿çšããŠãã¹ãŠãèšå®ããŸãã Texture2DArray textureArray = new Texture2DArray( t.width, t.height, textures.Length, t.format, t.mipmapCount > 1 ); textureArray.anisoLevel = t.anisoLevel; textureArray.filterMode = t.filterMode; textureArray.wrapMode = t.wrapMode;
ã¡ãœããã䜿çšããŠããã¯ã¹ãã£ãé
åã«ã³ããŒã§ããŸãGraphics.CopyTexture
ããã®ã¡ãœããã¯ãäžåºŠã«1ãããã¬ãã«ã®çã®ãã¯ã¹ãã£ããŒã¿ãã³ããŒããŸãããããã£ãŠããã¹ãŠã®ãã¯ã¹ãã£ãšãããã®ãããã¬ãã«ãã«ãŒãããå¿
èŠããããŸããã¡ãœãããã©ã¡ãŒã¿ã¯ããã¯ã¹ãã£ãªãœãŒã¹ãã€ã³ããã¯ã¹ãããã³ãããã¬ãã«ã§æ§æããã2ã€ã®ã»ããã§ãããœãŒã¹ãã¯ã¹ãã£ã¯é
åã§ã¯ãªããããã€ã³ããã¯ã¹ã¯åžžã«ãŒãã§ãã textureArray.wrapMode = t.wrapMode; for (int i = 0; i < textures.Length; i++) { for (int m = 0; m < t.mipmapCount; m++) { Graphics.CopyTexture(textures[i], 0, m, textureArray, i, m); } }
ãã®æ®µéã§ãã¡ã¢ãªã«ã¯æ£ãããã¯ã¹ãã£ã®é
åããããŸããããŸã è³ç£ã§ã¯ãããŸãããæåŸã®æé ã¯AssetDatabase.CreateAsset
ãé
åãšãã®ãã¹ã䜿çšããŠåŒã³åºãããšã§ãããã®å ŽåãããŒã¿ã¯ãããžã§ã¯ãã®ãã¡ã€ã«ã«æžã蟌ãŸãããããžã§ã¯ããŠã£ã³ããŠã«è¡šç€ºãããŸãã for (int i = 0; i < textures.Length; i++) { ⊠} AssetDatabase.CreateAsset(textureArray, path);
ãã¯ã¹ãã£ãŒ
ãã¯ã¹ãã£ã®å®éã®é
åãäœæããã«ã¯ãå
ã®ãã¯ã¹ãã£ãå¿
èŠã§ãã以äžã¯ããããŸã§äœ¿çšããŠããè²ã«äžèŽãã5ã€ã®ãã¯ã¹ãã£ã§ããé»è²ãç ã«ãªããç·ãèã«ãªããéãåã«ãªãããªã¬ã³ãžãç³ã«ãªããçœãéªã«ãªããŸããç ãèãå°çãç³ãéªã®ãã¯ã¹ãã£ããããã®ãã¯ã¹ãã£ã¯ããã®ã¬ãªãŒãã®åçã§ã¯ãªãããšã«æ³šæããŠãã ããããããã¯ãNumberFlowã䜿çšããŠäœæãã軜éã®æ¬äŒŒã©ã³ãã ãã¿ãŒã³ã§ããç§ã¯ãæœè±¡çãªå€è§åœ¢ã®ã¬ãªãŒããšççŸããªããèªèå¯èœãªã¬ãªãŒãã®ã¿ã€ããšè©³çްãäœæããããåªããŸããããã©ããªã¢ãªãºã ã¯ããã«é©ããªãããšã倿ããŸãããããã«ããã¿ãŒã³ã¯å€åæ§ã远å ããŸãããç¹°ãè¿ããããã«ç®ç«ã€ããã«ãããã¿ãŒã³ã¯ã»ãšãã©ãããŸããããããã®ãã¯ã¹ãã£ããã¹ã¿ãŒé
åã«è¿œå ãããã®é åºãè²ãšäžèŽããããšã確èªããŸããã€ãŸããæåã«ç ãæ¬¡ã«èãåãç³ããããŠæåŸã«éªã§ãããã¯ã¹ãã£ã®é
åãäœæããŸãããã¯ã¹ãã£é
åã¢ã»ãããäœæãããããããéžæããŠã€ã³ã¹ãã¯ã¿ãŒã§èª¿ã¹ãŸãããã¯ã¹ãã£é
åã€ã³ã¹ãã¯ã¿ãŒãããã¯ããã¯ã¹ãã£é
åã®ããŒã¿ã®æãåçŽãªè¡šç€ºã§ããæåã«ãªã³ã«ãªã£ãŠããIs Readableã¹ã€ãããããããšã«æ³šæããŠãã ãããé
åãããã¯ã»ã«ããŒã¿ãèªã¿åãå¿
èŠããªãããããªãã«ããŸããTexture2DArray
ãã®ãã©ã¡ãŒã¿ãŒã«ã¢ã¯ã»ã¹ããã¡ãœãããŸãã¯ããããã£ããªãããããŠã£ã¶ãŒãã§ãããè¡ãããšã¯ã§ããŸãããïŒã§ã¯ãŠããã£5.6ã¯ãåšãã«ã¯åæãããã«ãå¯èœã§ãããè€æ°ã®ãã©ãããã©ãŒã éã§ã®ã¢ã»ã³ããªã«ããããã¯ã¹ãã£ã®ãã°ãã®è
æã®ã¢ã¬ã€ãæããèªã¿åãå¯èœã§ãããïŒããã¯ããã£ãŒã«ããããããšã泚ç®ã«ã䟡å€ãããã«ã©ãŒã¹ããŒã¹ã¯ãå€1ãå²ãåœãŠãããŸããããã¯ããã¯ã¹ãã£ãã¬ã³ã空éã«ãããšæ³å®ãããããšãæå³ããŸããããããç·åœ¢ç©ºéã«ããããšã«ãªã£ãŠããå Žåããã£ãŒã«ãã«å€0ãå²ãåœãŠãå¿
èŠããããŸãããå®éããã¶ã€ããŒã«Texture2DArray
ã¯è²ç©ºéãèšå®ããããã®è¿œå ã®ãã©ã¡ãŒã¿ãŒããããŸãTexture2D
ããç·åœ¢ç©ºéã«ãããã©ããã¯è¡šç€ºãããªãããããããã«ããŠããèšå®ããå¿
èŠããããŸãæåã§å€ãã·ã§ãŒããŒ
ãã¯ã¹ãã£ã®é
åãã§ããã®ã§ãã·ã§ãŒããŒã«ãã®æäœæ¹æ³ãæããå¿
èŠããããŸããããã§ã¯ãVertexColorsã·ã§ãŒããŒã䜿çšããŠå°åœ¢ãã¬ã³ããªã³ã°ããŸããä»ããè²ã®ä»£ããã«ãã¯ã¹ãã£ã䜿çšããã®ã§ãååãTerrainã«å€æŽããŸããæ¬¡ã«ã_MainTexãã©ã¡ãŒã¿ãŒããã¯ã¹ãã£ã®é
åã«å€æããã¢ã»ããã«å²ãåœãŠãŸãã Shader "Custom/Terrain" { Properties { _Color ("Color", Color) = (1,1,1,1) _MainTex ("Terrain Texture Array", 2DArray) = "white" {} _Glossiness ("Smoothness", Range(0,1)) = 0.5 _Metallic ("Metallic", Range(0,1)) = 0.0 } ⊠}
ãã¯ã¹ãã£ã®é
åãå«ãã¬ãªãŒãçŽ æããã¯ã¹ãã£ã¢ã¬ã€ããµããŒããããã¹ãŠã®ãã©ãããã©ãŒã ã§ãã¯ã¹ãã£ã¢ã¬ã€ãæå¹ã«ããã«ã¯ãã·ã§ãŒããŒã®ã¿ãŒã²ããã¬ãã«ã3.0ãã3.5ã«äžããå¿
èŠããããŸãã #pragma target 3.5
倿°_MainTex
ã¯ãã¯ã¹ãã£ã®é
åãåç
§ããããã«ãªã£ããããã¿ã€ãã倿Žããå¿
èŠããããŸããã¿ã€ãã¯ã¿ãŒã²ãããã©ãããã©ãŒã ã«äŸåãããã¯ãããããåŠçãUNITY_DECLARE_TEX2DARRAY
ãŸãã
ä»ã®ã·ã§ãŒããŒãšåæ§ã«ãå°åœ¢ãã¯ã¹ãã£ããµã³ããªã³ã°ããã«ã¯ãäžçã®XZ座æšãå¿
èŠã§ãããããã£ãŠããµãŒãã§ã¹ã·ã§ãŒããŒã®å
¥åæ§é ã«ã¯ãŒã«ãå
ã®äœçœ®ã远å ããŸãããŸããããã©ã«ãã®UV座æšãå¿
èŠãªããããåé€ããŸãã struct Input {
ãã¯ã¹ãã£ã®é
åããµã³ããªã³ã°ããã«ã¯ããã¯ãã䜿çšããå¿
èŠããããŸãUNITY_SAMPLE_TEX2DARRAY
ãé
åããµã³ããªã³ã°ããã«ã¯ã3ã€ã®åº§æšãå¿
èŠã§ããæåã®2ã€ã¯éåžžã®UV座æšã§ãã0.02ã«ã¹ã±ãŒãªã³ã°ãããXZã¯ãŒã«ã座æšã䜿çšããŸãããã®ããããã«åçã§è¯å¥œãªãã¯ã¹ãã£è§£å床ãåŸãããŸãããã¯ã¹ãã£ã¯çŽ4ã»ã«ããšã«ç¹°ãè¿ãããŸãã3çªç®ã®åº§æšã¯ãéåžžã®é
åãšåæ§ã«ããã¯ã¹ãã£é
åã®ã€ã³ããã¯ã¹ãšããŠäœ¿çšãããŸãã座æšã¯æµ®åå°æ°ç¹ãªã®ã§ãGPUé
åã«ã€ã³ããã¯ã¹ãä»ããåã«åº§æšãäžžããŸããã©ã®ãã¯ã¹ãã£ãå¿
èŠããããããŸã§ãåžžã«æåã®ãã¯ã¹ãã£ã䜿çšããŸãããããŸããé ç¹ã®è²ã¯ã¹ãã©ãããããã§ãããããæçµçµæã«åœ±é¿ããŸããã void surf (Input IN, inout SurfaceOutputStandard o) { float2 uv = IN.worldPos.xz * 0.02; fixed4 c = UNITY_SAMPLE_TEX2DARRAY(_MainTex, float3(uv, 0)); Albedo = c.rgb * _Color; o.Metallic = _Metallic; o.Smoothness = _Glossiness; o.Alpha = ca; }
ãã¹ãŠãç ã«ãªããŸããããŠããã£ããã±ãŒãžãã¯ã¹ãã£éžæ
äžè§åœ¢ããšã«3ã€ã®ã¿ã€ããæ··åšãããã¬ãªãŒãã¹ãã©ããããããå¿
èŠã§ãããã¯ã¹ãã£ã®é
åããããå°åœ¢ã®ã¿ã€ãããšã«ãã¯ã¹ãã£ããããŸãããã¯ã¹ãã£é
åããµã³ããªã³ã°ããã·ã§ãŒããŒããããŸãããã ããçŸæç¹ã§ã¯ãåäžè§åœ¢ã«éžæãããã¯ã¹ãã£ãã·ã§ãŒããŒã«äŒããæ¹æ³ã¯ãããŸãããåäžè§åœ¢ã«ã¯æå€§3ã€ã®ã¿ã€ããæ··åšããŠãããããåäžè§åœ¢ã«3ã€ã®ã€ã³ããã¯ã¹ãé¢é£ä»ããå¿
èŠããããŸããäžè§åœ¢ã®æ
å ±ãä¿åã§ããªããããé ç¹ã®ã€ã³ããã¯ã¹ãä¿åããå¿
èŠããããŸããäžè§åœ¢ã®3ã€ã®é ç¹ã¯ãã¹ãŠãåè²ã®å Žåãšåãã€ã³ããã¯ã¹ãåçŽã«æ ŒçŽããŸããã¡ãã·ã¥ããŒã¿
ã€ã³ããã¯ã¹ãä¿åããããã«ãUVã¡ãã·ã¥ã®ã»ããã®1ã€ã䜿çšã§ããŸããåé ç¹ã«3ã€ã®ã€ã³ããã¯ã¹ãæ ŒçŽãããŠãããããæ¢åã®2D UVã»ããã§ã¯ååã§ã¯ãããŸããã幞ããªããšã«ãUVã»ããã«ã¯æå€§4ã€ã®åº§æšãå«ããããšãã§ããŸãããããã£ãŠãHexMesh
2çªç®ã®ãªã¹ãã«è¿œå ããVector3
ãããã¬ãªãŒãã¿ã€ããšåŒã³ãŸãã public bool useCollider, useColors, useUVCoordinates, useUV2Coordinates; public bool useTerrainTypes; [NonSerialized] List<Vector3> vertices, terrainTypes;
ãã¬ããã®Hex Grid Chunkã®Terrainåãªããžã§ã¯ãã®å°åœ¢ã¿ã€ããæå¹ã«ããŸãããªãªãŒãã¿ã€ãã䜿çšããŠããŸããå¿
èŠã«å¿ããŠãVector3
ã¡ãã·ã¥ã¯ãªãŒãã³ã°äžã«ã¬ãªãŒãã¿ã€ãã®å¥ã®ãªã¹ããååŸããŸãã public void Clear () { ⊠if (useTerrainTypes) { terrainTypes = ListPool<Vector3>.Get(); } triangles = ListPool<int>.Get(); }
ã¡ãã·ã¥ããŒã¿ãé©çšããããã»ã¹ã§ã¯ã3çªç®ã®UVã»ããã«ã¬ãªãŒãã¿ã€ããä¿åããŸãããã®ãããäžç·ã«äœ¿çšããããšã«æ±ºããå Žåãä»ã®2ã€ã®ã»ãããšç«¶åããããšã¯ãããŸããã public void Apply () { ⊠if (useTerrainTypes) { hexMesh.SetUVs(2, terrainTypes); ListPool<Vector3>.Add(terrainTypes); } hexMesh.SetTriangles(triangles, 0); ⊠}
äžè§åœ¢ã®ã¬ãªãŒãã¿ã€ããèšå®ããã«ã¯ãã䜿çšããŸãVector3
ããããã¯äžè§åœ¢å
šäœã§åãã§ãããããåãããŒã¿ã3å远å ããã ãã§ãã public void AddTriangleTerrainTypes (Vector3 types) { terrainTypes.Add(types); terrainTypes.Add(types); terrainTypes.Add(types); }
ã¯ã¯ããã§ã®æ··åãåãããã«æ©èœããŸãã4ã€ã®é ç¹ã¯ãã¹ãŠåãã¿ã€ãã§ãã public void AddQuadTerrainTypes (Vector3 types) { terrainTypes.Add(types); terrainTypes.Add(types); terrainTypes.Add(types); terrainTypes.Add(types); }
ãªãã®äžè§åœ¢ã®ãã¡ã³
次ã«ãã®ã¡ãã·ã¥ããŒã¿ã«åã远å ããå¿
èŠãããHexGridChunk
ãŸããããå§ããŸãããTriangulateEdgeFan
ããŸããèªã¿ãããããããã«ãé ç¹ã¡ãœãããšã«ã©ãŒã¡ãœããã®åŒã³åºããåé¢ããŸãããã®ã¡ãœãããåŒã³åºããã³ã«ããã圌color1
ã«æž¡ãã®ã§ããã®è²ãçŽæ¥äœ¿çšã§ãããã©ã¡ãŒã¿ãŒãé©çšããªãããšãæãåºããŠãã ããã void TriangulateEdgeFan (Vector3 center, EdgeVertices edge, Color color) { terrain.AddTriangle(center, edge.v1, edge.v2);
è²ã®åŸã«ãã¬ãªãŒãã¿ã€ãã远å ããŸããäžè§åœ¢ã®ã¿ã€ãã¯ç°ãªãå Žåããããããããã¯è²ã眮ãæãããã©ã¡ãŒã¿ãŒã§ããå¿
èŠããããŸãããã®åçŽãªã¿ã€ãã䜿çšããŠãäœæããŸãVector3
ããã®å Žåãã¹ãã©ãããããã¯åžžã«èµ€ã§ãããããæåã®4ã€ã®ãã£ãã«ã®ã¿ãéèŠã§ãããã¯ãã«ã®3ã€ã®ã³ã³ããŒãã³ããã¹ãŠãå²ãåœãŠãå¿
èŠãããããã1ã€ã®ã¿ã€ããå²ãåœãŠãŸãããã void TriangulateEdgeFan (Vector3 center, EdgeVertices edge, float type) { ⊠Vector3 types; types.x = types.y = types.z = type; terrain.AddTriangleTerrainTypes(types); terrain.AddTriangleTerrainTypes(types); terrain.AddTriangleTerrainTypes(types); terrain.AddTriangleTerrainTypes(types); }
次ã«ããã®ã¡ãœããã®ãã¹ãŠã®åŒã³åºãã倿ŽããŠãè²ã®åŒæ°ãã»ã«ã®å°åœ¢ã®ã¿ã€ãã®ã€ã³ããã¯ã¹ã«çœ®ãæããå¿
èŠããããŸããTriangulateWithoutRiver
ãTriangulateAdjacentToRiver
ããã³ã§ãã®å€æŽãè¡ãTriangulateWithRiverBeginOrEnd
ãŸãã
ãã®æç¹ã§ãåçã¢ãŒããéå§ãããšãUVã¡ãã·ã¥ã®3çªç®ã®ã»ãããç¯å²å€ã§ããããšãéç¥ãããšã©ãŒã衚瀺ãããŸããããã¯ãåäžè§åœ¢ãšåè§åœ¢ã«ãŸã ã¬ãªãŒãã¿ã€ãã远å ããŠããªãããã«çºçããŸãããããã§ã倿Žãç¶ããŸãããHexGridChunk
ããªãã¹ãã©ã€ã
ããã§ããšããžã¹ããªãããäœæãããšããäž¡åŽã«ã©ã®ãããªå°åœ¢ãããããç¥ãå¿
èŠããããŸãããããã£ãŠããããããã©ã¡ãŒã¿ãŒãšããŠè¿œå ãã2ã€ã®ãã£ãã«ã«ãããã®ã¿ã€ããå²ãåœãŠãããŠããã¿ã€ãã®ãã¯ãã«ãäœæããŸãã3çªç®ã®ãã£ãã«ã¯éèŠã§ã¯ãããŸããããããã£ãŠãæåã®ãã£ãã«ãšåäžèŠããŠãã ãããè²ã远å ããããã¯ã¯ããã«ã¿ã€ãã远å ããŸãã void TriangulateEdgeStrip ( EdgeVertices e1, Color c1, float type1, EdgeVertices e2, Color c2, float type2, bool hasRoad = false ) { terrain.AddQuad(e1.v1, e1.v2, e2.v1, e2.v2); terrain.AddQuad(e1.v2, e1.v3, e2.v2, e2.v3); terrain.AddQuad(e1.v3, e1.v4, e2.v3, e2.v4); terrain.AddQuad(e1.v4, e1.v5, e2.v4, e2.v5); terrain.AddQuadColor(c1, c2); terrain.AddQuadColor(c1, c2); terrain.AddQuadColor(c1, c2); terrain.AddQuadColor(c1, c2); Vector3 types; types.x = types.z = type1; types.y = type2; terrain.AddQuadTerrainTypes(types); terrain.AddQuadTerrainTypes(types); terrain.AddQuadTerrainTypes(types); terrain.AddQuadTerrainTypes(types); if (hasRoad) { TriangulateRoadSegment(e1.v2, e1.v3, e1.v4, e2.v2, e2.v3, e2.v4); } }
ä»ãç§ãã¡ã¯èª²é¡ãå€ããå¿
èŠãããTriangulateEdgeStrip
ãŸãããŸãTriangulateAdjacentToRiver
ãTriangulateWithRiverBeginOrEnd
ãããŠTriangulateWithRiver
ããªãã¯ããã£ã³ã¹ããªããã®äž¡åŽã®ããã®çްèåã䜿çšããå¿
èŠããããŸãã
次ã«ããšããžã®æãåçŽãªã±ãŒã¹ã§ã¯TriangulateConnection
ãæãè¿ããšããžã«ã¯ã»ã«ã¿ã€ãã䜿çšããé ããšããžã«ã¯é£æ¥ã¿ã€ãã䜿çšããå¿
èŠããããŸãããããã¯åãã§ãç°ãªã£ãŠããŠãããŸããŸããã void TriangulateConnection ( HexDirection direction, HexCell cell, EdgeVertices e1 ) { ⊠if (cell.GetEdgeType(direction) == HexEdgeType.Slope) { TriangulateEdgeTerraces(e1, cell, e2, neighbor, hasRoad); } else {
åãTriangulateEdgeTerraces
ããšã3åããªã¬ãŒããããã®ã«ãåœãŠã¯ãŸããŸãTriangulateEdgeStrip
ãæ£ã®ã¿ã€ãã¯åãã§ãã void TriangulateEdgeTerraces ( EdgeVertices begin, HexCell beginCell, EdgeVertices end, HexCell endCell, bool hasRoad ) { EdgeVertices e2 = EdgeVertices.TerraceLerp(begin, end, 1); Color c2 = HexMetrics.TerraceLerp(color1, color2, 1); float t1 = beginCell.TerrainTypeIndex; float t2 = endCell.TerrainTypeIndex; TriangulateEdgeStrip(begin, color1, t1, e2, c2, t2, hasRoad); for (int i = 2; i < HexMetrics.terraceSteps; i++) { EdgeVertices e1 = e2; Color c1 = c2; e2 = EdgeVertices.TerraceLerp(begin, end, i); c2 = HexMetrics.TerraceLerp(color1, color2, i); TriangulateEdgeStrip(e1, c1, t1, e2, c2, t2, hasRoad); } TriangulateEdgeStrip(e2, c2, t1, end, color2, t2, hasRoad); }
è§åºŠ
è§åºŠã®æãåçŽãªå Žåã¯ãåçŽãªäžè§åœ¢ã§ããäžã®ã»ã«ã¯æåã®ã¿ã€ããå·Šã¯2çªç®ãå³ã¯3çªç®ã®ã¿ã€ããéä¿¡ããŸãããããã䜿çšããŠãã¿ã€ãã®ãã¯ãã«ãäœæããäžè§åœ¢ã«è¿œå ããŸãã void TriangulateCorner ( Vector3 bottom, HexCell bottomCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell ) { ⊠else { terrain.AddTriangle(bottom, left, right); terrain.AddTriangleColor(color1, color2, color3); Vector3 types; types.x = bottomCell.TerrainTypeIndex; types.y = leftCell.TerrainTypeIndex; types.z = rightCell.TerrainTypeIndex; terrain.AddTriangleTerrainTypes(types); } features.AddWall(bottom, bottomCell, left, leftCell, right, rightCell); }
ã§åãã¢ãããŒãã䜿çšããŸãããTriangulateCornerTerraces
ããã§ã¯ã¯ã¯ããã®ã°ã«ãŒããäœæããŸãã void TriangulateCornerTerraces ( Vector3 begin, HexCell beginCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell ) { Vector3 v3 = HexMetrics.TerraceLerp(begin, left, 1); Vector3 v4 = HexMetrics.TerraceLerp(begin, right, 1); Color c3 = HexMetrics.TerraceLerp(color1, color2, 1); Color c4 = HexMetrics.TerraceLerp(color1, color3, 1); Vector3 types; types.x = beginCell.TerrainTypeIndex; types.y = leftCell.TerrainTypeIndex; types.z = rightCell.TerrainTypeIndex; terrain.AddTriangle(begin, v3, v4); terrain.AddTriangleColor(color1, c3, c4); terrain.AddTriangleTerrainTypes(types); for (int i = 2; i < HexMetrics.terraceSteps; i++) { Vector3 v1 = v3; Vector3 v2 = v4; Color c1 = c3; Color c2 = c4; v3 = HexMetrics.TerraceLerp(begin, left, i); v4 = HexMetrics.TerraceLerp(begin, right, i); c3 = HexMetrics.TerraceLerp(color1, color2, i); c4 = HexMetrics.TerraceLerp(color1, color3, i); terrain.AddQuad(v1, v2, v3, v4); terrain.AddQuadColor(c1, c2, c3, c4); terrain.AddQuadTerrainTypes(types); } terrain.AddQuad(v3, v4, left, right); terrain.AddQuadColor(c3, c4, color2, color3); terrain.AddQuadTerrainTypes(types); }
æ£ãšåŽãæ··ãããšãã¯ãã䜿çšããå¿
èŠããããŸãTriangulateBoundaryTriangle
ãåãã¯ãã«ãã©ã¡ãŒã¿ãŒãæå®ããŠããã¹ãŠã®äžè§åœ¢ã«è¿œå ããã ãã§ãã void TriangulateBoundaryTriangle ( Vector3 begin, Color beginColor, Vector3 left, Color leftColor, Vector3 boundary, Color boundaryColor, Vector3 types ) { Vector3 v2 = HexMetrics.Perturb(HexMetrics.TerraceLerp(begin, left, 1)); Color c2 = HexMetrics.TerraceLerp(beginColor, leftColor, 1); terrain.AddTriangleUnperturbed(HexMetrics.Perturb(begin), v2, boundary); terrain.AddTriangleColor(beginColor, c2, boundaryColor); terrain.AddTriangleTerrainTypes(types); for (int i = 2; i < HexMetrics.terraceSteps; i++) { Vector3 v1 = v2; Color c1 = c2; v2 = HexMetrics.Perturb(HexMetrics.TerraceLerp(begin, left, i)); c2 = HexMetrics.TerraceLerp(beginColor, leftColor, i); terrain.AddTriangleUnperturbed(v1, v2, boundary); terrain.AddTriangleColor(c1, c2, boundaryColor); terrain.AddTriangleTerrainTypes(types); } terrain.AddTriangleUnperturbed(v2, HexMetrics.Perturb(left), boundary); terrain.AddTriangleColor(c2, leftColor, boundaryColor); terrain.AddTriangleTerrainTypes(types); }
TriangulateCornerTerracesCliff
éé现èã¿ã€ãã«åºã¥ããŠãã¯ãã«ãäœæããŸããæ¬¡ã«ãããã1ã€ã®äžè§åœ¢ã«è¿œå ããŠæž¡ãTriangulateBoundaryTriangle
ãŸãã void TriangulateCornerTerracesCliff ( Vector3 begin, HexCell beginCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell ) { float b = 1f / (rightCell.Elevation - beginCell.Elevation); if (b < 0) { b = -b; } Vector3 boundary = Vector3.Lerp( HexMetrics.Perturb(begin), HexMetrics.Perturb(right), b ); Color boundaryColor = Color.Lerp(color1, color3, b); Vector3 types; types.x = beginCell.TerrainTypeIndex; types.y = leftCell.TerrainTypeIndex; types.z = rightCell.TerrainTypeIndex; TriangulateBoundaryTriangle( begin, color1, left, color2, boundary, boundaryColor, types ); if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope) { TriangulateBoundaryTriangle( left, color2, right, color3, boundary, boundaryColor, types ); } else { terrain.AddTriangleUnperturbed( HexMetrics.Perturb(left), HexMetrics.Perturb(right), boundary ); terrain.AddTriangleColor(color2, color3, boundaryColor); terrain.AddTriangleTerrainTypes(types); } }
åãããšãåœãŠã¯ãŸãTriangulateCornerCliffTerraces
ãŸãã void TriangulateCornerCliffTerraces ( Vector3 begin, HexCell beginCell, Vector3 left, HexCell leftCell, Vector3 right, HexCell rightCell ) { float b = 1f / (leftCell.Elevation - beginCell.Elevation); if (b < 0) { b = -b; } Vector3 boundary = Vector3.Lerp( HexMetrics.Perturb(begin), HexMetrics.Perturb(left), b ); Color boundaryColor = Color.Lerp(color1, color2, b); Vector3 types; types.x = beginCell.TerrainTypeIndex; types.y = leftCell.TerrainTypeIndex; types.z = rightCell.TerrainTypeIndex; TriangulateBoundaryTriangle( right, color3, begin, color1, boundary, boundaryColor, types ); if (leftCell.GetEdgeType(rightCell) == HexEdgeType.Slope) { TriangulateBoundaryTriangle( left, color2, right, color3, boundary, boundaryColor, types ); } else { terrain.AddTriangleUnperturbed( HexMetrics.Perturb(left), HexMetrics.Perturb(right), boundary ); terrain.AddTriangleColor(color2, color3, boundaryColor); terrain.AddTriangleTerrainTypes(types); } }
å·
倿ŽããæåŸã®æ¹æ³ã¯ããTriangulateWithRiver
ã§ããããã§ã¯ã»ã«ã®äžå¿ã«ããã®ã§ãçŸåšã®ã»ã«ã®ã¿ã€ãã®ã¿ãæ±ã£ãŠããŸãããããã£ãŠããã®ããã®ãã¯ãã«ãäœæããäžè§åœ¢ãšåè§åœ¢ã«è¿œå ããŸãã void TriangulateWithRiver ( HexDirection direction, HexCell cell, Vector3 center, EdgeVertices e ) { ⊠terrain.AddTriangleColor(color1); terrain.AddQuadColor(color1); terrain.AddQuadColor(color1); terrain.AddTriangleColor(color1); Vector3 types; types.x = types.y = types.z = cell.TerrainTypeIndex; terrain.AddTriangleTerrainTypes(types); terrain.AddQuadTerrainTypes(types); terrain.AddQuadTerrainTypes(types); terrain.AddTriangleTerrainTypes(types); ⊠}
ã¿ã€ãããã¯ã¹
ãã®æ®µéã§ãã¡ãã·ã¥ã«ã¯å¿
èŠãªæšé«ã€ã³ããã¯ã¹ãå«ãŸããŠããŸããæ®ã£ãŠããã®ã¯ãTerrainã·ã§ãŒããŒã«åŒ·å¶çã«ãããã䜿çšãããããšã ãã§ãããã©ã°ã¡ã³ãã·ã§ãŒããŒã§ã€ã³ããã¯ã¹ãååŸããã«ã¯ãæåã«ã€ã³ããã¯ã¹ãé ç¹ã·ã§ãŒããŒã«æž¡ãå¿
èŠããããŸããæ²³å£ã·ã§ãŒããŒã§è¡ã£ãããã«ãç¬èªã®é ç¹é¢æ°ã§ãããè¡ãããšãã§ããŸãããã®å Žåãå
¥åæ§é ã«ãã£ãŒã«ãã远å ãããã®æ§é float3 terrain
ã«ã³ããŒããŸãv.texcoord2.xyz
ã #pragma surface surf Standard fullforwardshadows vertex:vert #pragma target 3.5 ⊠struct Input { float4 color : COLOR; float3 worldPos; float3 terrain; }; void vert (inout appdata_full v, out Input data) { UNITY_INITIALIZE_OUTPUT(Input, data); data.terrain = v.texcoord2.xyz; }
ãã¯ã¹ãã£é
åããã©ã°ã¡ã³ãããšã«3åãµã³ããªã³ã°ããå¿
èŠããããŸãããããã£ãŠããã¯ã¹ãã£åº§æšã®äœæãé
åã®ãµã³ããªã³ã°ã1ã€ã®ã€ã³ããã¯ã¹ã®ã¹ãã©ãããããã䜿çšãããµã³ãã«ã®å€èª¿ã«äŸ¿å©ãªé¢æ°ãäœæããŸãããã float4 GetTerrainColor (Input IN, int index) { float3 uvw = float3(IN.worldPos.xz * 0.02, IN.terrain[index]); float4 c = UNITY_SAMPLE_TEX2DARRAY(_MainTex, uvw); return c * IN.color[index]; } void surf (Input IN, inout SurfaceOutputStandard o) { ⊠}
ãã¯ãã«ãé
åãšããŠäœ¿çšã§ããŸããïŒã¯ã - color[0]
color.r
. color[1]
color.g
, .
ãã®é¢æ°ã䜿çšãããšãåçŽã«ãã¯ã¹ãã£é
åã3åãµã³ããªã³ã°ããçµæãçµã¿åãããããšãã§ããŸãã void surf (Input IN, inout SurfaceOutputStandard o) { // float2 uv = IN.worldPos.xz * 0.02; fixed4 c = GetTerrainColor(IN, 0) + GetTerrainColor(IN, 1) + GetTerrainColor(IN, 2); o.Albedo = c.rgb * _Color; o.Metallic = _Metallic; o.Smoothness = _Glossiness; o.Alpha = ca; }
ãã¯ã¹ãã£ã¬ãªãŒããããã§ããã¯ã¹ãã£ã§ã¬ãªãŒãããã€ã³ãã§ããŸããåè²ã®ããã«æ··ãããŸããã¯ãŒã«ã座æšã¯UV座æšãšããŠäœ¿çšããããããé«ãã«ãã£ãŠå€åããããšã¯ãããŸããããã®çµæãéãåŽã«æ²¿ã£ãŠããã¯ã¹ãã£ãåŒã䌞ã°ãããŸãããã¯ã¹ãã£ãããªããã¥ãŒãã©ã«ã§éåžžã«å€åããããå Žåãçµæã¯åãå
¥ããããŸãããã以å€ã®å Žåã倧ããªbigãã¹ãã¬ããããŒã¯ã衚瀺ãããŸãã远å ã®ãžãªã¡ããªãŸãã¯åŽã®ãã¯ã¹ãã£ã§é衚瀺ã«ããããšãã§ããŸããããã¥ãŒããªã¢ã«ã§ã¯ãããè¡ããŸãããã¹ã€ãŒã
ããã§ãè²ã®ä»£ããã«ãã¯ã¹ãã£ã䜿çšããå Žåããšãã£ã¿ãŒããã«ã倿Žããã®ãè«ççã§ããã¬ãªãŒããã¯ã¹ãã£ã衚瀺ããããšãã§ããçŸããã€ã³ã¿ãŒãã§ã€ã¹ãäœæã§ããŸãããæ¢åã®ã¹ããŒã ã®ã¹ã¿ã€ã«ã«å¯Ÿå¿ããç¥èªã«çŠç¹ãåœãŠãŸããææžãªãã·ã§ã³ããŸããHexCell
colorããããã£ã¯äžèŠã«ãªã£ããããåé€ããŸãã
ãŸãã®ã§HexGrid
ãããªãã¯è²ã®é
åãšããã«é¢é£ããã³ãŒããåé€ããããšãã§ããŸãã
æåŸã«ãè²ã®é
åãå¿
èŠãããŸããHexMetrics
ã
ãŠããã£ããã±ãŒãžããŒã15ïŒè·é¢
- ã°ãªããç·ã衚瀺ããŸãã
- ç·šéã¢ãŒããšããã²ãŒã·ã§ã³ã¢ãŒããåãæ¿ããŸãã
- ã»ã«éã®è·é¢ãèšç®ããŸãã
- é害ãåé¿ããæ¹æ³ãèŠã€ããŸãã
- ç§»åã®å€åè²»ãèæ
®ããŸãã
é«å質ã®ããããäœæããããããã²ãŒã·ã§ã³ãéå§ããŸããæççµè·¯ã¯å¿
ãããçŽç·ã§ã¯ãããŸãããã°ãªãã衚瀺
ãããäžã®ããã²ãŒã·ã§ã³ã¯ãã»ã«ããã»ã«ã«ç§»åããããšã«ããå®è¡ãããŸããã©ããã«å°éããã«ã¯ãäžé£ã®ã»ã«ãééããå¿
èŠããããŸããè·é¢ã®æšå®ãç°¡åã«ããããã«ããããã®ããŒã¹ãšãªãå
è§åœ¢ã®ã°ãªããã衚瀺ãããªãã·ã§ã³ã远å ããŸããããã¡ãã·ã¥ãã¯ã¹ãã£
ãããã¡ãã·ã¥ã®äžèŠåæ§ã«ãããããããåºç€ãšãªãã¡ãã·ã¥ã¯å®å
šã«å¹³ãã§ããããã瀺ãã«ã¯ãã°ãªãããã¿ãŒã³ãå°å³ã«æåœ±ããŸããããã¯ãç¹°ãè¿ãã¡ãã·ã¥ãã¯ã¹ãã£ã䜿çšããŠå®çŸã§ããŸããã¡ãã·ã¥ãã¯ã¹ãã£ãç¹°ãè¿ããŸããäžèšã®ãã¯ã¹ãã£ã«ã¯ã2 x 2ã»ã«ãã«ããŒããå
è§åœ¢ã°ãªããã®å°ããªéšåãå«ãŸããŠããŸãããã®é åã¯æ£æ¹åœ¢ã§ã¯ãªãé·æ¹åœ¢ã§ãããã¯ã¹ãã£èªäœã¯æ£æ¹åœ¢ãªã®ã§ããã¿ãŒã³ã¯åŒã䌞ã°ãããŠèŠããŸãããµã³ããªã³ã°æã«ã¯ããããè£æ£ããå¿
èŠããããŸããã°ãªããæåœ±
ã¡ãã·ã¥ãã¿ãŒã³ãæåœ±ããã«ã¯ãTerrainã·ã§ãŒããŒã«ãã¯ã¹ãã£ããããã£ã远å ããå¿
èŠããããŸãã Properties { _Color ("Color", Color) = (1,1,1,1) _MainTex ("Terrain Texture Array", 2DArray) = "white" {} _GridTex ("Grid Texture", 2D) = "white" {} _Glossiness ("Smoothness", Range(0,1)) = 0.5 _Metallic ("Metallic", Range(0,1)) = 0.0 }
ã¡ãã·ã¥ãã¯ã¹ãã£ä»ãã®ã¬ãªãŒãçŽ æãã¯ãŒã«ãã®XZ座æšã䜿çšããŠãã¯ã¹ãã£ããµã³ããªã³ã°ããã¢ã«ãããæããŸãããã¯ã¹ãã£ã®ã°ãªããç·ã¯ç°è²ã§ãããããããã«ãããã¿ãŒã³ãæµ®ã圫ãã«ç¹ã蟌ãŸããŸãã sampler2D _GridTex; ⊠void surf (Input IN, inout SurfaceOutputStandard o) { fixed4 c = GetTerrainColor(IN, 0) + GetTerrainColor(IN, 1) + GetTerrainColor(IN, 2); fixed4 grid = tex2D(_GridTex, IN.worldPos.xz); o.Albedo = c.rgb * grid * _Color; o.Metallic = _Metallic; o.Smoothness = _Glossiness; o.Alpha = ca; }
ã¢ã«ããã«çްããã¡ãã·ã¥ãæããŸãããããå
ã®ã»ã«ã«äžèŽããããã«ãã¿ãŒã³ãã¹ã±ãŒãªã³ã°ããå¿
èŠããããŸãã飿¥ããã»ã«ã®äžå¿éã®è·é¢ã¯15ã§ã2ã€ã®ã»ã«ãäžã«ç§»åããã«ã¯2åã«ããå¿
èŠããããŸããã€ãŸããVã°ãªããã®åº§æšã30ã§å²ãå¿
èŠããããŸããã»ã«ã®å
éšååŸã¯5â3ã§ããã2ã€ã®ã»ã«ãå³ã«ç§»åããã«ã¯ã4åå¿
èŠã§ãããããã£ãŠãã°ãªããã®U座æšã20â3ã§é€ç®ããå¿
èŠããããŸãã float2 gridUV = IN.worldPos.xz; gridUV.x *= 1 / (4 * 8.66025404); gridUV.y *= 1 / (2 * 15.0); fixed4 grid = tex2D(_GridTex, gridUV);
æ£ããã¡ãã·ã¥ãµã€ãºãããã§ãã°ãªããç·ã¯ãããã®ã»ã«ã«å¯Ÿå¿ããŸããã¬ãªãŒããã¯ã¹ãã£ãšåæ§ã«ãé«ãã¯ç¡èŠããããããåŽã«æ²¿ã£ãŠç·ãåŒã䌞ã°ãããŸããé«ãã®ããã»ã«ãžã®æåœ±ãã¡ãã·ã¥ã®å€åœ¢ã¯ãç¹ã«ããããé ãããèŠãå Žåãç¹ã«ããã»ã©æªãã¯ãããŸãããé ãã®ã¡ãã·ã¥ãã°ãªããæå¹å
ã°ãªããã®è¡šç€ºã¯äŸ¿å©ã§ãããåžžã«å¿
èŠãªããã§ã¯ãããŸãããããšãã°ãã¹ã¯ãªãŒã³ã·ã§ãããæ®ããšãã¯ãªãã«ããå¿
èŠããããŸããããã«ã誰ããåžžã«ã°ãªãããèŠãããšã奜ãããã§ã¯ãããŸãããããã§ã¯ããªãã·ã§ã³ã«ããŸããããmulti_compileãã£ã¬ã¯ãã£ããã·ã§ãŒããŒã«è¿œå ããŠãã°ãªããã®æç¡ã«ããããããªãã·ã§ã³ãäœæããŸãããããè¡ãã«ã¯ãããŒã¯ãŒãã䜿çšãGRID_ON
ãŸããæ¡ä»¶ä»ãã·ã§ãŒããŒã®ã³ã³ãã€ã«ã«ã€ããŠã¯ãRendering 5ãã¥ãŒããªã¢ã«ãMultiple Lightsã§èª¬æãããŠããŸãã #pragma surface surf Standard fullforwardshadows vertex:vert #pragma target 3.5 #pragma multi_compile _ GRID_ON
倿°ã宣èšãããšããgrid
æåã«å€1ãå²ãåœãŠãŸãããã®çµæãã°ãªããã¯ç¡å¹ã«ãªããŸããæ¬¡ã«ãç¹å®ã®ããŒã¯ãŒããæã€ããªã¢ã³ãã®ã°ãªãããã¯ã¹ãã£ã®ã¿ããµã³ããªã³ã°ãGRID_ON
ãŸãã fixed4 grid = 1; #if defined(GRID_ON) float2 gridUV = IN.worldPos.xz; gridUV.x *= 1 / (4 * 8.66025404); gridUV.y *= 1 / (2 * 15.0); grid = tex2D(_GridTex, gridUV); #endif o.Albedo = c.rgb * grid * _Color;
ããŒã¯ãŒãã¯GRID_ON
ãã¬ã€ã³ã·ã§ãŒããŒã«å«ãŸããŠããªããããã°ãªããã¯æ¶ããŸããåã³æå¹ã«ããã«ã¯ãããããšãã£ã¿ãŒUIã«ã¹ã€ããã远å ããŸãããããå¯èœã«ããã«HexMapEditor
ã¯ããã¬ã€ã³ãããªã¢ã«ãžã®ãªã³ã¯ãšãããŒã¯ãŒããæå¹ãŸãã¯ç¡å¹ã«ããã¡ãœãããååŸããå¿
èŠããããŸãGRID_ON
ã public Material terrainMaterial; ⊠public void ShowGrid (bool visible) { if (visible) { terrainMaterial.EnableKeyword("GRID_ON"); } else { terrainMaterial.DisableKeyword("GRID_ON"); } }
ææã«é¢ãã3æã®ç·šéè
ã®å
è§åœ¢ã ã°ãªããã¹ã€ãããUIã«è¿œå ãããããã¡ãœããã«æ¥ç¶ããŸããShowGrid
ã°ãªããã¹ã€ãããç¶æ
ãä¿å
ããã§ããã¬ã€ã¢ãŒãã§ãã°ãªããã®è¡šç€ºãåãæ¿ããããšãã§ããŸããæåã®ãã¹ãã§ã¯ãã°ãªããã¯æåã¯ãªãã«ãªã£ãŠãããã¹ã€ããããªã³ã«ãããšè¡šç€ºãããŸãããªãã«ãããšãã°ãªããã¯åã³è¡šç€ºãããªããªããŸãããã ããã°ãªããã衚瀺ãããŠãããšãã«åçã¢ãŒããçµäºãããšã次ã«åçã¢ãŒããéå§ãããšãã¹ã€ããã¯ãªãã«ãªããŸãããåã³ãªã³ã«ãªããŸããããã¯ãäžè¬çãªãã¬ã€ã³ãããªã¢ã«ã®ããŒã¯ãŒãã倿ŽããŠããããã§ãããããªã¢ã«ã¢ã»ãããç·šéããŠããããã倿Žã¯Unityãšãã£ã¿ãŒã«ä¿åãããŸããã¢ã»ã³ããªã«ã¯ä¿åãããŸãããåžžã«ã°ãªãããªãã§ã²ãŒã ãéå§ããã«ã¯GRID_ON
ãAwakeã§ããŒã¯ãŒããç¡å¹ã«ãHexMapEditor
ãŸãã void Awake () { terrainMaterial.DisableKeyword("GRID_ON"); }
ãŠããã£ããã±ãŒãžç·šéã¢ãŒã
ãããäžã®åããå¶åŸ¡ãããå Žåããããšå¯Ÿè©±ããå¿
èŠããããŸããå°ãªããšãããã¹ã®éå§ç¹ãšããŠã»ã«ãéžæããå¿
èŠããããŸããããããã»ã«ãã¯ãªãã¯ãããšãç·šéãããŸãããã¹ãŠã®ç·šéãªãã·ã§ã³ãæåã§ç¡å¹ã«ã§ããŸãããããã¯äžäŸ¿ã§ããããã«ããããã®ç·šéäžã«ãã£ã¹ãã¬ã€ã¹ã¡ã³ãã®èšç®ãå®è¡ããããããŸãããããã§ã¯ãç·šéã¢ãŒããã©ãããæ±ºå®ããã¹ã€ããã远å ããŸããããç·šéã¹ã€ãã
HexMapEditor
ããŒã«åãã£ãŒã«ãeditMode
ãããã³ãããå®çŸ©ããã¡ãœããã«è¿œå ããŸããæ¬¡ã«ãUIã«å¥ã®ã¹ã€ããã远å ããŠå¶åŸ¡ããŸããããã²ãŒã·ã§ã³ã¢ãŒãããå§ããŸããããã€ãŸããç·šéã¢ãŒãã¯ããã©ã«ãã§ç¡å¹ã«ãªããŸãã bool editMode; ⊠public void SetEditMode (bool toggle) { editMode = toggle; }
ç·šéã¢ãŒãã®åãæ¿ããç·šéãå®éã«ç¡å¹ã«ããã«ã¯ãåŒã³åºããã«EditCells
äŸåããeditMode
ãŸãã void HandleInput () { Ray inputRay = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Physics.Raycast(inputRay, out hit)) { HexCell currentCell = hexGrid.GetCell(hit.point); if (previousCell && previousCell != currentCell) { ValidateDrag(currentCell); } else { isDrag = false; } if (editMode) { EditCells(currentCell); } previousCell = currentCell; } else { previousCell = null; } }
ã©ãã«ã®ãããã°
ãããŸã§ã®ãšããããããå
ãç§»åãããŠãããã¯ãããŸããã代ããã«ãç§»åè·é¢ãèŠèŠåããŸãããããè¡ãã«ã¯ãæ¢åã®ã»ã«ã©ãã«ã䜿çšã§ããŸãããããã£ãŠãç·šéã¢ãŒããç¡å¹ã«ãªã£ãŠãããšãã«ãããã衚瀺ããŸãã public void SetEditMode (bool toggle) { editMode = toggle; hexGrid.ShowUI(!toggle); }
ããã²ãŒã·ã§ã³ã¢ãŒãã§éå§ãããããããã©ã«ãã®ã©ãã«ãæå¹ã«ããå¿
èŠããããŸããçŸåšHexGridChunk.Awake
ãããããç¡å¹ã«ããŸããã圌ã¯ãããè¡ãã¹ãã§ã¯ãããŸããã void Awake () { gridCanvas = GetComponentInChildren<Canvas>(); cells = new HexCell[HexMetrics.chunkSizeX * HexMetrics.chunkSizeZ];
ã©ãã«ã調æŽããŸãããã¬ã€ã¢ãŒããèµ·åãããšãã»ã«åº§æšãããã«è¡šç€ºãããããã«ãªããŸããããã ãã座æšã¯å¿
èŠãããŸãããã©ãã«ã䜿çšããŠè·é¢ã衚瀺ããŸããããã«ã¯ã»ã«ããšã«1ã€ã®æ°å€ããå¿
èŠãªãããããã©ã³ããµã€ãºã倧ããããŠèªã¿ãããããããšãã§ããŸããHex Cell Labelã®ãã¬ããã倿ŽããŠããµã€ãº8ã®å€ªåãã©ã³ãã䜿çšããããã«ããŸãã倪åã®ãã©ã³ããµã€ãº8ã®ã¿ã°ãåçã¢ãŒããèµ·åãããšã倧ããªã¿ã°ã衚瀺ãããŸããã»ã«ã®æåã®åº§æšã®ã¿ã衚瀺ãããæ®ãã¯ã©ãã«ã«é
眮ãããŸããã倧ããªã¿ã°ã座æšã¯ããå¿
èŠãªãã®ã§ãHexGrid.CreateCell
å²ãåœãŠã®å€ãåé€ããŸãlabel.text
ã void CreateCell (int x, int z, int i) { ⊠Text label = Instantiate<Text>(cellLabelPrefab); label.rectTransform.anchoredPosition = new Vector2(position.x, position.z);
Labelsã¹ã€ãããšãã®é¢é£ã¡ãœãããUIããåé€ããããšãã§ãHexMapEditor.ShowUI
ãŸãã
ã¡ãœããã®åãæ¿ãã¯ãããããŸããããŠããã£ããã±ãŒãžè·é¢ãèŠã€ãã
ã¿ã°ä»ãããã²ãŒã·ã§ã³ã¢ãŒããã§ããã®ã§ãè·é¢ã®è¡šç€ºãéå§ã§ããŸããã»ã«ãéžæãããã®ã»ã«ãããããäžã®ãã¹ãŠã®ã»ã«ãŸã§ã®è·é¢ã衚瀺ããŸããè·é¢è¡šç€º
ã»ã«ãŸã§ã®è·é¢ã远跡ããã«ã¯ãHexCell
æŽæ°ãã£ãŒã«ãã«è¿œå ããŸãdistance
ããã®ã»ã«ãšéžæããã»ã«ã®éã®è·é¢ã瀺ããŸãããããã£ãŠãéžæãããã»ã«èªäœã®å Žåã¯ãŒãã«ãªããããé£ã®ã»ã«ã®å Žåã¯1ã«ãªããŸãã int distance;
è·é¢ãèšå®ãããããã»ã«ã©ãã«ãæŽæ°ããŠãã®å€ã衚瀺ããå¿
èŠããããŸããUIãªããžã§ã¯ãHexCell
ãžã®åç
§ãRectTransform
ãããŸããç§ãã¡ã¯åœŒã«é»è©±ãGetComponent<Text>
ãŠãç¬æ¿ã«çãå¿
èŠããããŸããText
åå空éã«ãããã®ãèæ
®ããŠUnityEngine.UI
ãã¹ã¯ãªããã®æåã§äœ¿çšããŠãã ããã void UpdateDistanceLabel () { Text label = uiRect.GetComponent<Text>(); label.text = distance.ToString(); }
ããã¹ãã³ã³ããŒãã³ããžã®çŽæ¥ãªã³ã¯ãä¿æããå¿
èŠã¯ãããŸãããïŒ, . , , , . , .
äžè¬çãªããããã£ãèšå®ããŠãã»ã«ãŸã§ã®è·é¢ãåãåã£ãŠèšå®ããã©ãã«ãæŽæ°ããŸãã public int Distance { get { return distance; } set { distance = value; UpdateDistanceLabel(); } }
cellãã©ã¡ãŒã¿ãŒã䜿çšããŠHexGrid
äžè¬çãªã¡ãœããã«è¿œå ãFindDistancesTo
ãŸããããã§ã¯ãåã»ã«ã«ãŒãè·é¢ãèšå®ããã ãã§ãã public void FindDistancesTo (HexCell cell) { for (int i = 0; i < cells.Length; i++) { cells[i].Distance = 0; } }
ç·šéã¢ãŒããæå¹ã«ãªã£ãŠããªãå ŽåHexMapEditor.HandleInput
ãçŸåšã®ã»ã«ã§æ°ããã¡ãœãããåŒã³åºããŸãã if (editMode) { EditCells(currentCell); } else { hexGrid.FindDistancesTo(currentCell); }
座æšéã®è·é¢
ããã²ãŒã·ã§ã³ã¢ãŒãã§ã¯ããã®ãã¡ã®1ã€ã«è§Šãããšããã¹ãŠã®ã»ã«ã«ãŒãã衚瀺ãããŸãããã ãããã¡ãããã»ã«ãŸã§ã®å®éã®è·é¢ã衚瀺ããå¿
èŠããããŸããããããŸã§ã®è·é¢ãèšç®ããã«ã¯ãã»ã«ã®åº§æšã䜿çšã§ããŸãããããã£ãŠãHexCoordinates
ã¡ãœããããããšä»®å®ãDistanceTo
ãã§äœ¿çšãHexGrid.FindDistancesTo
ãŸãã public void FindDistancesTo (HexCell cell) { for (int i = 0; i < cells.Length; i++) { cells[i].Distance = cell.coordinates.DistanceTo(cells[i].coordinates); } }
HexCoordinates
ã¡ãœããã«è¿œå ãDistanceTo
ãŸãã圌ã¯èªåã®åº§æšãå¥ã®ã»ããã®åº§æšãšæ¯èŒããªããã°ãªããŸãããXãæž¬å®ããããšããå§ããŸããããX座æšãäºãã«æžç®ããŸãã public int DistanceTo (HexCoordinates other) { return x - other.x; }
ãã®çµæãéžæããã»ã«ã«å¯ŸããŠXã«æ²¿ã£ããªãã»ãããååŸããŸãããã ããè·é¢ãè² ã«ããããšã¯ã§ããªãããã座æšå·®Xã¢ãžã¥ããè¿ãå¿
èŠããããŸãã return x < other.x ? other.x - x : x - other.x;
Xã«æ²¿ã£ãè·é¢ããããã£ãŠã1ã€ã®æ¬¡å
ã®ã¿ãèæ
®ããå Žåã«ã®ã¿æ£ããè·é¢ãåŸãããŸããããããå
è§åœ¢ã®ã°ãªããã«ã¯3ã€ã®æ¬¡å
ããããŸããããã§ã¯ã3ã€ã®æ¬¡å
ãã¹ãŠã®è·é¢ãåèšããŠããããäœãããããããèŠãŠã¿ãŸãããã return (x < other.x ? other.x - x : x - other.x) + (Y < other.Y ? other.Y - Y : Y - other.Y) + (z < other.z ? other.z - z : z - other.z);
XYZã«ããè·é¢ã®åèšãè·é¢ã2åã«ãªãããšãããããŸãããã€ãŸããæ£ããè·é¢ãååŸããã«ã¯ããã®éãååã«åå²ããå¿
èŠããããŸãã return ((x < other.x ? other.x - x : x - other.x) + (Y < other.Y ? other.Y - Y : Y - other.Y) + (z < other.z ? other.z - z : z - other.z)) / 2;
å®éã®è·é¢ãåèšãè·é¢ã®2åã«çããã®ã¯ãªãã§ããïŒ, . , (1, â3, 2). . , . . , . .
. ãŠããã£ããã±ãŒãžé害ç©ãæ±ã
ç§ãã¡ãèšç®ããè·é¢ã¯ãéžæããã»ã«ããä»ã®åã»ã«ãŸã§ã®æççµè·¯ã«å¯Ÿå¿ããŠããŸãããã£ãšçãæ¹æ³ãèŠã€ããããšã¯ã§ããŸããããã ããã«ãŒããäœããããã¯ããªãå Žåããããã®ãã¹ã¯æ£ããããšãä¿èšŒãããŸããåŽãæ°Žããã®ä»ã®é害ç©ããããšãç§ãã¡ã¯æ©ãåãããšãã§ããŸãããããããããã€ãã®ã»ã«ã«ãŸã£ããå°éã§ããŸãããé害ç©ãåé¿ããæ¹æ³ãèŠã€ããã«ã¯ãåã«åº§æšéã®è·é¢ãèšç®ããã®ã§ã¯ãªããå¥ã®ã¢ãããŒãã䜿çšããå¿
èŠããããŸããåã»ã«ãåå¥ã«èª¿ã¹ãããšã¯ã§ããªããªããŸãããå°éå¯èœãªãã¹ãŠã®ã»ã«ãèŠã€ãããŸã§ãããããæ€çŽ¢ããå¿
èŠããããŸããæ€çŽ¢ã®èŠèŠå
ãããæ€çŽ¢ã¯å埩ããã»ã¹ã§ããç§ãã¡ãäœãããŠããããçè§£ããã«ã¯ãæ€çŽ¢ã®å段éã確èªãããšåœ¹ç«ã¡ãŸãããããè¡ãã«ã¯ãæ€çŽ¢ã¢ã«ãŽãªãºã ãã³ã«ãŒãã³ã«å€æããŸãSystem.Collections
ãããã«ã¯æ€çŽ¢ã¹ããŒã¹ãå¿
èŠã§ãã1ç§éã«60åã®æŽæ°ã®ãªãã¬ãã·ã¥ã¬ãŒãã¯ãäœãèµ·ãã£ãŠããã®ãã確èªããã«ã¯ååã«å°ãããå°ããªãããã§ã®æ€çŽ¢ã«ã¯ããã»ã©æéãããããŸããã§ããã public void FindDistancesTo (HexCell cell) { StartCoroutine(Search(cell)); } IEnumerator Search (HexCell cell) { WaitForSeconds delay = new WaitForSeconds(1 / 60f); for (int i = 0; i < cells.Length; i++) { yield return delay; cells[i].Distance = cell.coordinates.DistanceTo(cells[i].coordinates); } }
åžžã«1ã€ã®æ€çŽ¢ã®ã¿ãã¢ã¯ãã£ãã§ããããšã確èªããå¿
èŠããããŸãããããã£ãŠãæ°ããæ€çŽ¢ãéå§ããåã«ããã¹ãŠã®ã³ã«ãŒãã³ã忢ããŸãã public void FindDistancesTo (HexCell cell) { StopAllCoroutines(); StartCoroutine(Search(cell)); }
ããã«ãæ°ããããããèªã¿èŸŒããšãã«æ€çŽ¢ãå®äºããå¿
èŠããããŸãã public void Load (BinaryReader reader, int header) { StopAllCoroutines(); ⊠}
å¹
åªå
æ€çŽ¢
æ€çŽ¢ãéå§ããåã§ããéžæããã»ã«ãŸã§ã®è·é¢ã¯ãŒãã§ããããšãããããŸãããããŠããã¡ããããããã«å°éã§ããå Žåããã®ãã¹ãŠã®è¿é£ãžã®è·é¢ã¯1ã§ããæ¬¡ã«ããããã®é£äººã®1ã€ãèŠãŠã¿ãŸãããããã®ã»ã«ã«ã¯ãå°éå¯èœãªç¬èªã®è¿åããããè·é¢ã¯ãŸã èšç®ãããŠããŸããããã®å Žåããããã®é£äººãŸã§ã®è·é¢ã¯2ã§ããå¿
èŠããããŸããè·é¢1ã®ãã¹ãŠã®é£äººã«å¯ŸããŠãã®ããã»ã¹ãç¹°ãè¿ãããšãã§ããŸãããã®åŸãè·é¢2ã®ãã¹ãŠã®é£äººã«å¯ŸããŠãã®ããã»ã¹ãç¹°ãè¿ããŸããã€ãŸããæåã«è·é¢1ã«ãããã¹ãŠã®ã»ã«ãèŠã€ããæ¬¡ã«2ã®è·é¢ã«ãããã¹ãŠã®ã»ã«ãèŠã€ããæ¬¡ã«3ã®è·é¢ã«ãããªã©ãçµäºãããŸã§èŠã€ããŸããããã«ãããå°éå¯èœãªåã»ã«ãŸã§ã®æçè·é¢ãèŠã€ããããšãã§ããŸãããã®ã¢ã«ãŽãªãºã ã¯ãå¹
åªå
æ€çŽ¢ãšåŒã°ããŸãããããæ©èœããããã«ã¯ãã»ã«ãŸã§ã®è·é¢ããã§ã«æ±ºå®ããŠãããã©ãããç¥ãå¿
èŠããããŸããå€ãã®å Žåãã»ã«ã¯æ¢è£œã»ãããŸãã¯å¯éã»ãããšåŒã°ããã³ã¬ã¯ã·ã§ã³ã«é
眮ãããŸãããã ããã»ã«int.MaxValue
ãŸã§ã®è·é¢ãèšå®ããŠããŸã ã¢ã¯ã»ã¹ããŠããªãããšã瀺ãããšãã§ããŸããæ€çŽ¢ãå®è¡ããçŽåã«ããã¹ãŠã®ã»ã«ã«å¯ŸããŠãããè¡ãå¿
èŠããããŸãã IEnumerator Search (HexCell cell) { for (int i = 0; i < cells.Length; i++) { cells[i].Distance = int.MaxValue; } ⊠}
ããã䜿çšããŠãã倿Žããããšã«ãããæªèšªåã®ã»ã«ããã¹ãŠé衚瀺ã«ããããšãã§ãHexCell.UpdateDistanceLabel
ãŸãããã®åŸã空çœã®ãããã§åæ€çŽ¢ãéå§ããŸãã void UpdateDistanceLabel () { Text label = uiRect.GetComponent<Text>(); label.text = distance == int.MaxValue ? "" : distance.ToString(); }
次ã«ã蚪åããå¿
èŠãããã»ã«ãšã蚪åããé åºã远跡ããå¿
èŠããããŸãããã®ãããªã³ã¬ã¯ã·ã§ã³ã¯ãå€ãã®å ŽåãããŒããŒãŸãã¯ãªãŒãã³ã»ãããšåŒã°ããŸããã»ã«ã¯ãåºäŒã£ãã®ãšåãé åºã§åŠçããå¿
èŠããããŸãããããè¡ãã«Queue
ã¯ãåå空éã®äžéšã§ããqueueã䜿çšã§ããŸãSystem.Collections.Generic
ãéžæããã»ã«ããã®ãã¥ãŒã«æåã«é
眮ãããè·é¢ã¯0ã«ãªããŸãã IEnumerator Search (HexCell cell) { for (int i = 0; i < cells.Length; i++) { cells[i].Distance = int.MaxValue; } WaitForSeconds delay = new WaitForSeconds(1 / 60f); Queue<HexCell> frontier = new Queue<HexCell>(); cell.Distance = 0; frontier.Enqueue(cell);
ãã®ç¬éãããã¢ã«ãŽãªãºã ã¯ãã¥ãŒã«äœããããéã«ã«ãŒããå®è¡ããŸããåå埩ã§ãæåé¢ã®ã»ã«ããã¥ãŒããååŸãããŸãã frontier.Enqueue(cell); while (frontier.Count > 0) { yield return delay; HexCell current = frontier.Dequeue(); }
ããã§çŸåšã®ã»ã«ãã§ããŸãããããã¯ã©ããªè·é¢ã§ãæ§ããŸãããæ¬¡ã«ãéžæããã»ã«ããããã«1ã¹ãããå
ã®ãã¹ãŠã®é£æ¥ããŒãããã¥ãŒã«è¿œå ããå¿
èŠããããŸãã while (frontier.Count > 0) { yield return delay; HexCell current = frontier.Dequeue(); for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++) { HexCell neighbor = current.GetNeighbor(d); if (neighbor != null) { neighbor.Distance = current.Distance + 1; frontier.Enqueue(neighbor); } } }
ãã ãããŸã è·é¢ãäžããããŠããªãã»ã«ã®ã¿ã远å ããå¿
èŠããããŸãã if (neighbor != null && neighbor.Distance == int.MaxValue) { neighbor.Distance = current.Distance + 1; frontier.Enqueue(neighbor); }
åºãæ€çŽ¢ãæ°Žãé¿ãã
å¹
åªå
æ¢çŽ¢ãå調ãªãããäžã§æ£ããè·é¢ãèŠã€ããããšã確èªããåŸãé害ç©ã®è¿œå ãéå§ã§ããŸããããã¯ãç¹å®ã®æ¡ä»¶ãæºããããå Žåã«ãã¥ãŒã«ã»ã«ã远å ããããšãæåŠããããšã§å®è¡ã§ããŸããå®éãããã€ãã®ã»ã«ããã§ã«æ¬ èœããŠããŸããååšããªãã»ã«ãšãè·é¢ããã§ã«ç€ºããã»ã«ã§ãããã®å Žåãæç€ºçã«é£äººãã¹ãããããããã«ã³ãŒããæžãçŽããŸãããã for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++) { HexCell neighbor = current.GetNeighbor(d); if (neighbor == null || neighbor.Distance != int.MaxValue) { continue; } neighbor.Distance = current.Distance + 1; frontier.Enqueue(neighbor); }
ãŸããæ°Žäžã«ãããã¹ãŠã®çްèãã¹ãããããŸããããã€ãŸããæçè·é¢ãæ€çŽ¢ãããšãã¯ãå°äžã§ã®åãã®ã¿ãèæ
®ããŸãã if (neighbor == null || neighbor.Distance != int.MaxValue) { continue; } if (neighbor.IsUnderwater) { continue; }
æ°Žã®äžãç§»åããã«è·é¢ãã¢ã«ãŽãªãºã ã¯äŸç¶ãšããŠæçè·é¢ãèŠã€ããŸããããã¹ãŠã®æ°Žãåé¿ããŸãããããã£ãŠãæ°Žäžã®ã»ã«ã¯ãå€ç«ããåå°ã®ããããã®ããã«è·é¢ãåŸãããšãã§ããŸãããæ°Žäžã®ã»ã«ã¯ãéžæãããŠããå Žåã«ã®ã¿è·é¢ãååŸããŸããåŽãé¿ãã
ãŸããé£äººã蚪åããå¯èœæ§ã倿ããããã«ãrib骚ã®ã¿ã€ãã䜿çšã§ããŸããããšãã°ãåŽã§ãã¹ããããã¯ããããšãã§ããŸããæé¢ã§ã®ç§»åãèš±å¯ããå ŽåãåŽã®å察åŽã®ã»ã«ã«ã¯ãä»ã®ãã¹ã§ã®ã¿å°éã§ããŸãããããã£ãŠããããã¯éåžžã«ç°ãªãè·é¢ã«ããå¯èœæ§ããããŸãã if (neighbor.IsUnderwater) { continue; } if (current.GetEdgeType(neighbor) == HexEdgeType.Cliff) { continue; }
åŽãè¶ããªãè·é¢ããŠããã£ããã±ãŒãžæ
è²»
ã»ã«ãšãšããžã¯åé¿ã§ããŸããããããã®ãªãã·ã§ã³ã¯ãã€ããªã§ããä»ã®æ¹åãããããæ¹åã«ããã²ãŒãããæ¹ãç°¡åã ãšæ³åã§ããŸãããã®å Žåãè·é¢ã¯åŽåãŸãã¯æéã§æž¬å®ãããŸããé«ééè·¯
éè·¯ãç§»åããæ¹ãç°¡åã§é«éã§ããããšãè«ççã§ããããããšããžãšéè·¯ã®äº€å·®ç¹ã®ã³ã¹ããäœãããŸããããæŽæ°å€ã䜿çšããŠè·é¢ãèšå®ãããããéè·¯ã«æ²¿ã£ãŠç§»åããã³ã¹ãã1ã®ãŸãŸã«ããä»ã®ãšããžã暪æããã³ã¹ãã10ã«å¢ãããŸããããã¯å€§ããªéãã§ãããæ£ããçµæãåŸããããã©ãããããã«ç¢ºèªã§ããŸãã int distance = current.Distance; if (current.HasRoadThroughEdge(d)) { distance += 1; } else { distance += 10; } neighbor.Distance = distance;
è·é¢ãééã£ãŠããéè·¯ãããŒããŒãœãŒã
æ®å¿µãªãããå¹
åªå
ã®æ€çŽ¢ã¯ãå€åããç§»åã³ã¹ãã§ã¯æ©èœããŸããã圌ã¯ãè·é¢ã®å¢å é ã«ã»ã«ãå¢çã«è¿œå ããããšæ³å®ããŠãããç§ãã¡ã«ãšã£ãŠããã¯ãã¯ãé¢ä¿ãããŸãããåªå
ãã¥ãŒãã€ãŸãããèªäœããœãŒããããã¥ãŒãå¿
èŠã§ãããã¹ãŠã®ç¶æ³ã«é©åãããããªæ¹æ³ã§ããããããã°ã©ã ããããšã¯ã§ããªããããæšæºã®åªå
床ãã¥ãŒã¯ãããŸãããç¬èªã®åªå
床ãã¥ãŒãäœæã§ããŸãããä»åŸã®ãã¥ãŒããªã¢ã«çšã«æé©åããŠã¿ãŸããããä»ã®ãšããããã¥ãŒãmethodãæã€ãªã¹ãã«çœ®ãæããã ãSort
ã§ãã List<HexCell> frontier = new List<HexCell>(); cell.Distance = 0; frontier.Add(cell); while (frontier.Count > 0) { yield return delay; HexCell current = frontier[0]; frontier.RemoveAt(0); for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++) { ⊠neighbor.Distance = distance; frontier.Add(neighbor); } }
ListPool <HexCell>ã䜿çšã§ããŸãããïŒ, , . , , .
å¢çç·ãçã«ããã«ã¯ãã»ã«ã远å ããåŸã«å¢çç·ãäžŠã¹æ¿ããå¿
èŠããããŸããå®éãã»ã«ã®ãã¹ãŠã®é£æ¥ã»ã«ã远å ããããŸã§ãœãŒããå»¶æã§ããŸãããæé©åã«é¢å¿ããªããªããŸã§ç¹°ãè¿ããŸããè·é¢ã§ã»ã«ããœãŒãããŸãããããè¡ãã«ã¯ããã®æ¯èŒãå®è¡ããã¡ãœãããžã®ãªã³ã¯ã䜿çšããŠãªã¹ãã®äžŠã¹æ¿ãã¡ãœãããåŒã³åºãå¿
èŠããããŸãã frontier.Add(neighbor); frontier.Sort((x, y) => x.Distance.CompareTo(y.Distance));
ãã®ãœãŒãæ¹æ³ã¯ã©ã®ããã«æ©èœããŸããïŒ. , . .
frontier.Sort(CompareDistances); ⊠static int CompareDistances (HexCell x, HexCell y) { return x.Distance.CompareTo(y.Distance); }
ãœãŒããããå¢çç·ã¯ãŸã æ£ãããããŸãããåœå¢æŽæ°
å¢çç·ã®äžŠã¹æ¿ããéå§ããåŸãããè¯ãçµæãåŸããå§ããŸãããããŸã ãšã©ãŒããããŸããããã¯ãã»ã«ãå¢çã«è¿œå ããããšãã«ããã®ã»ã«ãŸã§ã®æçè·é¢ãå¿
ãããèŠã€ããããšãã§ããªãããã§ããããã¯ããã§ã«è·é¢ãå²ãåœãŠãããŠããé£äººãã¹ãããã§ããªããªã£ãããšãæå³ããŸãã代ããã«ãçããã¹ãèŠã€ãã£ããã©ããã確èªããå¿
èŠããããŸãããã®å Žåãå¢çã«è¿œå ããã®ã§ã¯ãªããè¿é£ãžã®è·é¢ã倿Žããå¿
èŠããããŸãã HexCell neighbor = current.GetNeighbor(d); if (neighbor == null) { continue; } if (neighbor.IsUnderwater) { continue; } if (current.GetEdgeType(neighbor) == HexEdgeType.Cliff) { continue; } int distance = current.Distance; if (current.HasRoadThroughEdge(d)) { distance += 1; } else { distance += 10; } if (neighbor.Distance == int.MaxValue) { neighbor.Distance = distance; frontier.Add(neighbor); } else if (distance < neighbor.Distance) { neighbor.Distance = distance; } frontier.Sort((x, y) => x.Distance.CompareTo(y.Distance));
æ£ããè·é¢ãæ£ããè·é¢ãåŸãããã®ã§ãç§»åã®ã³ã¹ããæ€èšãå§ããŸããäžéšã®ã»ã«ãŸã§ã®è·é¢ã¯æåã¯å€§ããããŸãããå¢çããåé€ããããšä¿®æ£ãããŸãããã®ã¢ãããŒãã¯ãã€ã¯ã¹ãã©ã®ã¢ã«ãŽãªãºã ãšåŒã°ãããšãã¬ãŒã»ãã€ã¯ã¹ãã©ãæåã«çºæãããã®ã«ã¡ãªãã§åä»ããããŸãããåé
ç§ãã¡ã¯ãéè·¯ã ãã®ç°ãªãã³ã¹ãã«å¶éãããããšãæã¿ãŸãããããšãã°ãéè·¯ã®ãªãå¹³åŠãªãšããžã暪æããã³ã¹ãã5ã«åæžããéè·¯ã®ãªãæé¢ã®å€ã10ã®ãŸãŸã«ããããšãã§ããŸãã HexEdgeType edgeType = current.GetEdgeType(neighbor); if (edgeType == HexEdgeType.Cliff) { continue; } int distance = current.Distance; if (current.HasRoadThroughEdge(d)) { distance += 1; } else { distance += edgeType == HexEdgeType.Flat ? 5 : 10; }
æé¢ãå
æããã«ã¯ãããå€ãã®äœæ¥ãè¡ãå¿
èŠããããéè·¯ã¯åžžã«é«éã§ããææžãªããžã§ã¯ã
å°åœ¢æ©èœãããå Žåãã³ã¹ãã远å ã§ããŸããããšãã°ãå€ãã®ã²ãŒã ã§ã¯ããã©ã¬ã¹ããããã²ãŒãããããšã¯ããå°é£ã§ãããã®å Žåããªããžã§ã¯ãã®ãã¹ãŠã®ã¬ãã«ãè·é¢ã«è¿œå ããã ãã§ãããããŠãããã§ãéã¯ãã¹ãŠãå éããŸãã if (current.HasRoadThroughEdge(d)) { distance += 1; } else { distance += edgeType == HexEdgeType.Flat ? 5 : 10; distance += neighbor.UrbanLevel + neighbor.FarmLevel + neighbor.PlantLevel; }
éè·¯ããªãå Žåããªããžã§ã¯ãã¯é
ããªããŸããå£
æåŸã«ãå£ãèæ
®ããŸããããéè·¯ãééããªãå Žåãå£ã¯åãããããã¯ããå¿
èŠããããŸãã if (current.HasRoadThroughEdge(d)) { distance += 1; } else if (current.Walled != neighbor.Walled) { continue; } else { distance += edgeType == HexEdgeType.Flat ? 5 : 10; distance += neighbor.UrbanLevel + neighbor.FarmLevel + neighbor.PlantLevel; }
å£ã¯ééãããªãã®ã§ãéãæ¢ãå¿
èŠããããŸãããŠããã£ããã±ãŒãž