[ рдкрд╣рд▓рд╛ рднрд╛рдЧ: рдЯрд╛рдЗрд▓реНрд╕ рдФрд░ рд░рд╛рд╕реНрддрд╛ рдЦреЛрдЬрдирд╛ ]- рд╢рддреНрд░реБ рдирд┐рд░реНрдорд╛рдг рдмрд┐рдВрджреБрдУрдВ рдХрд╛ рд╕реНрдерд╛рдиред
- рдореИрджрд╛рди рдореЗрдВ рджреБрд╢реНрдордиреЛрдВ рдФрд░ рдЙрдирдХреЗ рдЖрдВрджреЛрд▓рди рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ред
- рдПрдХ рд╕реНрдерд┐рд░ рдЧрддрд┐ рд╕реЗ рдЪрд┐рдХрдиреА рдЧрддрд┐ рдмрдирд╛рдирд╛ред
- рджреБрд╢реНрдордиреЛрдВ рдХреЗ рдЖрдХрд╛рд░, рдЧрддрд┐ рдФрд░ рд╕реНрдерд╛рди рдХреЛ рдмрджрд▓реЗрдВред
рдпрд╣ рдПрдХ рд╕рд╛рдзрд╛рд░рдг
рдЯреЙрд╡рд░ рд░рдХреНрд╖рд╛ рдЦреЗрд▓ рдкрд░ рдПрдХ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХрд╛ рджреВрд╕рд░рд╛ рднрд╛рдЧ рд╣реИред рдпрд╣ рджреБрд╢реНрдордиреЛрдВ рдФрд░ рдЙрдирдХреЗ рдЖрдВрджреЛрд▓рди рдХреЛ рдирд┐рдХрдЯрддрдо рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ рддрдХ рдмрдирд╛рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддрд╛ рд╣реИред
рдпрд╣ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдпреВрдирд┐рдЯреА 2018.3.0f2 рдореЗрдВ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдЕрдВрдд рдмрд┐рдВрджреБ рдХреЗ рд░рд╛рд╕реНрддреЗ рдкрд░ рджреБрд╢реНрдордиредрд╢рддреНрд░реБ рдирд┐рд░реНрдорд╛рдг (рд╕реНрдкреЙрди) рдЕрдВрдХ
рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рд╣рдо рджреБрд╢реНрдорди рдмрдирд╛рдирд╛ рд╢реБрд░реВ рдХрд░реЗрдВ, рд╣рдореЗрдВ рдпрд╣ рддрдп рдХрд░рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ рдХрд┐ рдЙрдиреНрд╣реЗрдВ рдореИрджрд╛рди рдкрд░ рдХрд╣рд╛рдВ рд░рдЦрд╛ рдЬрд╛рдПред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╕реНрдкреЙрди рдкреЙрдЗрдВрдЯ рдмрдирд╛рдПрдВрдЧреЗред
рдЯрд╛рдЗрд▓ рдХреА рд╕рд╛рдордЧреНрд░реА
рд╕реНрдкреЙрди рдкреЙрдЗрдВрдЯ рдПрдХ рдЕрдиреНрдп рдкреНрд░рдХрд╛рд░ рдХреА рдЯрд╛рдЗрд▓ рд╕рд╛рдордЧреНрд░реА рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕рдХреЗ рд▓рд┐рдП
GameTileContentType
рдореЗрдВ рдПрдХ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдЬреЛрдбрд╝реЗрдВред
public enum GameTileContentType { Empty, Destination, Wall, SpawnPoint }
рдФрд░ рдлрд┐рд░ рдЗрд╕рдХреА рдХрд▓реНрдкрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд░реАрдлреИрдм рдмрдирд╛рдПрдВред рд╢реБрд░реБрдЖрддреА рдмрд┐рдВрджреБ рдХреЗ рдкреНрд░реАрдлреИрдм рдХрд╛ рдПрдХ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдХрд╛рдлреА рдЙрдкрдпреБрдХреНрдд рд╣реИ, рдмрд╕ рдЗрд╕рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рдмрджрд▓реЗрдВ рдФрд░ рдЗрд╕реЗ рдПрдХ рдФрд░ рд╕рд╛рдордЧреНрд░реА рджреЗрдВред рдореИрдВрдиреЗ рдЗрд╕реЗ рдирд╛рд░рдВрдЧреА рдмрдирд╛ рджрд┐рдпрд╛ред
рд╕реНрдкреЙрди рдкреЙрдЗрдВрдЯ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рдиредрд╕рд╛рдордЧреНрд░реА рдлреИрдХреНрдЯреНрд░реА рдореЗрдВ рд╕реНрдкреЙрди рдкреЙрдЗрдВрдЯ рд╕рдкреЛрд░реНрдЯ рдЬреЛрдбрд╝реЗрдВ рдФрд░ рдЗрд╕реЗ рдкреНрд░реАрдлреИрдм рдХрд╛ рд▓рд┐рдВрдХ рджреЗрдВред
[SerializeField] GameTileContent spawnPointPrefab = default; тАж public GameTileContent Get (GameTileContentType type) { switch (type) { case GameTileContentType.Destination: return Get(destinationPrefab); case GameTileContentType.Empty: return Get(emptyPrefab); case GameTileContentType.Wall: return Get(wallPrefab); case GameTileContentType.SpawnPoint: return Get(spawnPointPrefab); } Debug.Assert(false, "Unsupported type: " + type); return null; }
рд╕реНрдкреЙрди рдкреЙрдЗрдВрдЯ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рдХреЗ рд╕рд╛рде рдлреИрдХреНрдЯрд░реАредрд╕реНрдкреЙрди рдкреЙрдЗрдВрдЯ рдХреЛ рд╕рдХреНрд╖рдо рдпрд╛ рдЕрдХреНрд╖рдо рдХрд░реЗрдВ
рд╕реНрдкреЙрди рдмрд┐рдВрджреБ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХреА рд╡рд┐рдзрд┐, рдЕрдиреНрдп рд╕реНрд╡рд┐рдЪрд┐рдВрдЧ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреА рддрд░рд╣, рд╣рдо
GameBoard
рдЬреЛрдбрд╝
GameBoard
ред рд▓реЗрдХрд┐рди рд╕реНрдкреЙрди рдкреЙрдЗрдВрдЯ рдорд╛рд░реНрдЧ рдХреА рдЦреЛрдЬ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдмрджрд▓рд╛рд╡ рдХреЗ рдмрд╛рдж рд╣рдореЗрдВ рдирдП рд░рд╛рд╕реНрддреЛрдВ рдХреА рддрд▓рд╛рд╢ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
public void ToggleSpawnPoint (GameTile tile) { if (tile.Content.Type == GameTileContentType.SpawnPoint) { tile.Content = contentFactory.Get(GameTileContentType.Empty); } else if (tile.Content.Type == GameTileContentType.Empty) { tile.Content = contentFactory.Get(GameTileContentType.SpawnPoint); } }
рдЦреЗрд▓ рдХреЗрд╡рд▓ рддрднреА рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ рдЬрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рджреБрд╢реНрдорди рд╣реЛрддреЗ рд╣реИрдВ, рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╕реНрдкреЙрди рдкреЙрдЗрдВрдЯреНрд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдЗрд╕рд▓рд┐рдП, рдЦреЗрд▓ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдХрдо рд╕реЗ рдХрдо рдПрдХ рд╕реНрдкреЙрди рдмрд┐рдВрджреБ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рд╣рдореЗрдВ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рд╕реНрдкреЙрди рдкреЙрдЗрдВрдЯ рддрдХ рдкрд╣реБрдВрдЪ рдХреА рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдЬрдм рд╣рдо рджреБрд╢реНрдордиреЛрдВ рдХреЛ рдЬреЛрдбрд╝реЗрдВрдЧреЗ, рддреЛ рдЖрдЗрдП рдЗрди рдмрд┐рдВрджреБрдУрдВ рдкрд░ рд╕рднреА рдЯрд╛рдЗрд▓реЛрдВ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реВрдЪреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рд╣рдо рд╕реНрдкреЙрди рдмрд┐рдВрджреБ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рд╕реНрд╡рд┐рдЪ рдХрд░рддреЗ рд╕рдордп рд╕реВрдЪреА рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВрдЧреЗ рдФрд░ рдЕрдВрддрд┐рдо рд╕реНрдкреЙрди рдмрд┐рдВрджреБ рдХреЛ рд╣рдЯрд╛рдиреЗ рд╕реЗ рд░реЛрдХреЗрдВрдЧреЗред
List<GameTile> spawnPoints = new List<GameTile>(); тАж public void ToggleSpawnPoint (GameTile tile) { if (tile.Content.Type == GameTileContentType.SpawnPoint) { if (spawnPoints.Count > 1) { spawnPoints.Remove(tile); tile.Content = contentFactory.Get(GameTileContentType.Empty); } } else if (tile.Content.Type == GameTileContentType.Empty) { tile.Content = contentFactory.Get(GameTileContentType.SpawnPoint); spawnPoints.Add(tile); } }
Initialize
рд╡рд┐рдзрд┐ рдХреЛ рдЕрдм рдХреНрд╖реЗрддреНрд░ рдХреА рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕рд╣реА рд╕реНрдерд┐рддрд┐ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдкреЙрди рдкреЙрдЗрдВрдЯ рд╕реЗрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЪрд▓реЛ рдмрд╕ рдкрд╣рд▓реА рдЯрд╛рдЗрд▓ рд╢рд╛рдорд┐рд▓ рдХрд░реЗрдВ, рдЬреЛ рдирд┐рдЪрд▓реЗ рдмрд╛рдПрдВ рдХреЛрдиреЗ рдореЗрдВ рд╣реИред
public void Initialize ( Vector2Int size, GameTileContentFactory contentFactory ) { тАж ToggleDestination(tiles[tiles.Length / 2]); ToggleSpawnPoint(tiles[0]); }
рд╣рдо рд╡реИрдХрд▓реНрдкрд┐рдХ рд╕реНрдкрд░реНрд╢ рдХреЛ рдЕрдм рд╕реНрдкреЙрди рдкреЙрдЗрдВрдЯреНрд╕ рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдмрджрд▓ рджреЗрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдЬрдм рдЖрдк рдмрд╛рдИрдВ Shift рдХреБрдВрдЬреА рд░рдЦрддреЗ рд╣реИрдВ (
Input.GetKey
рджреНрд╡рд╛рд░рд╛ рдХреАрд╕реНрдЯреНрд░реЛрдХ рдХреА рдЬрд╛рдБрдЪ рдХреА рдЬрд╛рддреА рд╣реИред рд╡рд┐рдзрд┐ рд╡рд┐рдзрд┐), рдЕрдВрддрд┐рдо рдмрд┐рдВрджреБ рдХреА рд╕реНрдерд┐рддрд┐ рд╕реНрд╡рд┐рдЪ рд╣реЛ рдЬрд╛рдПрдЧреА
void HandleAlternativeTouch () { GameTile tile = board.GetTile(TouchRay); if (tile != null) { if (Input.GetKey(KeyCode.LeftShift)) { board.ToggleDestination(tile); } else { board.ToggleSpawnPoint(tile); } } }
рд╕реНрдкреЙрди рдбреЙрдЯреНрд╕ рдХреЗ рд╕рд╛рде рдлрд╝реАрд▓реНрдбредрд╕реНрдкреЙрди рдкреЙрдЗрдВрдЯ рддрдХ рдкрд╣реБрдВрдЪ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ
рдХреНрд╖реЗрддреНрд░ рдЕрдкрдиреА рд╕рднреА рдЯрд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рджреБрд╢реНрдорди рдЗрд╕рдХреА рдЬрд┐рдореНрдореЗрджрд╛рд░реА рдирд╣реАрдВ рд╣реИрдВред рд╣рдо рдПрдХ рдЗрдВрдбреЗрдХреНрд╕ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде рд╕рд╛рдорд╛рдиреНрдп
GetSpawnPoint
рд╡рд┐рдзрд┐ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЗрд╕рдХреЗ рд╕реНрдкреЙрди рдкреЙрдЗрдВрдЯ рддрдХ рдкрд╣реБрдВрдЪрдирд╛ рд╕рдВрднрд╡
GetSpawnPoint
ред
public GameTile GetSpawnPoint (int index) { return spawnPoints[index]; }
рдпрд╣ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдХреМрди рд╕реЗ рд╕реВрдЪрдХрд╛рдВрдХ рд╕рд╣реА рд╣реИрдВ, рд╕реНрдкреЙрди рдЕрдВрдХреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЗрд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рд╛рдкреНрддрдХрд░реНрддрд╛ рд╕рдВрдкрддреНрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рдмрдирд╛ рджреЗрдВрдЧреЗред
public int SpawnPointCount => spawnPoints.Count;
рд╢рддреНрд░реБ рд╕реНрдкреЙрди
рдПрдХ рджреБрд╢реНрдорди рдХреЛ рдкреИрджрд╛ рдХрд░рдирд╛ рдХреБрдЫ рд╣рдж рддрдХ рдПрдХ рдЯрд╛рдЗрд▓ рдХреА рд╕рд╛рдордЧреНрд░реА рдмрдирд╛рдиреЗ рдХреЗ рд╕рдорд╛рди рд╣реИред рд╣рдо рдХрд╛рд░рдЦрд╛рдиреЗ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ рдкреНрд░реАрдлреИрдм рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рддреЗ рд╣реИрдВ, рдЬрд┐рд╕реЗ рд╣рдо рдлрд┐рд░ рдореИрджрд╛рди рдкрд░ рд░рдЦрддреЗ рд╣реИрдВред
рдлрд╝реИрдХреНрдЯрд░реА
рд╣рдо рджреБрд╢реНрдордиреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдРрд╕реА рдлреИрдХреНрдЯреНрд░реА рдмрдирд╛рдПрдВрдЧреЗ рдЬреЛ рд╡рд╣ рд╕рдм рдХреБрдЫ рдмрдирд╛рдПрдЧреА рдЬреЛ рд╡рд╣ рдЕрдкрдиреЗ рд╕реНрддрд░ рдкрд░ рдмрдирд╛рддрд╛ рд╣реИред рдпрд╣ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рдореМрдЬреВрдж рдлреИрдХреНрдЯреНрд░реА рдХреЗ рд╕рд╛рде рдЖрдо рд╣реИ, рддреЛ рдЪрд▓рд┐рдП рдЗрд╕рдХреЗ рд▓рд┐рдП рдХреЛрдб рдХреЛ рдЖрдо рдЖрдзрд╛рд░ рд╡рд░реНрдЧ
GameObjectFactory
ред рд╣рдореЗрдВ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп
CreateGameObjectInstance
рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде рдХреЗрд╡рд▓ рдПрдХ
CreateGameObjectInstance
рд╡рд┐рдзрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдЬреЛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рд░рд┐рдЯрд░реНрди рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдкреВрд░реЗ рджреГрд╢реНрдп рдХрд╛ рдкреНрд░рдмрдВрдзрди рднреА рдХрд░рддрд╛ рд╣реИред рд╣рдо
protected
рд╡рд┐рдзрд┐ рдмрдирд╛рддреЗ рд╣реИрдВ,
protected
рдпрд╣ рдХреЗрд╡рд▓ рдЙрд╕ рд╡рд░реНрдЧ рдФрд░ рд╕рднреА рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рд╣реЛрдЧреА рдЬреЛ рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рд╕рдм рд╡рд░реНрдЧ рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рдкреВрд░реА рддрд░рд╣ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдХрд╛рд░рдЦрд╛рдиреЗ рдХреЗ рд░реВрдк рдореЗрдВ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд░рдиреЗ рдХрд╛ рдЗрд░рд╛рджрд╛ рдирд╣реАрдВ рд╣реИред рдЗрд╕рд▓рд┐рдП, рд╣рдо рдЗрд╕реЗ
abstract
рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рд╣рдореЗрдВ рдЗрд╕рдХреА рд╡рд╕реНрддреБрдУрдВ рдХреЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЛ рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрдЧрд╛ред
using UnityEngine; using UnityEngine.SceneManagement; public abstract class GameObjectFactory : ScriptableObject { Scene scene; protected T CreateGameObjectInstance<T> (T prefab) where T : MonoBehaviour { if (!scene.isLoaded) { if (Application.isEditor) { scene = SceneManager.GetSceneByName(name); if (!scene.isLoaded) { scene = SceneManager.CreateScene(name); } } else { scene = SceneManager.CreateScene(name); } } T instance = Instantiate(prefab); SceneManager.MoveGameObjectToScene(instance.gameObject, scene); return instance; } }
GameTileContentFactory
рдмрджрд▓реЗрдВ рддрд╛рдХрд┐ рдпрд╣ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреА рдлреИрдХреНрдЯреНрд░реА рдХреЛ
GameTileContentFactory
рдФрд░ рдЕрдкрдиреЗ
Get
CreateGameObjectInstance
рдореЗрдВ
CreateGameObjectInstance
рдХрд╛ рдЙрдкрдпреЛрдЧ
CreateGameObjectInstance
рдФрд░ рдлрд┐рд░ рдЗрд╕рдореЗрдВ рд╕реЗ рд╕реАрди рдХрдВрдЯреНрд░реЛрд▓ рдХреЛрдб рдХреЛ рд╣рдЯрд╛ рджреЗрдВред
using UnityEngine; [CreateAssetMenu] public class GameTileContentFactory : GameObjectFactory { тАж
рдЙрд╕рдХреЗ рдмрд╛рдж, рдПрдХ рдирдпрд╛
EnemyFactory
рдкреНрд░рдХрд╛рд░ рдмрдирд╛рдПрдБ, рдЬреЛ
Reclaim
Get
рд╡рд┐рдзрд┐ рдХреЗ рд╕рд╛рде-рд╕рд╛рде
Get
рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ
Enemy
EnemyFactory
рдПрдХ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рддрд╛ рд╣реИред
using UnityEngine; [CreateAssetMenu] public class EnemyFactory : GameObjectFactory { [SerializeField] Enemy prefab = default; public Enemy Get () { Enemy instance = CreateGameObjectInstance(prefab); instance.OriginFactory = this; return instance; } public void Reclaim (Enemy enemy) { Debug.Assert(enemy.OriginFactory == this, "Wrong factory reclaimed!"); Destroy(enemy.gameObject); } }
рдирдП
Enemy
рдкреНрд░рдХрд╛рд░ рдХреЛ рд╢реБрд░реВ рдореЗрдВ рдХреЗрд╡рд▓ рдЕрдкрдиреЗ рдореВрд▓ рдХрд╛рд░рдЦрд╛рдиреЗ рдХрд╛ рдзреНрдпрд╛рди рд░рдЦрдирд╛ рдерд╛ред
using UnityEngine; public class Enemy : MonoBehaviour { EnemyFactory originFactory; public EnemyFactory OriginFactory { get => originFactory; set { Debug.Assert(originFactory == null, "Redefined origin factory!"); originFactory = value; } } }
рдкреВрд░реНрд╡рдирд┐рд░реНрдорд┐рдд
рджреБрд╢реНрдордиреЛрдВ рдХреЛ рд╡рд┐рдЬрд╝реБрдЕрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬреЛ рдХреБрдЫ рднреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ - рдПрдХ рд░реЛрдмреЛрдЯ, рдПрдХ рдордХрдбрд╝реА, рдПрдХ рднреВрдд, рдХреБрдЫ рд╕рд░рд▓, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдШрди, рдЬреЛ рд╣рдо рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рджреБрд╢реНрдорди рдХреЗ рдкрд╛рд╕ рдХрд┐рд╕реА рднреА рдЬрдЯрд┐рд▓рддрд╛ рдХрд╛ 3 рдбреА рдореЙрдбрд▓ рд╣реЛрддрд╛ рд╣реИред рдЗрд╕рдХрд╛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╕рдорд░реНрдерди рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╢рддреНрд░реБ рдкреНрд░реАрдлреИрдм рдкрджрд╛рдиреБрдХреНрд░рдо рдХреЗ рд▓рд┐рдП рд░реВрдЯ рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ, рдЬрд┐рд╕рдореЗрдВ рдХреЗрд╡рд▓
Enemy
рдШрдЯрдХ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИред
рдкреНрд░реАрдлреИрдм рд░реВрдЯрдЖрдЗрдП рдЗрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдПрдХрдорд╛рддреНрд░ рдмрд╛рд▓ рддрддреНрд╡ рдмрдирд╛рддреЗ рд╣реИрдВ, рдЬреЛ рдореЙрдбрд▓ рдХрд╛ рдореВрд▓ рд╣реЛрдЧрд╛ред рдЗрд╕рдореЗрдВ рдЯреНрд░рд╛рдВрд╕рдлреЙрд░реНрдо рдпреВрдирд┐рдЯ рд╡реИрд▓реНрдпреВ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред
рдореЙрдбрд▓ рдХреА рдЬрдбрд╝редрдЗрд╕ рдореЙрдбрд▓ рд░реВрдЯ рдХрд╛ рдХрд╛рд░реНрдп 3 рдбреА рдореЙрдбрд▓ рдХреЛ рджреБрд╢реНрдорди рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреА рдЙрддреНрдкрддреНрддрд┐ рдХреЗ рд╕реНрдерд╛рдиреАрдп рдмрд┐рдВрджреБ рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рд╕реНрдерд┐рдд рдХрд░рдирд╛ рд╣реИ, рддрд╛рдХрд┐ рд╡рд╣ рдЗрд╕реЗ рдПрдХ рд╕рдВрджрд░реНрдн рдмрд┐рдВрджреБ рдорд╛рдирддрд╛ рд╣реИ, рдЬрд┐рд╕ рдкрд░ рджреБрд╢реНрдорди рдЦрдбрд╝рд╛ рд╣реЛрддрд╛ рд╣реИ рдпрд╛ рд▓рдЯрдХрд╛ рд░рд╣рддрд╛ рд╣реИред рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдореЙрдбрд▓ рдПрдХ рдорд╛рдирдХ рдЖрдзрд╛ рдЖрдХрд╛рд░ рдХрд╛ рдХреНрдпреВрдм рд╣реЛрдЧрд╛, рдЬрд┐рд╕реЗ рдореИрдВ рдЧрд╣рд░реЗ рдиреАрд▓реЗ рд░рдВрдЧ рдХрд╛ рд░рдВрдЧ рджреВрдВрдЧрд╛ред рд╣рдо рдЗрд╕реЗ рдореЙрдбрд▓ рд░реВрдЯ рдХрд╛ рдмрдЪреНрдЪрд╛ рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рд╡рд╛рдИ рд╕реНрдерд┐рддрд┐ рдХреЛ 0.25 рдкрд░ рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдпрд╣ рдЬрдореАрди рдкрд░ рдЦрдбрд╝рд╛ рд╣реЛред
рдШрди рдореЙрдбрд▓рдЗрд╕ рдкреНрд░рдХрд╛рд░, рджреБрд╢реНрдорди рдХреЗ рдкреНрд░реАрдлреИрдм рдореЗрдВ рддреАрди рдиреЗрд╕реНрдЯреЗрдб рдСрдмреНрдЬреЗрдХреНрдЯ рд╣реЛрддреЗ рд╣реИрдВ: рдкреНрд░реАрдлреИрдм рд░реВрдЯ, рдореЙрдбрд▓ рд░реВрдЯ, рдФрд░ рдХреНрдпреВрдмред рдпрд╣ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдШрди рдХреЗ рд▓рд┐рдП рдПрдХ рд╣рд▓рдЪрд▓ рдХреА рддрд░рд╣ рд▓рдЧ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕ рддрд░рд╣ рдХреА рдкреНрд░рдгрд╛рд▓реА рдЖрдкрдХреЛ рдЗрд╕рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд┐рдВрддрд╛ рдХрд┐рдП рдмрд┐рдирд╛ рдХрд┐рд╕реА рднреА рджреБрд╢реНрдорди рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдФрд░ рдЪреЗрддрди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИред
рджреБрд╢реНрдорди рдХрд╛ рдкреВрд░реНрд╡рдкрдж рдкрджрд╛рдиреБрдХреНрд░рдоредрдЪрд▓реЛ рдПрдХ рджреБрд╢реНрдорди рдХрд╛ рдХрд╛рд░рдЦрд╛рдирд╛ рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рдПрдХ рдкреНрд░реАрдлреИрдм рдЕрд╕рд╛рдЗрди рдХрд░рддреЗ рд╣реИрдВред
рдПрд╕реЗрдЯ рдлреИрдХреНрдЯреНрд░реАредрдореИрджрд╛рди рдкрд░ рджреБрд╢реНрдордиреЛрдВ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдирд╛
рджреБрд╢реНрдордиреЛрдВ рдХреЛ рдореИрджрд╛рди рдкрд░ рд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП,
Game
рдХреЛ рджреБрд╢реНрдордиреЛрдВ рдХреЗ рдХрд╛рд░рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд▓рд┐рдВрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЪреВрдВрдХрд┐ рд╣рдореЗрдВ рджреБрд╢реНрдордиреЛрдВ рдХреА рдмрд╣реБрдд рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб рджреБрд╢реНрдордиреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╡реНрдпрдХреНрдд рдХреА рдЧрдИ рд╕реНрдкреЙрдирд┐рдВрдЧ рдХреА рдЧрддрд┐ рдХреЛ рд╕рдорд╛рдпреЛрдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╡рд┐рдХрд▓реНрдк рдЬреЛрдбрд╝реЗрдВрдЧреЗред рдПрдХ рд╕реНрд╡реАрдХрд╛рд░реНрдп рд╕реАрдорд╛ 1 рдХреЗ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди рдХреЗ рд╕рд╛рде 0.1-10 рд╣реИред
[SerializeField] EnemyFactory enemyFactory = default; [SerializeField, Range(0.1f, 10f)] float spawnSpeed = 1f;
рдПрдХ рджреБрд╢реНрдорди рдХрд╛рд░рдЦрд╛рдиреЗ рдФрд░ 4 рдЧрддрд┐ spawning рдХреЗ рд╕рд╛рде рдЦреЗрд▓редрд╣рдо
Update
рдореЗрдВ рд╕реНрдкреЙрдирд┐рдВрдЧ рдХреА рдкреНрд░рдЧрддрд┐ рдХреЛ рдЯреНрд░реИрдХ рдХрд░реЗрдВрдЧреЗ, рдЗрд╕реЗ рдбреЗрд▓реНрдЯрд╛ рд╕рдордп рдХреА рдЧрддрд┐ рд╕реЗ рдмрдврд╝рд╛рдПрдВрдЧреЗред рдпрджрд┐ prggress рдорд╛рди 1 рд╕реЗ рдЕрдзрд┐рдХ рд╣реИ, рддреЛ рд╣рдо рдЗрд╕реЗ
SpawnEnemy
рдФрд░ рдирдП
SpawnEnemy
рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рджреБрд╢реНрдорди рдХреЛ рд╕реНрдкреЙрди рдХрд░рддреЗ рд╣реИрдВред рд╣рдо рдЗрд╕реЗ рддрдм рддрдХ рдЬрд╛рд░реА рд░рдЦрддреЗ рд╣реИрдВ рдЬрдм рддрдХ рдХрд┐ рдкреНрд░рдЧрддрд┐ 1 рд╕реЗ рдЕрдзрд┐рдХ рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддреА рд╣реИ рдпрджрд┐ рдЧрддрд┐ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╣реИ рдФрд░ рдлреНрд░реЗрдо рдХрд╛ рд╕рдордп рдмрд╣реБрдд рд▓рдВрдмрд╛ рд╣реИ рддрд╛рдХрд┐ рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдХрдИ рджреБрд╢реНрдорди рдкреИрджрд╛ рди рд╣реЛрдВред
float spawnProgress; тАж void Update () { тАж spawnProgress += spawnSpeed * Time.deltaTime; while (spawnProgress >= 1f) { spawnProgress -= 1f; SpawnEnemy(); } }
рдХреНрдпрд╛ FixedUpdate рдореЗрдВ рдкреНрд░рдЧрддрд┐ рдХреЛ рдЕрджреНрдпрддрди рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ?рд╣рд╛рдВ, рдпрд╣ рд╕рдВрднрд╡ рд╣реИ, рд▓реЗрдХрд┐рди рдЯреЙрд╡рд░ рд░рдХреНрд╖рд╛ рдЦреЗрд▓ рдХреЗ рд▓рд┐рдП рдЗрд╕ рддрд░рд╣ рдХреЗ рд╕рдЯреАрдХ рд╕рдордп рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рд╣рдо рдмрд╕ рд╣рд░ рдлреНрд░реЗрдо рдореЗрдВ рдЧреЗрдо рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВрдЧреЗ рдФрд░ рдХрд┐рд╕реА рднреА рд╕рдордп рдбреЗрд▓реНрдЯрд╛ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд░реВрдк рд╕реЗ рдХрд╛рдо рдХрд░реЗрдВрдЧреЗред
рдмрддрд╛ рджреЗрдВ рдХрд┐
SpawnEnemy
рдХреЛ рдореИрджрд╛рди рд╕реЗ рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд╕реНрдкреЙрди рдкреЙрдЗрдВрдЯ рдорд┐рд▓рддрд╛ рд╣реИ рдФрд░ рдЗрд╕ рдЯрд╛рдЗрд▓ рдореЗрдВ рдПрдХ рджреБрд╢реНрдорди рдмрдирд╛рддреЗ рд╣реИрдВред рд╣рдо
Enemy
рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ
SpawnOn
рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП
SpawnOn
рд╡рд┐рдзрд┐ рджреЗрдВрдЧреЗред
void SpawnEnemy () { GameTile spawnPoint = board.GetSpawnPoint(Random.Range(0, board.SpawnPointCount)); Enemy enemy = enemyFactory.Get(); enemy.SpawnOn(spawnPoint); }
рдЕрднреА рдХреЗ рд▓рд┐рдП, рд╕рднреА
SpawnOn
рдХреЛ рдЯрд╛рдЗрд▓ рдХреЗ рдХреЗрдВрджреНрд░ рдХреЗ рдмрд░рд╛рдмрд░ рдЕрдкрдиреА рд╕реНрдерд┐рддрд┐ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреА рд╣реЛрдЧреАред рдЪреВрдВрдХрд┐ рдкреНрд░реАрдлреИрдм рдореЙрдбрд▓ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рддреИрдирд╛рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рджреБрд╢реНрдорди рдХрд╛ рдХреНрдпреВрдм рдЗрд╕ рдЯрд╛рдЗрд▓ рдХреЗ рдКрдкрд░ рд╣реЛрдЧрд╛ред
public void SpawnOn (GameTile tile) { transform.localPosition = tile.transform.localPosition; }
рджреБрд╢реНрдорди рд╕реНрдкреЙрди рдкреЙрдЗрдВрдЯ рдкрд░ рджрд┐рдЦрд╛рдИ рджреЗрддреЗ рд╣реИрдВредрд╣рд┐рд▓рддреЗ рд╣реБрдП рджреБрд╢реНрдорди
рд╢рддреНрд░реБ рдХреЗ рдкреНрд░рдХрдЯ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рдЙрд╕реЗ рдирд┐рдХрдЯрддрдо рдЕрдВрдд рдмрд┐рдВрджреБ рдХреЗ рд▓рд┐рдП рдорд╛рд░реНрдЧ рдХреЗ рд╕рд╛рде рдЪрд▓рдирд╛ рд╢реБрд░реВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рджреБрд╢реНрдордиреЛрдВ рдХреЛ рдЪреЗрддрди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╣рдо рдЯрд╛рдЗрд▓ рд╕реЗ рдЯрд╛рдЗрд▓ рддрдХ рдПрдХ рд╕рд░рд▓ рдЪрд┐рдХрдиреА рдЧреНрд▓рд╛рдЗрдб рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдЙрдирдХреЗ рдЖрдВрджреЛрд▓рди рдХреЛ рдЕрдзрд┐рдХ рдХрдард┐рди рдмрдирд╛рддреЗ рд╣реИрдВред
рджреБрд╢реНрдордиреЛрдВ рдХрд╛ рд╕рдВрдЧреНрд░рд╣
рджреБрд╢реНрдордиреЛрдВ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЙрд╕реА рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреЗ
рдСрдмреНрдЬреЗрдХреНрдЯ рдкреНрд░рдмрдВрдзрди рд╢реНрд░реГрдВрдЦрд▓рд╛ рдореЗрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рд╣рдо
Enemy
рд╕рд╛рдорд╛рдиреНрдп
GameUpdate
рдкрджреНрдзрддрд┐ рд╕реЗ
GameUpdate
, рдЬреЛ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рджреЗрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╡рд╣ рдЬреАрд╡рд┐рдд рд╣реИ, рдЬреЛ рдЗрд╕ рд╕реНрддрд░ рдкрд░ рд╣рдореЗрд╢рд╛ рд╕рд╣реА рд░рд╣реЗрдЧрд╛ред рдЕрднреА рдХреЗ рд▓рд┐рдП, рдмрд╕ рдЙрд╕реЗ рд╕рдордп рдХреЗ рдбреЗрд▓реНрдЯрд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЖрдЧреЗ рдмрдврд╝рд╛рдПрдВред
public bool GameUpdate () { transform.localPosition += Vector3.forward * Time.deltaTime; return true; }
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдореЗрдВ рдЬреАрд╡рд┐рдд рджреБрд╢реНрдордиреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдмрдирд╛рдП рд░рдЦрдиреЗ рдФрд░ рд╕рднреА рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЙрдиреНрд╣реЗрдВ рдореГрдд рджреБрд╢реНрдордиреЛрдВ рдХреА рд╕реВрдЪреА рд╕реЗ рд╣рдЯрд╛ рджреЗрдВред рд╣рдо рдЗрд╕ рд╕рд╛рд░реЗ рдХреЛрдб рдХреЛ
Game
рдореЗрдВ рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдЗрд╕реЗ рдЕрд▓рдЧ рдХрд░рдХреЗ рдПрдХ
EnemyCollection
рдкреНрд░рдХрд╛рд░ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдПрдХ рдЕрдиреБрдХреНрд░рдорд┐рдХ рд╡рд░реНрдЧ рд╣реИ рдЬреЛ рдХрд┐рд╕реА рднреА рдЪреАрдЬрд╝ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдирд╣реАрдВ рдорд┐рд▓рддрд╛ рд╣реИред рд╣рдо рдЙрдиреНрд╣реЗрдВ рдПрдХ рджреБрд╢реНрдорди рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рддрд░реАрдХрд╛ рджреЗрддреЗ рд╣реИрдВ рдФрд░ рдкреВрд░реЗ рд╕рдВрдЧреНрд░рд╣ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдФрд░ рддрд░реАрдХрд╛ рджреЗрддреЗ рд╣реИрдВред
using System.Collections.Generic; [System.Serializable] public class EnemyCollection { List<Enemy> enemies = new List<Enemy>(); public void Add (Enemy enemy) { enemies.Add(enemy); } public void GameUpdate () { for (int i = 0; i < enemies.Count; i++) { if (!enemies[i].GameUpdate()) { int lastIndex = enemies.Count - 1; enemies[i] = enemies[lastIndex]; enemies.RemoveAt(lastIndex); i -= 1; } } } }
рдЕрдм
Game
рдХреЗрд╡рд▓ рдПрдХ рд╣реА рд╕рдВрдЧреНрд░рд╣ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрдЧрд╛, рдкреНрд░рддреНрдпреЗрдХ рдлреНрд░реЗрдо рдореЗрдВ рдЗрд╕реЗ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВ рдФрд░ рдЗрд╕рдореЗрдВ рдмрдирд╛рдП рдЧрдП рджреБрд╢реНрдорди рдЬреЛрдбрд╝реЗрдВред рд╣рдо рдПрдХ рдирдП рджреБрд╢реНрдорди рдХреЗ рд╕рдВрднрд╛рд╡рд┐рдд рд╕реНрдкреИрдирд┐рдВрдЧ рдХреЗ рддреБрд░рдВрдд рдмрд╛рдж рджреБрд╢реНрдордиреЛрдВ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВрдЧреЗ рддрд╛рдХрд┐ рдЕрдкрдбреЗрдЯ рддреБрд░рдВрдд рд╣реЛред
EnemyCollection enemies = new EnemyCollection(); тАж void Update () { тАж enemies.GameUpdate(); } тАж void SpawnEnemy () { тАж enemies.Add(enemy); }
рд╢рддреНрд░реБ рдЖрдЧреЗ рдмрдврд╝ рд░рд╣реЗ рд╣реИрдВредрд░рд╛рд╕реНрддреЗ рдореЗрдВ рд╣рд▓рдЪрд▓
рджреБрд╢реНрдорди рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЖрдЧреЗ рдмрдврд╝ рд░рд╣реЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЕрднреА рддрдХ рдкрде рдХрд╛ рдЕрдиреБрд╕рд░рдг рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЙрдиреНрд╣реЗрдВ рдпрд╣ рдЬрд╛рдирдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдЖрдЧреЗ рдХрд╣рд╛рдБ рдЬрд╛рдирд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдЪрд▓рд┐рдП
GameTile
рдХреЛ рдкрде рдкрд░ рдЕрдЧрд▓реА рдЯрд╛рдЗрд▓ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
GameTile
рд╕рд╛рдорд╛рдиреНрдп рдЧреЗрдЯрд░ рдкреНрд░реЙрдкрд░реНрдЯреА рджреЗрдВред
public GameTile NextTileOnPath => nextOnPath;
рдЙрд╕ рдЯрд╛рдЗрд▓ рдХреЛ рдЬрд╛рдирдирд╛ рдЬрд┐рд╕рд╕реЗ рдЖрдк рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдФрд░ рдЬрд┐рд╕ рдЯрд╛рдЗрд▓ рдореЗрдВ рдЖрдкрдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рджреБрд╢реНрдорди рдПрдХ рдЯрд╛рдЗрд▓ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рд░рдВрдн рдФрд░ рдЕрдВрдд рдмрд┐рдВрджреБ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рджреБрд╢реНрдорди рдЗрди рджреЛ рдмрд┐рдВрджреБрдУрдВ рдХреЗ рдмреАрдЪ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдкреНрд░рдХреНрд╖реЗрдкрд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЙрдирдХреЗ рдЖрдВрджреЛрд▓рди рдкрд░ рдирдЬрд╝рд░ рд░рдЦ рд╕рдХрддрд╛ рд╣реИред рдЪрд╛рд▓ рдкреВрд░реА рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рдпрд╣ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЕрдЧрд▓реЗ рдЯрд╛рдЗрд▓ рдХреЗ рд▓рд┐рдП рджреЛрд╣рд░рд╛рдИ рдЬрд╛рддреА рд╣реИред рд▓реЗрдХрд┐рди рд░рд╛рд╕реНрддреЗ рдХрднреА рднреА рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдВрджреЛрд▓рди рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдЖрдЧреЗ рдмрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рд╣рдо рдмрд╕ рдпреЛрдЬрдирд╛рдмрджреНрдз рдорд╛рд░реНрдЧ рдХреЗ рд╕рд╛рде рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рдЬрд╛рдВрдЪрддреЗ рд╣реИрдВ, рдЕрдЧрд▓реА рдЯрд╛рдЗрд▓ рддрдХ рдкрд╣реБрдВрдЪрддреЗ рд╣реИрдВред
Enemy
рджреЛрдиреЛрдВ рдЯрд╛рдЗрд▓реЛрдВ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рджреЗрдВ, рддрд╛рдХрд┐ рд╡рд╣ рдорд╛рд░реНрдЧ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рд╕реЗ рдкреНрд░рднрд╛рд╡рд┐рдд рди рд╣реЛред рд╡рд╣ рдкрджреЛрдВ рдХреЛ рднреА рдЯреНрд░реИрдХ рдХрд░реЗрдЧрд╛ рддрд╛рдХрд┐ рд╣рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдлреНрд░реЗрдо рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рди рдХрд░рдирд╛ рдкрдбрд╝реЗ, рдФрд░ рдЪрд▓рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдирд╛ рдкрдбрд╝реЗред
GameTile tileFrom, tileTo; Vector3 positionFrom, positionTo; float progress;
SpawnOn
рдореЗрдВ рдЗрди рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ
SpawnOn
ред рдкрд╣рд▓рд╛ рдмрд┐рдВрджреБ рд╡рд╣ рдЯрд╛рдЗрд▓ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рджреБрд╢реНрдорди рдЖрдЧреЗ рдмрдврд╝ рд░рд╣рд╛ рд╣реИ, рдФрд░ рдЕрдВрддрд┐рдо рдмрд┐рдВрджреБ рдкрде рдкрд░ рдЕрдЧрд▓реА рдЯрд╛рдЗрд▓ рд╣реИред рдпрд╣ рдорд╛рдирддрд╛ рд╣реИ рдХрд┐ рдЕрдЧрд▓реА рдЯрд╛рдЗрд▓ рдореМрдЬреВрдж рд╣реИ, рдЬрдм рддрдХ рдХрд┐ рдЕрдВрддрд┐рдо рдмрд┐рдВрджреБ рдкрд░ рджреБрд╢реНрдорди рдирд╣реАрдВ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЬреЛ рдЕрд╕рдВрднрд╡ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдлрд┐рд░ рд╣рдо рдЯрд╛рдЗрд▓реНрд╕ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдХреИрд╢ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдкреНрд░рдЧрддрд┐ рдХреЛ рд░реАрд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВред рд╣рдореЗрдВ рдпрд╣рд╛рдВ рджреБрд╢реНрдорди рдХреА рд╕реНрдерд┐рддрд┐ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЙрд╕рдХреА
GameUpdate
рдкрджреНрдзрддрд┐
GameUpdate
рдПрдХ рд╣реА рдлреНрд░реЗрдо рдореЗрдВ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред
public void SpawnOn (GameTile tile) {
GameUpdate
рдореЗрдВ рдкреНрд░рдЧрддрд┐ рд╡реГрджреНрдзрд┐ рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЖрдЗрдП рдПрдХ рд╕реНрдерд┐рд░ рд╕рдордп рдбреЗрд▓реНрдЯрд╛ рдЬреЛрдбрд╝реЗрдВ, рддрд╛рдХрд┐ рджреБрд╢реНрдорди рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб рдПрдХ рдЯрд╛рдЗрд▓ рдХреА рдЧрддрд┐ рд╕реЗ рдЖрдЧреЗ рдмрдврд╝реЗрдВред рдЬрдм рдкреНрд░рдЧрддрд┐ рдкреВрд░реА рд╣реЛ рдЬрд╛рддреА рд╣реИ, рддреЛ рд╣рдо рдбреЗрдЯрд╛ рдХреЛ рд╢рд┐рдлреНрдЯ рдХрд░ рджреЗрддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдореВрд▓реНрдп
From
, рдФрд░ рдирдпрд╛ TO рдкрде рдкрд░ рдЕрдЧрд▓реА рдЯрд╛рдЗрд▓ рдмрди рдЬрд╛рдПред рдлрд┐рд░ рд╣рдо рдкреНрд░рдЧрддрд┐ рдореЗрдВ рдХрдореА рдХрд░рддреЗ рд╣реИрдВред рдЬрдм рдбреЗрдЯрд╛ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╣рдо
From
рдФрд░ рдХреЗ рдмреАрдЪ рджреБрд╢реНрдорди рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдкреНрд░рдХреНрд╖реЗрдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдЪреВрдВрдХрд┐ рдкреНрд░рдХреНрд╖реЗрдкрдХ рдкреНрд░рдЧрддрд┐ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕рдХрд╛ рдорд╛рди рдЖрд╡рд╢реНрдпрдХ рд░реВрдк рд╕реЗ 0 рдФрд░ 1 рдХреА рд╕реАрдорд╛ рдореЗрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо s
Vector3.LerpUnclamped
рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
Vector3.LerpUnclamped
ред
public bool GameUpdate () { progress += Time.deltaTime; while (progress >= 1f) { tileFrom = tileTo; tileTo = tileTo.NextTileOnPath; positionFrom = positionTo; positionTo = tileTo.transform.localPosition; progress -= 1f; } transform.localPosition = Vector3.LerpUnclamped(positionFrom, positionTo, progress); return true; }
рдпрд╣ рджреБрд╢реНрдордиреЛрдВ рдХреЛ рдкрде рдХрд╛ рдЕрдиреБрд╕рд░рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдВрддрд┐рдо рдмрд┐рдВрджреБ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдкрд░ рдХрд╛рд░реНрдп рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред рдЗрд╕рд▓рд┐рдП,
From
рдФрд░
To
рдХреА рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЛ рдмрджрд▓рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдЖрдкрдХреЛ
null
рд╕рд╛рде рдкрде рдкрд░ рдЕрдЧрд▓реЗ рдЯрд╛рдЗрд▓ рдХреА рддреБрд▓рдирд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрджрд┐ рдРрд╕рд╛ рд╣реИ, рддреЛ рд╣рдо рдЕрдВрддрд┐рдо рдмрд┐рдВрджреБ рдкрд░ рдкрд╣реБрдВрдЪ рдЧрдП рд╣реИрдВ рдФрд░ рджреБрд╢реНрдорди рдиреЗ рдЖрдВрджреЛрд▓рди рд╕рдорд╛рдкреНрдд рдХрд░ рджрд┐рдпрд╛ рд╣реИред рд╣рдо рдЗрд╕рдХреЗ рд▓рд┐рдП Reclaim рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░
false
рд╡рд╛рдкрд╕ рдЖрддреЗ рд╣реИрдВред
while (progress >= 1f) { tileFrom = tileTo; tileTo = tileTo.NextTileOnPath; if (tileTo == null) { OriginFactory.Reclaim(this); return false; } positionFrom = positionTo; positionTo = tileTo.transform.localPosition; progress -= 1f; }
рджреБрд╢реНрдорди рд╕рдмрд╕реЗ рдЫреЛрдЯрд╛ рд░рд╛рд╕реНрддрд╛ рдЕрдкрдирд╛рддреЗ рд╣реИрдВредрджреБрд╢реНрдорди рдЕрдм рдПрдХ рдЯрд╛рдЗрд▓ рдХреЗ рдХреЗрдВрджреНрд░ рд╕реЗ рджреВрд╕рд░реЗ рдореЗрдВ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВред рдпрд╣ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рд╡реЗ рдХреЗрд╡рд▓ рдЯрд╛рдЗрд▓реЛрдВ рдХреЗ рдХреЗрдВрджреНрд░реЛрдВ рдореЗрдВ рдЕрдкрдиреЗ рдЖрдВрджреЛрд▓рди рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдмрджрд▓рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╡реЗ рддреБрд░рдВрдд рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХрд╛ рдЬрд╡рд╛рдм рдирд╣реАрдВ рджреЗ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдХрднреА-рдХрднреА рджреБрд╢реНрдорди рд╕рд┐рд░реНрдл рдирд┐рд░реНрдзрд╛рд░рд┐рдд рджреАрд╡рд╛рд░реЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЖрдЧреЗ рдмрдврд╝реЗрдВрдЧреЗред рдПрдХ рдмрд╛рд░ рдЬрдм рд╡реЗ рд╕реЗрд▓ рдХреА рдУрд░ рдмрдврд╝рдиреЗ рд▓рдЧреЗ, рддреЛ рдХреБрдЫ рднреА рдЙрдиреНрд╣реЗрдВ рд░реЛрдХ рдирд╣реАрдВ рдкрд╛рдПрдЧрд╛ред рдЗрд╕реАрд▓рд┐рдП рджреАрд╡рд╛рд░реЛрдВ рдХреЛ рднреА рдЕрд╕рд▓реА рд░рд╛рд╕реНрддреЛрдВ рдХреА рдЬрд░реВрд░рдд рд╣реЛрддреА рд╣реИред
рджреБрд╢реНрдорди рдмрджрд▓рддреЗ рд░рд╛рд╕реНрддреЛрдВ рдкрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрд░рддреЗ рд╣реИрдВредрдПрдЬ рдЯреВ рдПрдЬ рдореВрд╡рдореЗрдВрдЯ
рдЯрд╛рдЗрд▓реЛрдВ рдХреЗ рдХреЗрдВрджреНрд░реЛрдВ рдФрд░ рджрд┐рд╢рд╛ рдХреЗ рддреЗрдЬ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдмреАрдЪ рдХреА рдЧрддрд┐ рдПрдХ рдЕрдореВрд░реНрдд рдЦреЗрд▓ рдХреЗ рд▓рд┐рдП рд╕рд╛рдорд╛рдиреНрдп рд▓рдЧрддреА рд╣реИ рдЬрд┐рд╕рдореЗрдВ рджреБрд╢реНрдорди рдХреНрдпреВрдмреНрд╕ рдХреЛ рдШреБрдорд╛ рд░рд╣реЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЖрдорддреМрд░ рдкрд░ рдЪрд┐рдХрдиреА рдЖрдВрджреЛрд▓рди рдЕрдзрд┐рдХ рд╕реБрдВрджрд░ рджрд┐рдЦрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рдкрд╣рд▓рд╛ рдХрджрдо рдХреЗрдВрджреНрд░реЛрдВ рдХреЗ рд╕рд╛рде рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдЯрд╛рдЗрд▓реЛрдВ рдХреЗ рдХрд┐рдирд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдЪрд▓рдирд╛ рд╣реИред
рдЖрд╕рдиреНрди рдЯрд╛рдЗрд▓реЛрдВ рдХреЗ рдмреАрдЪ рдХрд╛ рдХрд┐рдирд╛рд░рд╛ рдмрд┐рдВрджреБ рдЙрдирдХреЗ рдкрджреЛрдВ рдХреЗ рдФрд╕рдд рд╕реЗ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рджреБрд╢реНрдорди рдХреЗ рд▓рд┐рдП рд╣рд░ рдХрджрдо рдкрд░ рдЗрд╕рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рд╣рдо рдХреЗрд╡рд▓
GameTile.GrowPathTo
рдореЗрдВ рдкрде рдмрджрд▓рддреЗ рд╕рдордп рдЗрд╕рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВрдЧреЗред
ExitPoint
рд╕рдВрдкрддреНрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рдЙрдкрд▓рдмреНрдз
ExitPoint
ред
public Vector3 ExitPoint { get; private set; } тАж GameTile GrowPathTo (GameTile neighbor) { тАж neighbor.ExitPoint = (neighbor.transform.localPosition + transform.localPosition) * 0.5f; return neighbor.Content.Type != GameTileContentType.Wall ? neighbor : null; }
рдПрдХрдорд╛рддреНрд░ рд╡рд┐рд╢реЗрд╖ рдорд╛рдорд▓рд╛ рдЕрдВрддрд┐рдо рд╕реЗрд▓ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдирд┐рдХрд╛рд╕ рдмрд┐рдВрджреБ рдЗрд╕рдХрд╛ рдХреЗрдВрджреНрд░ рд╣реЛрдЧрд╛ред
public void BecomeDestination () { distance = 0; nextOnPath = null; ExitPoint = transform.localPosition; }
Enemy
рдмрджрд▓реЗрдВ рддрд╛рдХрд┐ рдпрд╣ рдирд┐рдХрд╛рд╕ рдХреЗрдВрджреНрд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗ, рди рдХрд┐ рдЯрд╛рдЗрд▓ рдХреЗрдВрджреНрд░реЛрдВ рдХрд╛ред
public bool GameUpdate () { progress += Time.deltaTime; while (progress >= 1f) { тАж positionTo = tileFrom.ExitPoint; progress -= 1f; } transform.localPosition = Vector3.Lerp(positionFrom, positionTo, progress); return true; } public void SpawnOn (GameTile tile) { тАж positionTo = tileFrom.ExitPoint; progress = 0f; }
рджреБрд╢реНрдорди рдХрд┐рдирд╛рд░реЛрдВ рдХреЗ рдмреАрдЪ рдЪрд▓рддреЗ рд╣реИрдВредрдЗрд╕ рдкрд░рд┐рд╡рд░реНрддрди рдХрд╛ рдПрдХ рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯ рдпрд╣ рд╣реИ рдХрд┐ рдЬрдм рджреБрд╢реНрдорди рд░рд╛рд╕реНрддреЗ рдореЗрдВ рдмрджрд▓рд╛рд╡ рдХреЗ рдХрд╛рд░рдг рдореБрдбрд╝рддреЗ рд╣реИрдВ, рддреЛ рд╡реЗ рдПрдХ рд╕реЗрдХрдВрдб рдХреЗ рд▓рд┐рдП рдЧрддрд┐рд╣реАрди рд░рд╣рддреЗ рд╣реИрдВред
рдореБрдбрд╝рддреЗ рд╕рдордп рджреБрд╢реНрдорди рд░реБрдХ рдЬрд╛рддреЗ рд╣реИрдВредрдЙрдиреНрдореБрдЦреАрдХрд░рдг
рдпрджреНрдпрдкрд┐ рд╢рддреНрд░реБ рд░рд╛рд╕реНрддреЛрдВ рдХреЗ рд╕рд╛рде рдЪрд▓рддреЗ рд╣реИрдВ рдЬрдм рддрдХ рдХрд┐ рд╡реЗ рдЕрдкрдиреА рдЕрднрд┐рд╡рд┐рдиреНрдпрд╛рд╕ рдХреЛ рдирд╣реАрдВ рдмрджрд▓рддреЗред рддрд╛рдХрд┐ рд╡реЗ рдЖрдВрджреЛрд▓рди рдХреА рджрд┐рд╢рд╛ рдореЗрдВ рджреЗрдЦ рд╕рдХреЗрдВ, рдЙрдиреНрд╣реЗрдВ рдЙрд╕ рдорд╛рд░реНрдЧ рдХреА рджрд┐рд╢рд╛ рдЬрд╛рдирдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рд╡реЗ рдЕрдиреБрд╕рд░рдг рдХрд░ рд░рд╣реЗ рд╣реИрдВред рд╣рдо рдЗрд╕реЗ рддрд░реАрдХреЛрдВ рдХреА рдЦреЛрдЬ рдХреЗ рджреМрд░рд╛рди рднреА рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВрдЧреЗ, рддрд╛рдХрд┐ рджреБрд╢реНрдордиреЛрдВ рджреНрд╡рд╛рд░рд╛ рдРрд╕рд╛ рди рдХрд┐рдпрд╛ рдЬрд╛рдПред
рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЪрд╛рд░ рджрд┐рд╢рд╛рдПрдБ рд╣реИрдВ: рдЙрддреНрддрд░, рдкреВрд░реНрд╡, рджрдХреНрд╖рд┐рдг рдФрд░ рдкрд╢реНрдЪрд┐рдоред рдЖрдЗрдП рд╣рдо рдЙрдирдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВред
public enum Direction { North, East, South, West }
рдлрд┐рд░ рд╣рдо рдЗрд╕рдХреЗ рдкрде рдХреА рджрд┐рд╢рд╛ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
GameTile
рдЧреБрдг
GameTile
рд╣реИрдВред
public Direction PathDirection { get; private set; }
GrowTo
рд▓рд┐рдП рдПрдХ рджрд┐рд╢рд╛ рдкреИрд░рд╛рдореАрдЯрд░ рдЬреЛрдбрд╝реЗрдВ, рдЬреЛ рд╕рдВрдкрддреНрддрд┐ рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИред рдЪреВрдВрдХрд┐ рд╣рдо рд╢реБрд░реВ рд╕реЗ рдЕрдВрдд рддрдХ рдПрдХ рд░рд╛рд╕реНрддрд╛ рдмрдврд╝рд╛ рд░рд╣реЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рджрд┐рд╢рд╛ рдЙрд╕ рджрд┐рд╢рд╛ рдХреЗ рд╡рд┐рдкрд░реАрдд рд╣реЛрдЧреА рдЬрд╣рд╛рдВ рд╕реЗ рд╣рдо рдЖрдЧреЗ рдмрдврд╝ рд░рд╣реЗ рд╣реИрдВред
public GameTile GrowPathNorth () => GrowPathTo(north, Direction.South); public GameTile GrowPathEast () => GrowPathTo(east, Direction.West); public GameTile GrowPathSouth () => GrowPathTo(south, Direction.North); public GameTile GrowPathWest () => GrowPathTo(west, Direction.East); GameTile GrowPathTo (GameTile neighbor, Direction direction) { тАж neighbor.PathDirection = direction; return neighbor.Content.Type != GameTileContentType.Wall ? neighbor : null; }
рд╣рдореЗрдВ рджрд┐рд╢рд╛рдУрдВ рдХреЛ quaternions рдХреЗ рд░реВрдк рдореЗрдВ рд╡реНрдпрдХреНрдд рдХрд┐рдП рдЧрдП рдореЛрдбрд╝ рдореЗрдВ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрд╣ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛрдЧрд╛ рдпрджрд┐ рд╣рдо рджрд┐рд╢рд╛ рдХреЗ рд▓рд┐рдП рдмрд╕
GetRotation
рдХреЛ рдХреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рддреЛ рдЪрд▓реЛ рдПрдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╡рд┐рдзрд┐ рдмрдирд╛рдХрд░ рдРрд╕рд╛ рдХрд░рддреЗ рд╣реИрдВред рд╕рд╛рдорд╛рдиреНрдп рд╕реНрдереИрддрд┐рдХ рд╡рд┐рдзрд┐
DirectionExtensions
рдЬреЛрдбрд╝реЗрдВ, рдпрд╣ рдЖрд╡рд╢реНрдпрдХ quaternions рдХреИрд╢рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд░рдгреА рджреЗ, рд╕рд╛рде рд╣реА рд╕рдВрдмрдВрдзрд┐рдд рджрд┐рд╢рд╛ рдорд╛рди рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
GetRotation
рд╡рд┐рдзрд┐ред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдпрд╣ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреНрд▓рд╛рд╕ рдХреЛ рдЙрд╕реА рдкреНрд░рдХрд╛рд░ рдХреА рдлрд╛рдЗрд▓ рдореЗрдВ рдбрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИред
using UnityEngine; public enum Direction { North, East, South, West } public static class DirectionExtensions { static Quaternion[] rotations = { Quaternion.identity, Quaternion.Euler(0f, 90f, 0f), Quaternion.Euler(0f, 180f, 0f), Quaternion.Euler(0f, 270f, 0f) }; public static Quaternion GetRotation (this Direction direction) { return rotations[(int)direction]; } }
рд╡рд┐рд╕реНрддрд╛рд░ рд╡рд┐рдзрд┐ рдХреНрдпрд╛ рд╣реИ?рдПрдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╡рд┐рдзрд┐ рдПрдХ рд╕реНрдерд┐рд░ рд╡рд░реНрдЧ рдХреЗ рдЕрдВрджрд░ рдПрдХ рд╕реНрдерд┐рд░ рд╡рд┐рдзрд┐ рд╣реИ рдЬреЛ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреА рдЖрд╡реГрддреНрддрд┐ рд╡рд┐рдзрд┐ рдХреА рддрд░рд╣ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рддреА рд╣реИред рдпрд╣ рдкреНрд░рдХрд╛рд░ рдПрдХ рд╡рд░реНрдЧ, рдЗрдВрдЯрд░рдлрд╝реЗрд╕, рд╕рдВрд░рдЪрдирд╛, рдЖрджрд┐рдо рдореВрд▓реНрдп рдпрд╛ рдЧрдгрдирд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдореЗрдердб рдХреЗ рд▓рд┐рдП рдкрд╣рд▓рд╛ рддрд░реНрдХ this
рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рдЙрд╕ рдкреНрд░рдХрд╛рд░ рдФрд░ рдЙрджрд╛рд╣рд░рдг рдХреЗ рдореВрд▓реНрдп рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рд╡рд┐рдзрд┐ рдХрд╛рдо рдХрд░реЗрдЧреАред рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рд╡рд┐рд╕реНрддрд╛рд░ рдЧреБрдг рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИрдВред
рдХреНрдпрд╛ рдпрд╣ рдЖрдкрдХреЛ рдХрд┐рд╕реА рднреА рддрд░реАрдХреЗ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ? рд╣рд╛рдВ, рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдХрд┐рд╕реА рднреА рд╕реНрдерд┐рд░ рд╡рд┐рдзрд┐ рдХреЛ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдХрд╛ рдкреИрд░рд╛рдореАрдЯрд░ рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╣реИред
рдЕрдм рд╣рдо
Enemy
рдХреЛ рдШреБрдорд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЬрдм рднреА рд╣рдо рд╣рд░ рдмрд╛рд░ рдПрдХ рдирдИ рдЯрд╛рдЗрд▓ рдбрд╛рд▓рддреЗ рд╣реИрдВред рдбреЗрдЯрд╛ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж,
From
рдЯрд╛рдЗрд▓ рд╣рдореЗрдВ рджрд┐рд╢рд╛ рджреЗрддрд╛ рд╣реИред
public bool GameUpdate () { progress += Time.deltaTime; while (progress >= 1f) { тАж transform.localRotation = tileFrom.PathDirection.GetRotation(); progress -= 1f; } transform.localPosition = Vector3.LerpUnclamped(positionFrom, positionTo, progress); return true; } public void SpawnOn (GameTile tile) { тАж transform.localRotation = tileFrom.PathDirection.GetRotation(); progress = 0f; }
рджрд┐рд╢рд╛ рдХрд╛ рдкрд░рд┐рд╡рд░реНрддрди
рддреБрд░рдиреНрдд рдмрджрд▓рддреА рджрд┐рд╢рд╛ рдХреЗ рдмрдЬрд╛рдп, рд╣рдо рдкрджреЛрдВ рдХреЗ рдмреАрдЪ рдХреИрд╕реЗ рдкреНрд░рдХреНрд╖реЗрдкрд┐рдд рд╣реЛрддреЗ рд╣реИрдВ, рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, рдореВрд▓реНрдпреЛрдВ рдХреЗ рдмреАрдЪ рдЕрдВрддрд░ рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реЛрддрд╛ рд╣реИред рдПрдХ рдЕрднрд┐рд╡рд┐рдиреНрдпрд╛рд╕ рд╕реЗ рджреВрд╕рд░реЗ рдореЗрдВ рдЬрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЙрд╕ рджрд┐рд╢рд╛ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рдЬрд╛рдирдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдХрд┐рдП рдЬрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ: рдмрд┐рдирд╛ рдореБрдбрд╝реЗрдВ, рджрд╛рдПрдВ рдореБрдбрд╝реЗрдВ, рдмрд╛рдПрдВ рдореБрдбрд╝реЗрдВ рдпрд╛ рдкреАрдЫреЗ рдореБрдбрд╝реЗрдВред рд╣рдо рдЗрд╕реЗ рдПрдХ рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рдЬрд┐рд╕реЗ рдлрд┐рд░ рд╕реЗ рдЙрд╕реА рдлрд╛рдЗрд▓ рдореЗрдВ
Direction
рд░реВрдк рдореЗрдВ рд░рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рдЫреЛрдЯреЗ рдФрд░ рдирд┐рдХрдЯ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИрдВред
public enum Direction { North, East, South, West } public enum DirectionChange { None, TurnRight, TurnLeft, TurnAround }
рдПрдХ рдФрд░ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝реЗрдВ, рдЗрд╕ рдмрд╛рд░
GetDirectionChangeTo
, рдЬреЛ рд╡рд░реНрддрдорд╛рди рджрд┐рд╢рд╛ рд╕реЗ рдЕрдЧрд▓реА рджрд┐рд╢рд╛ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рд▓реМрдЯрд╛рддрд╛ рд╣реИред рдпрджрд┐ рджрд┐рд╢рд╛рдПрдВ рдореЗрд▓ рдЦрд╛рддреА рд╣реИрдВ, рддреЛ рдХреЛрдИ рдмрджрд▓рд╛рд╡ рдирд╣реАрдВ рд╣реИред рдпрджрд┐ рдЕрдЧрд▓рд╛ рдПрдХ рд╡рд░реНрддрдорд╛рди рд╕реЗ рдЕрдзрд┐рдХ рд╣реИ, рддреЛ рдпрд╣ рджрд╛рдИрдВ рдУрд░ рдПрдХ рдореЛрдбрд╝ рд╣реИред рд▓реЗрдХрд┐рди рдЪреВрдВрдХрд┐ рджрд┐рд╢рд╛рдУрдВ рдХреЛ рджреЛрд╣рд░рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд╡рд╣реА рд╕реНрдерд┐рддрд┐ рддрдм рд╣реЛрдЧреА рдЬрдм рдЕрдЧрд▓рд╛ рд╡рд░реНрддрдорд╛рди рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рддреАрди рдХрдо рд╣реЛред рдПрдХ рдмрд╛рдПрдВ рдореЛрдбрд╝ рдХреЗ рд╕рд╛рде рдпрд╣ рд╕рдорд╛рди рд╣реЛрдЧрд╛, рдХреЗрд╡рд▓ рдЬреЛрдбрд╝ рдФрд░ рдШрдЯрд╛рд╡ рд╕реНрдерд╛рдиреЛрдВ рдХреЛ рд╕реНрд╡рд┐рдЪ рдХрд░реЗрдЧрд╛ред
рдХреЗрд╡рд▓ рд╢реЗрд╖ рдорд╛рдорд▓рд╛ рдПрдХ рдореЛрдбрд╝ рд╡рд╛рдкрд╕ рд╣реИред public static DirectionChange GetDirectionChangeTo ( this Direction current, Direction next ) { if (current == next) { return DirectionChange.None; } else if (current + 1 == next || current - 3 == next) { return DirectionChange.TurnRight; } else if (current - 1 == next || current + 3 == next) { return DirectionChange.TurnLeft; } return DirectionChange.TurnAround; }
рд╣рдо рдХреЗрд╡рд▓ рдПрдХ рд╣реА рдЖрдпрд╛рдо рдореЗрдВ рдПрдХ рдШреБрдорд╛рд╡ рдмрдирд╛рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдХреЛрдгреЛрдВ рдХрд╛ рд░реИрдЦрд┐рдХ рдкреНрд░рдХреНрд╖реЗрдк рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрдЧрд╛ред рдПрдХ рдФрд░ рд╡рд┐рд╕реНрддрд╛рд░ рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝реЗрдВ рдЬреЛ рдбрд┐рдЧреНрд░реА рдореЗрдВ рджрд┐рд╢рд╛ рдХрд╛ рдХреЛрдг рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред public static float GetAngle (this Direction direction) { return (float)direction * 90f; }
рдЕрдм рдЖрдкрдХреЛ Enemy
рджрд┐рд╢рд╛, рджрд┐рд╢рд╛ рдФрд░ рдХреЛрдгреЛрдВ рдХреЛ рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛, рдЬрд┐рд╕рдХреЗ рдмреАрдЪ рдореЗрдВ рдЖрдкрдХреЛ рдкреНрд░рдХреНрд╖реЗрдк рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред Direction direction; DirectionChange directionChange; float directionAngleFrom, directionAngleTo;
SpawnOn
рдХрдард┐рди рд╣реЛ рд░рд╣рд╛ рд╣реИ, рддреЛ рдЪрд▓рд┐рдП рд░рд╛рдЬреНрдп рддреИрдпрд╛рд░реА рдХреЛрдб рдХреЛ рджреВрд╕рд░реА рд╡рд┐рдзрд┐ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рд╣рдо рджреБрд╢реНрдорди рдХреЗ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд░рд╛рдЬреНрдп рдХреЛ рдПрдХ рдкрд░рд┐рдЪрдпрд╛рддреНрдордХ рд░рд╛рдЬреНрдп рдХреЗ рд░реВрдк рдореЗрдВ рдирд╛рдорд┐рдд рдХрд░реЗрдВрдЧреЗ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЗрд╕реЗ рдХреЙрд▓ рдХрд░реЗрдВрдЧреЗ PrepareIntro
ред рдЗрд╕ рдЕрд╡рд╕реНрдерд╛ рдореЗрдВ, рджреБрд╢реНрдорди рдХреЗрдВрджреНрд░ рд╕реЗ рдЕрдкрдиреА рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЯрд╛рдЗрд▓ рдХреЗ рдХрд┐рдирд╛рд░реЗ рдкрд░ рдЪрд▓рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рджрд┐рд╢рд╛ рдХрд╛ рдХреЛрдИ рдкрд░рд┐рд╡рд░реНрддрди рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рдХреЛрдг From
рдФрд░ To
рдПрдХ рд╣реАред public void SpawnOn (GameTile tile) { Debug.Assert(tile.NextTileOnPath != null, "Nowhere to go!", this); tileFrom = tile; tileTo = tile.NextTileOnPath;
рдЗрд╕ рд╕реНрддрд░ рдкрд░, рд╣рдо рдПрдХ рдЫреЛрдЯреЗ рд░рд╛рдЬреНрдп рдорд╢реАрди рдХреА рддрд░рд╣ рдХреБрдЫ рдмрдирд╛рддреЗ рд╣реИрдВред рдЪреАрдЬреЛрдВ рдХреЛ рд╕рд░рд▓ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП GameUpdate
, рд╕реНрдерд┐рддрд┐ рдХреЛрдб рдХреЛ рдПрдХ рдирдИ рд╡рд┐рдзрд┐ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░реЗрдВ PrepareNextState
ред рд╣рдо рдХреЗрд╡рд▓ рдЯрд╛рдЗрд▓реЛрдВ рдХреЗ рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рдЫреЛрдбрд╝ рджреЗрдВрдЧреЗ From
рдФрд░ To
, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдпрд╣рд╛рдВ рдпрд╣ рдЬрд╛рдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рджреБрд╢реНрдорди рдиреЗ рд░рд╛рд╕реНрддрд╛ рдЦрддреНрдо рдХрд░ рджрд┐рдпрд╛ рд╣реИред public bool GameUpdate () { progress += Time.deltaTime; while (progress >= 1f) { тАж
рдПрдХ рдирдП рд░рд╛рдЬреНрдп рдореЗрдВ рд╕рдВрдХреНрд░рдордг рдХрд░рддреЗ рд╕рдордп, рдЖрдкрдХреЛ рд╣рдореЗрд╢рд╛ рдкрджреЛрдВ рдХреЛ рдмрджрд▓рдиреЗ, рджрд┐рд╢рд╛ рдмрджрд▓рдиреЗ, рд╡рд░реНрддрдорд╛рди рджрд┐рд╢рд╛ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдФрд░ рдХреЛрдг To
рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ From
ред рд╣рдордиреЗ рдЕрдм рдХреЛрдИ рдЯрд░реНрди рдирд╣реАрдВ рд▓рд┐рдпрд╛ рд╣реИред void PrepareNextState () { positionFrom = positionTo; positionTo = tileFrom.ExitPoint; directionChange = direction.GetDirectionChangeTo(tileFrom.PathDirection); direction = tileFrom.PathDirection; directionAngleFrom = directionAngleTo; }
рдЕрдиреНрдп рдХреНрд░рд┐рдпрд╛рдПрдВ рджрд┐рд╢рд╛ рдмрджрд▓рдиреЗ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреА рд╣реИрдВред рдЖрдЗрдП рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдХрд▓реНрдк рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝реЗрдВред рдпрджрд┐ рд╣рдо рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВ, рддреЛ рдХреЛрдг To
рд╡рд░реНрддрдорд╛рди рд╕реЗрд▓ рдХреЗ рдорд╛рд░реНрдЧ рдХреА рджрд┐рд╢рд╛ рдХреЗ рд╕рд╛рде рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдореЗрдВ рд░реЛрдЯреЗрд╢рди рд╕реЗрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рддрд╛рдХрд┐ рджреБрд╢реНрдорди рд╕реАрдзреЗ рдЖрдЧреЗ рджреЗрдЦ рд░рд╣рд╛ рд╣реЛред void PrepareForward () { transform.localRotation = direction.GetRotation(); directionAngleTo = direction.GetAngle(); }
рдПрдХ рдореЛрдбрд╝ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо рддреБрд░рдВрдд рдирд╣реАрдВ рдореБрдбрд╝рддреЗ рд╣реИрдВред рд╣рдореЗрдВ рдПрдХ рдЕрд▓рдЧ рдХреЛрдг рдкрд░ рдкреНрд░рдХреНрд╖реЗрдкрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ: рджрд╛рдПрдВ рдореБрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП 90 ┬░ рдЕрдзрд┐рдХ, рдмрд╛рдПрдВ рдореБрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП 90 ┬░ рдХрдо, рдФрд░ рд╡рд╛рдкрд╕ рдореБрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП 180 ┬░ рдЕрдзрд┐рдХред 359 ┬░ рд╕реЗ 0 ┬░ рдХреЗ рдХреЛрдг рдореВрд▓реНрдпреЛрдВ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдХрд╛рд░рдг рдЧрд▓рдд рджрд┐рд╢рд╛ рдореЗрдВ рдореЛрдбрд╝ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП, рдХреЛрдг To
рдХреЛ рд╡рд░реНрддрдорд╛рди рджрд┐рд╢рд╛ рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рд╕рдВрдХреЗрдд рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рд╣рдореЗрдВ рдпрд╣ рдЪрд┐рдВрддрд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХреЛрдг 0 ┬░ рд╕реЗ рдХрдо рдпрд╛ 360 ┬░ рд╕реЗ рдЕрдзрд┐рдХ рд╣реЛ рдЬрд╛рдПрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо Quaternion.Euler
рдЗрд╕реЗ рд╕рдВрднрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВред void PrepareTurnRight () { directionAngleTo = directionAngleFrom + 90f; } void PrepareTurnLeft () { directionAngleTo = directionAngleFrom - 90f; } void PrepareTurnAround () { directionAngleTo = directionAngleFrom + 180f; }
рдЕрдВрдд рдореЗрдВ, PrepareNextState
рд╣рдо рдпрд╣ switch
рддрдп рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдХрд┐рди рдЪрд╛рд░ рддрд░реАрдХреЛрдВ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рджрд┐рд╢рд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ ред void PrepareNextState () { тАж switch (directionChange) { case DirectionChange.None: PrepareForward(); break; case DirectionChange.TurnRight: PrepareTurnRight(); break; case DirectionChange.TurnLeft: PrepareTurnLeft(); break; default: PrepareTurnAround(); break; } }
рдЕрдм рдЕрдВрдд рдореЗрдВ GameUpdate
рд╣рдореЗрдВ рдпрд╣ рдЬрд╛рдВрдЪрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рджрд┐рд╢рд╛ рдмрджрд▓ рдЧрдИ рд╣реИред рдпрджрд┐ рдРрд╕рд╛ рд╣реИ, рддреЛ рджреЛ рдХреЛрдиреЛрдВ рдХреЗ рдмреАрдЪ рдЗрдВрдЯрд░рдкреЛрд▓реЗрдЯ рдХрд░реЗрдВ рдФрд░ рдШреБрдорд╛рд╡ рд╕реЗрдЯ рдХрд░реЗрдВред public bool GameUpdate () { тАж transform.localPosition = Vector3.LerpUnclamped(positionFrom, positionTo, progress); if (directionChange != DirectionChange.None) { float angle = Mathf.LerpUnclamped( directionAngleFrom, directionAngleTo, progress ); transform.localRotation = Quaternion.Euler(0f, angle, 0f); } return true; }
рджреБрд╢реНрдорди рдкрд▓рдЯ рд░рд╣реЗ рд╣реИрдВредрд╡рдХреНрд░ рдЖрдВрджреЛрд▓рди
рд╣рдо рджреБрд╢реНрдордиреЛрдВ рдХреЛ рдореЛрдбрд╝рддреЗ рд╕рдордп рдПрдХ рдШреБрдорд╛рд╡ рдХреЗ рд╕рд╛рде рдЧрддрд┐ рдХреЛ рдмреЗрд╣рддрд░ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рдЯрд╛рдЗрд▓ рдХреЗ рдХрд┐рдирд╛рд░реЗ рд╕реЗ рдХрд┐рдирд╛рд░реЗ рддрдХ рдЪрд▓рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдЙрдиреНрд╣реЗрдВ рдПрдХ рд╕рд░реНрдХрд▓ рдХреЗ рдПрдХ рдЪреМрдерд╛рдИ рдЪрд▓рдиреЗ рджреЗрдВред рдЯрд╛рдЗрд▓реНрд╕ рдХреЗ рдХреЛрдиреЗ рдЖрдо рдореЗрдВ рдЗрд╕ рдордВрдбрд▓реА рдЭреВрда рдХрд╛ рдХреЗрдВрджреНрд░ From
рдФрд░ To
рдЬрд┐рд╕ рдкрд░ рджреБрд╢реНрдорди рдЯрд╛рдЗрд▓ рдкрд░ рджрд░реНрдЬ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдПрдХ рд╣реА рдХрд┐рдирд╛рд░реЗ рдкрд░, From
редрджрд╛рдИрдВ рдУрд░ рдореБрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЪреМрдерд╛рдИ рд╡реГрддреНрдд рд░реЛрдЯреЗрд╢рдиредрд╣рдо рдЗрд╕реЗ рддреНрд░рд┐рдХреЛрдгрдорд┐рддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдЪрд╛рдк рдореЗрдВ рджреБрд╢реНрдорди рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдХреЗ рдорд╣рд╕реВрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрдмрдХрд┐ рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдЗрд╕реЗ рдореЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдпрд╣ рдХреЗрд╡рд▓ рд░реЛрдЯреЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рд░рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЕрд╕реНрдерд╛рдпреА рд░реВрдк рд╕реЗ рджреБрд╢реНрдорди рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреЗ рд╕реНрдерд╛рдиреАрдп рдореВрд▓ рдХреЛ рд╕рд░реНрдХрд▓ рдХреЗ рдХреЗрдВрджреНрд░ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рджреБрд╢реНрдорди рдореЙрдбрд▓ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо Enemy
рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝реАрд▓реНрдб рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реБрд▓рдн рдЗрд╕ рдореЙрдбрд▓ рдХреЛ рдПрдХ рд▓рд┐рдВрдХ рджреЗрдВрдЧреЗ ред [SerializeField] Transform model = default;
рдореЙрдбрд▓ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рджреБрд╢реНрдордиредрдЖрдЧреЗ рдмрдврд╝рдиреЗ рдпрд╛ рдкреАрдЫреЗ рдореБрдбрд╝рдиреЗ рдХреА рддреИрдпрд╛рд░реА рдореЗрдВ, рдореЙрдбрд▓ рдХреЛ рджреБрд╢реНрдорди рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреЗ рд╕реНрдерд╛рдиреАрдп рдореВрд▓ рддрдХ рдорд╛рдирдХ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЕрдиреНрдпрдерд╛, рдореЙрдбрд▓ рдХреЛ рдорд╛рдк рдХреА рдЖрдзрд╛ рдЗрдХрд╛рдИ рджреНрд╡рд╛рд░рд╛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП - рдШреБрдорд╛рд╡ рдХреЗ рдЪрдХреНрд░ рдХреА рддреНрд░рд┐рдЬреНрдпрд╛, рдореЛрдбрд╝ рд╕реЗ рджреВрд░ред void PrepareForward () { transform.localRotation = direction.GetRotation(); directionAngleTo = direction.GetAngle(); model.localPosition = Vector3.zero; } void PrepareTurnRight () { directionAngleTo = directionAngleFrom + 90f; model.localPosition = new Vector3(-0.5f, 0f); } void PrepareTurnLeft () { directionAngleTo = directionAngleFrom - 90f; model.localPosition = new Vector3(0.5f, 0f); } void PrepareTurnAround () { directionAngleTo = directionAngleFrom + 180f; model.localPosition = Vector3.zero; }
рдЕрдм рджреБрд╢реНрдорди рдХреЛ рдЦреБрдж рдХреЛ рдирд┐рд░реНрдгрд╛рдпрдХ рдореЛрдбрд╝ рдкрд░ рд▓реЗ рдЬрд╛рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрд╕реЗ рдорд╛рдк рдХреА рдЖрдзреА рдЗрдХрд╛рдИ рдХреЛ рднреА рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рд╕рдЯреАрдХ рдСрдлрд╕реЗрдЯ рджрд┐рд╢рд╛ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред рдЖрдЗрдП рдЗрд╕рдореЗрдВ Direction
рдПрдХ рд╕рд╣рд╛рдпрдХ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝реЗрдВ GetHalfVector
ред static Vector3[] halfVectors = { Vector3.forward * 0.5f, Vector3.right * 0.5f, Vector3.back * 0.5f, Vector3.left * 0.5f }; тАж public static Vector3 GetHalfVector (this Direction direction) { return halfVectors[(int)direction]; }
рджрд╛рдПрдВ рдпрд╛ рдмрд╛рдПрдВ рдореБрдбрд╝рддреЗ рд╕рдордп рд╕рдВрдмрдВрдзрд┐рдд рд╡реЗрдХреНрдЯрд░ рдЬреЛрдбрд╝реЗрдВред void PrepareTurnRight () { directionAngleTo = directionAngleFrom + 90f; model.localPosition = new Vector3(-0.5f, 0f); transform.localPosition = positionFrom + direction.GetHalfVector(); } void PrepareTurnLeft () { directionAngleTo = directionAngleFrom - 90f; model.localPosition = new Vector3(0.5f, 0f); transform.localPosition = positionFrom + direction.GetHalfVector(); }
рдФрд░ рдЬрдм рдкреАрдЫреЗ рдореБрдбрд╝рддреЗ рд╣реИрдВ, рддреЛ рд╕реНрдерд┐рддрд┐ рд╕рд╛рдорд╛рдиреНрдп рд╢реБрд░реБрдЖрддреА рдмрд┐рдВрджреБ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред void PrepareTurnAround () { directionAngleTo = directionAngleFrom + 180f; model.localPosition = Vector3.zero; transform.localPosition = positionFrom; }
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдирд┐рдХрд╛рд╕ рдмрд┐рдВрджреБ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╕рдордп, рд╣рдо GameTile.GrowPathTo
рдЖрдзреЗ рд╡реЗрдХреНрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рддрд╛рдХрд┐ рд╣рдореЗрдВ рдЯрд╛рдЗрд▓реНрд╕ рдХреЗ рджреЛ рдкрджреЛрдВ рддрдХ рдкрд╣реБрдВрдЪ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рди рд╣реЛред neighbor.ExitPoint = neighbor.transform.localPosition + direction.GetHalfVector();
рдЕрдм, рдЬрдм рджрд┐рд╢рд╛рдПрдВ рдмрджрд▓ рд░рд╣реА рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рд╕реНрдерд┐рддрд┐ рдХреЛ рдмреАрдЪ рдореЗрдВ рд▓рд╛рдиреЗ рдХреА рдЬрд╝рд░реВрд░рдд рдирд╣реАрдВ рд╣реИ Enemy.GameUpdate
, рдХреНрдпреЛрдВрдХрд┐ рдШреБрдорд╛рд╡ рдЖрдВрджреЛрд▓рди рдореЗрдВ рд▓рдЧрд╛ рд╣реБрдЖ рд╣реИред public bool GameUpdate () { тАж if (directionChange == DirectionChange.None) { transform.localPosition = Vector3.LerpUnclamped(positionFrom, positionTo, progress); }
рджреБрд╢реНрдорди рдЖрд╕рд╛рдиреА рд╕реЗ рдХреЛрдиреЛрдВ рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдЭреБрдХрддреЗ рд╣реИрдВредрд▓рдЧрд╛рддрд╛рд░ рдЧрддрд┐
рдЗрд╕ рдмрд┐рдВрджреБ рддрдХ, рджреБрд╢реНрдордиреЛрдВ рдХреА рдЧрддрд┐ рд╣рдореЗрд╢рд╛ рдПрдХ рдЯрд╛рдЗрд▓ рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб рдХреЗ рдмрд░рд╛рдмрд░ рд░рд╣реА рд╣реИ, рднрд▓реЗ рд╣реА рд╡реЗ рдЯрд╛рдЗрд▓ рдХреЗ рдЕрдВрджрд░ рдХреИрд╕реЗ рдЖрдЧреЗ рдмрдврд╝реЗрдВред рд▓реЗрдХрд┐рди рдЙрдирдХреЗ рджреНрд╡рд╛рд░рд╛ рддрдп рдХреА рдЧрдИ рджреВрд░реА рдЙрдирдХреА рд╕реНрдерд┐рддрд┐ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб рдЗрдХрд╛рдЗрдпреЛрдВ рдореЗрдВ рд╡реНрдпрдХреНрдд рдХреА рдЧрдИ рдЙрдирдХреА рдЧрддрд┐ рднрд┐рдиреНрди рд╣реЛрддреА рд╣реИред рдЗрд╕ рдЧрддрд┐ рдХреЛ рд╕реНрдерд┐рд░ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рд░рд╛рдЬреНрдп рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдкреНрд░рдЧрддрд┐ рдХреА рдЧрддрд┐ рдХреЛ рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛ред рдЗрд╕рд▓рд┐рдП, рдкреНрд░рдЧрддрд┐ рдЧреБрдгрдХ рдлрд╝реАрд▓реНрдб рдХреЛ рдЬреЛрдбрд╝реЗрдВ рдФрд░ рдбреЗрд▓реНрдЯрд╛ рдХреЛ рд╕реНрдХреЗрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ GameUpdate
ред float progress, progressFactor; тАж public bool GameUpdate () { progress += Time.deltaTime * progressFactor; тАж }
рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдкреНрд░рдЧрддрд┐ рд░рд╛рдЬреНрдп рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдмрджрд▓ рдЬрд╛рддреА рд╣реИ, рддреЛ рд╢реЗрд╖ рдкреНрд░рдЧрддрд┐ рдореВрд▓реНрдп рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕реАрдзреЗ рдЕрдЧрд▓реЗ рд░рд╛рдЬреНрдп рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдирдП рд░рд╛рдЬреНрдп рдХреА рддреИрдпрд╛рд░реА рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ рдкреНрд░рдЧрддрд┐ рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рдХрд░рдиреЗ рдФрд░ рдирдП рд░рд╛рдЬреНрдп рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдирдП рдЧреБрдгрдХ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред public bool GameUpdate () { progress += Time.deltaTime * progressFactor; while (progress >= 1f) { тАж
рдЖрдЧреЗ рдмрдврд╝рдиреЗ рдкрд░ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП, рдпрд╣ 1 рдХреЗ рдХрд╛рд░рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рджрд╛рдПрдВ рдпрд╛ рдмрд╛рдПрдВ рдореБрдбрд╝рддреЗ рд╕рдордп, рджреБрд╢реНрдорди rad рдХреЗ рддреНрд░рд┐рдЬреНрдпрд╛ рдХреЗ рд╕рд╛рде рдПрдХ рд╕рд░реНрдХрд▓ рдХреЗ рдПрдХ рдЪреМрдерд╛рдИ рд╕реЗ рдЧреБрдЬрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдХрд╡рд░ рдХреА рдЧрдИ рджреВрд░реА ┬╝╧А рд╣реИред progress
рдЗрд╕ рдорд╛рди рд╕реЗ рд╡рд┐рднрд╛рдЬрд┐рдд рдПрдХ рдХреЗ рдмрд░рд╛рдмрд░ред рдкреАрдЫреЗ рдореБрдбрд╝рдиреЗ рдореЗрдВ рдЕрдзрд┐рдХ рд╕рдордп рдирд╣реАрдВ рд▓реЗрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЗрд╕рд▓рд┐рдП рдкреНрд░рдЧрддрд┐ рдХреЛ рджреЛрдЧреБрдирд╛ рдХрд░реЗрдВ рддрд╛рдХрд┐ рдЗрд╕реЗ рдЖрдзрд╛ рд╕реЗрдХрдВрдб рд▓рдЧ рдЬрд╛рдПред рдЕрдВрдд рдореЗрдВ, рдкрд░рд┐рдЪрдпрд╛рддреНрдордХ рдЖрдВрджреЛрд▓рди рдЯрд╛рдЗрд▓ рдХреЗ рдХреЗрд╡рд▓ рдЖрдзреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЛ рдХрд╡рд░ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП, рдирд┐рд░рдВрддрд░ рдЧрддрд┐ рдмрдирд╛рдП рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрд╕рдХреА рдкреНрд░рдЧрддрд┐ рдХреЛ рднреА рджреЛрдЧреБрдирд╛ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред void PrepareForward () { тАж progressFactor = 1f; } void PrepareTurnRight () { тАж progressFactor = 1f / (Mathf.PI * 0.25f); } void PrepareTurnLeft () { тАж progressFactor = 1f / (Mathf.PI * 0.25f); } void PrepareTurnAround () { тАж progressFactor = 2f; } void PrepareIntro () { тАж progressFactor = 2f; }
рджреВрд░реА 1/4 * рдкрд╛рдИ рдХреЗ рдмрд░рд╛рдмрд░ рдХреНрдпреЛрдВ рд╣реИ?2╧А, . , ┬╜, ┬╜╧А ├Ч ┬╜.
рдЕрдВрддрд┐рдо рд╕реНрдерд┐рддрд┐
рдЪреВрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдкрд░рд┐рдЪрдпрд╛рддреНрдордХ рд╕реНрдерд┐рддрд┐ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдПрдХ рдЕрдВрддрд┐рдо рдЬреЛрдбрд╝ рджреЗрдВред рджреБрд╢реНрдорди рд╡рд░реНрддрдорд╛рди рдореЗрдВ рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рддреБрд░рдВрдд рдмрд╛рдж рдЧрд╛рдпрдм рд╣реЛ рд░рд╣реЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЪрд▓реЛ рдЕрдВрдд рддрдХ рдЯрд╛рдЗрд▓ рдХреЗ рдХреЗрдВрджреНрд░ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рддрдХ рдЙрдирдХреЗ рд▓рд╛рдкрддрд╛ рд╣реЛрдиреЗ рдХреЛ рд╕реНрдердЧрд┐рдд рдХрд░ рджреЗрдВред рдЖрдЗрдП рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рдзрд┐ рдмрдирд╛рдПрдВ PrepareOutro
, рдЖрдЧреЗ рдХреА рдЧрддрд┐ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВ, рд▓реЗрдХрд┐рди рдирд┐рд░рдВрддрд░ рдЧрддрд┐ рдмрдирд╛рдП рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ рджреЛрдЧреБрдиреА рдкреНрд░рдЧрддрд┐ рдХреЗ рд╕рд╛рде рдЯрд╛рдЗрд▓ рдХреЗ рдХреЗрдВрджреНрд░ рдореЗрдВред void PrepareOutro () { positionTo = tileFrom.transform.localPosition; directionChange = DirectionChange.None; directionAngleTo = direction.GetAngle(); model.localPosition = Vector3.zero; transform.localRotation = direction.GetRotation(); progressFactor = 2f; }
рдЖрджреЗрд╢ рдореЗрдВ GameUpdate
рджреБрд╢реНрдорди рднреА рдЯрд╛рдЗрд▓реНрд╕ рдкрд╛рд░реА рдХреЛ рд╣рдЯрд╛рдиреЗ рдХреЗ рджреНрд╡рд╛рд░рд╛ рдЬрд▓реНрджреА рдирд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВред рдЕрдм рд╡реЗ рд▓рдЧреЗ рд╣реБрдП рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ PrepareNextState
ред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЕрдВрддрд┐рдо рд░рд╛рдЬреНрдп рдХреА рд╕рдорд╛рдкреНрддрд┐ рдХреЗ рдмрд╛рдж рд╣реА null
рд░рд┐рдЯрд░реНрди рдХреА рдЬрд╛рдБрдЪ рдХрд░рдирд╛ true
ред public bool GameUpdate () { progress += Time.deltaTime * progressFactor; while (progress >= 1f) {
рдЬреИрд╕рд╛ рдХрд┐ PrepareNextState
рд╣рдо рдЯрд╛рдЗрд▓реНрд╕ рд╢рд┐рдлреНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рдлрд┐рд░, рд╕реНрдерд┐рддрд┐ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж From
, рд▓реЗрдХрд┐рди рд╕реНрдерд┐рддрд┐ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, To
рд╣рдо рдЬрд╛рдБрдЪреЗрдВрдЧреЗ рдХрд┐ рдХреНрдпрд╛ рдЯрд╛рдЗрд▓ To
рдореВрд▓реНрдп рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ null
ред рдпрджрд┐ рдРрд╕рд╛ рд╣реИ, рддреЛ рдЕрдВрддрд┐рдо рд╕реНрдерд┐рддрд┐ рддреИрдпрд╛рд░ рдХрд░реЗрдВ рдФрд░ рдмрд╛рдХреА рд╡рд┐рдзрд┐ рдЫреЛрдбрд╝реЗрдВред void PrepareNextState () { tileFrom = tileTo; tileTo = tileTo.NextTileOnPath; positionFrom = positionTo; if (tileTo == null) { PrepareOutro(); return; } positionTo = tileFrom.ExitPoint; тАж }
рдПрдХ рдирд┐рд░рдВрддрд░ рдЧрддрд┐ рдФрд░ рдЕрдВрддрд┐рдо рд╕реНрдерд┐рддрд┐ рдХреЗ рд╕рд╛рде рджреБрд╢реНрдордиредрд╢рддреНрд░реБ рднрд┐рдиреНрдирддрд╛
рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рджреБрд╢реНрдордиреЛрдВ рдХреА рдПрдХ рдзрд╛рд░рд╛ рд╣реИ, рдФрд░ рд╡реЗ рд╕рднреА рдПрдХ рд╣реА рдШрди рд╣реИрдВ, рдПрдХ рд╣реА рдЧрддрд┐ рд╕реЗ рдмрдврд╝ рд░рд╣реЗ рд╣реИрдВред рдкрд░рд┐рдгрд╛рдо рд╡реНрдпрдХреНрддрд┐рдЧрдд рджреБрд╢реНрдордиреЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рд▓рдВрдмреЗ рд╕рд╛рдВрдк рдХреА рддрд░рд╣ рд╣реИред рдЖрдЗрдП рдЙрдирдХреЗ рдЖрдХрд╛рд░, рд╡рд┐рд╕реНрдерд╛рдкрди рдФрд░ рдЧрддрд┐ рдХреЛ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдХрд░рдХреЗ рдЙрдиреНрд╣реЗрдВ рдФрд░ рдЕрдзрд┐рдХ рднрд┐рдиреНрди рдмрдирд╛рддреЗ рд╣реИрдВредрдлреНрд▓реЛрдЯ рд╡реИрд▓реНрдпреВ рд░реЗрдВрдЬ
рд╣рдо рджреБрд╢реНрдордиреЛрдВ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдмрджрд▓ рджреЗрдВрдЧреЗ, рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд░реВрдк рд╕реЗ рдореВрд▓реНрдпреЛрдВ рдХреА рд╕реАрдорд╛ рд╕реЗ рдЕрдкрдиреА рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХрд╛ рдЪрдпрди рдХрд░реЗрдВрдЧреЗред рдСрдмреНрдЬреЗрдХреНрдЯ рдореИрдиреЗрдЬрдореЗрдВрдЯ, рдХреЙрдиреНрдлрд┐рдЧрд░рд┐рдВрдЧ рд╢реЗрдкреНрд╕FloatRange
рдЖрд░реНрдЯрд┐рдХрд▓ рдореЗрдВ рд╣рдордиреЗ рдЬреЛ рд╕реНрдЯреНрд░рдХреНрдЪрд░ рдмрдирд╛рдпрд╛ рд╣реИ, рд╡рд╣ рдпрд╣рд╛рдВ рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ , рддреЛ рдЖрдЗрдП рдЗрд╕реЗ рдХреЙрдкреА рдХрд░рддреЗ рд╣реИрдВред рдХреЗрд╡рд▓ рдкрд░рд┐рд╡рд░реНрддрди рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝ рд░рд╣реЗ рдереЗ рдФрд░ рд░реАрдбреЛрдирд▓реА-рдЧреБрдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдиреНрдпреВрдирддрдо рдФрд░ рдЕрдзрд┐рдХрддрдо рддрдХ рдкрд╣реБрдВрдЪ рдЦреЛрд▓ рд░рд╣реЗ рдереЗ, рддрд╛рдХрд┐ рдЕрдВрддрд░рд╛рд▓ рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рдерд╛ред using UnityEngine; [System.Serializable] public struct FloatRange { [SerializeField] float min, max; public float Min => min; public float Max => max; public float RandomValueInRange { get { return Random.Range(min, max); } } public FloatRange(float value) { min = max = value; } public FloatRange (float min, float max) { this.min = min; this.max = max < min ? min : max; } }
рд╣рдо рдЗрд╕рдХреЗ рдЕрдВрддрд░рд╛рд▓ рдХреЛ рд╕реАрдорд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕рдореЗрдВ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рднреА рдХреЙрдкреА рдХрд░рддреЗ рд╣реИрдВред using UnityEngine; public class FloatRangeSliderAttribute : PropertyAttribute { public float Min { get; private set; } public float Max { get; private set; } public FloatRangeSliderAttribute (float min, float max) { Min = min; Max = max < min ? min : max; } }
рд╣рдореЗрдВ рдХреЗрд╡рд▓ рд╕реНрд▓рд╛рдЗрдбрд░ рдХреЗ рджреГрд╢реНрдп рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ рд╕рдВрдкрд╛рджрдХFloatRangeSliderDrawer
рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдХреЙрдкреА рдХрд░реЗрдВ ред using UnityEditor; using UnityEngine; [CustomPropertyDrawer(typeof(FloatRangeSliderAttribute))] public class FloatRangeSliderDrawer : PropertyDrawer { public override void OnGUI ( Rect position, SerializedProperty property, GUIContent label ) { int originalIndentLevel = EditorGUI.indentLevel; EditorGUI.BeginProperty(position, label, property); position = EditorGUI.PrefixLabel( position, GUIUtility.GetControlID(FocusType.Passive), label ); EditorGUI.indentLevel = 0; SerializedProperty minProperty = property.FindPropertyRelative("min"); SerializedProperty maxProperty = property.FindPropertyRelative("max"); float minValue = minProperty.floatValue; float maxValue = maxProperty.floatValue; float fieldWidth = position.width / 4f - 4f; float sliderWidth = position.width / 2f; position.width = fieldWidth; minValue = EditorGUI.FloatField(position, minValue); position.x += fieldWidth + 4f; position.width = sliderWidth; FloatRangeSliderAttribute limit = attribute as FloatRangeSliderAttribute; EditorGUI.MinMaxSlider( position, ref minValue, ref maxValue, limit.Min, limit.Max ); position.x += sliderWidth + 4f; position.width = fieldWidth; maxValue = EditorGUI.FloatField(position, maxValue); if (minValue < limit.Min) { minValue = limit.Min; } if (maxValue < minValue) { maxValue = minValue; } else if (maxValue > limit.Max) { maxValue = limit.Max; } minProperty.floatValue = minValue; maxProperty.floatValue = maxValue; EditorGUI.EndProperty(); EditorGUI.indentLevel = originalIndentLevel; } }
рдореЙрдбрд▓ рдХрд╛ рдкреИрдорд╛рдирд╛
рд╣рдо рджреБрд╢реНрдорди рдХреЗ рдкреИрдорд╛рдиреЗ рдХреЛ рдмрджрд▓рдХрд░ рд╢реБрд░реВ рдХрд░реЗрдВрдЧреЗред EnemyFactory
рд╡рд┐рдХрд▓реНрдк рдореЗрдВ рд╕реНрдХреЗрд▓ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдЬреЛрдбрд╝реЗрдВ ред рдкреИрдорд╛рдиреЗ рдХрд╛ рдЕрдВрддрд░рд╛рд▓ рдмрд╣реБрдд рдмрдбрд╝рд╛ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди рджреБрд╢реНрдордиреЛрдВ рдХреА рд▓рдШреБ рдФрд░ рд╡рд┐рд╢рд╛рд▓ рдХрд┐рд╕реНрдореЛрдВ рдХреЛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред рдорд╛рдирдХ рдорд╛рди рдХреЗ рд╕рд╛рде 0.5-2 рдХреЗ рднреАрддрд░ рдХреБрдЫ рднреАред рд╣рдо рдЗрд╕ рдЕрдВрддрд░рд╛рд▓ рдореЗрдВ рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдкреИрдорд╛рдиреЗ рдХрд╛ рдЪрдпрди рдХрд░реЗрдВрдЧреЗ Get
рдФрд░ рдЗрд╕реЗ рдПрдХ рдирдИ рд╡рд┐рдзрд┐ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рджреБрд╢реНрдорди рдХреЛ рдкрд╛рд╕ рдХрд░реЗрдВрдЧреЗ Initialize
ред [SerializeField, FloatRangeSlider(0.5f, 2f)] FloatRange scale = new FloatRange(1f); public Enemy Get () { Enemy instance = CreateGameObjectInstance(prefab); instance.OriginFactory = this; instance.Initialize(scale.RandomValueInRange); return instance; }
рд╡рд┐рдзрд┐ Enemy.Initialize
рдмрд╕ рдЕрдкрдиреЗ рдореЙрдбрд▓ рдХреЗ рдкреИрдорд╛рдиреЗ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреА рд╣реИ рдЬреЛ рд╕рднреА рдЖрдпрд╛рдореЛрдВ рдореЗрдВ рд╕рдорд╛рди рд╣реИред public void Initialize (float scale) { model.localScale = new Vector3(scale, scale, scale); }
рддрд░рд╛рдЬреВ рдХреА рд╕реАрдорд╛ 0.5 рд╕реЗ 1.5 рддрдХ рд╣реИредрдкрде рдСрдлрд╕реЗрдЯ
рджреБрд╢реНрдордиреЛрдВ рдХреЗ рдкреНрд░рд╡рд╛рд╣ рдХреА рдПрдХрд░реВрдкрддрд╛ рдХреЛ рдФрд░ рдирд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЯрд╛рдЗрд▓реНрд╕ рдХреЗ рдЕрдВрджрд░ рдЙрдирдХреА рд╕рд╛рдкреЗрдХреНрд╖ рд╕реНрдерд┐рддрд┐ рдХреЛ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред рд╡реЗ рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЗрд╕ рджрд┐рд╢рд╛ рдореЗрдВ рдмрджрд▓рд╛рд╡ рдХреЗрд╡рд▓ рдЙрдирдХреЗ рдЖрдВрджреЛрд▓рди рдХреЗ рд╕рдордп рдХреЛ рдмрджрд▓рддрд╛ рд╣реИ, рдЬреЛ рдмрд╣реБрдд рд╣реА рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рдирд╣реАрдВ рд╣реИред рдЗрд╕рд▓рд┐рдП, рд╣рдо рдЙрдиреНрд╣реЗрдВ рдЯрд╛рдЗрд▓ рдХреЗ рдХреЗрдВрджреНрд░реЛрдВ рд╕реЗ рдЧреБрдЬрд░рдиреЗ рд╡рд╛рд▓реЗ рдЖрджрд░реНрд╢ рдкрде рд╕реЗ рджреВрд░, рдХрд┐рдирд╛рд░реЗ рдкрд░ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рджреЗрдВрдЧреЗред EnemyFactory
рдЕрдВрддрд░рд╛рд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рдкрде рдСрдлрд╕реЗрдЯ рдЬреЛрдбрд╝реЗрдВ рдФрд░ рд╡рд┐рдзрд┐ рдХреЛ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдСрдлрд╕реЗрдЯ рдкрд╛рд╕ рдХрд░реЗрдВ Initialize
ред рдСрдлрд╕реЗрдЯ рдирдХрд╛рд░рд╛рддреНрдордХ рдпрд╛ рд╕рдХрд╛рд░рд╛рддреНрдордХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХрднреА рднреА or рд╕реЗ рдЕрдзрд┐рдХ рдирд╣реАрдВ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рджреБрд╢реНрдорди рдХреЛ рдкрдбрд╝реЛрд╕реА рдЯрд╛рдЗрд▓ рдкрд░ рд▓реЗ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рджреБрд╢реНрдордиреЛрдВ рдХреЛ рдЙрди рдЯрд╛рдЗрд▓реЛрдВ рд╕реЗ рдЖрдЧреЗ рдирд╣реАрдВ рдЬрд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдЬрд┐рдирдХрд╛ рд╡реЗ рдЕрдиреБрд╕рд░рдг рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрдВрддрд░рд╛рд▓ рдХрдо рд╣реЛрдЧрд╛, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, 0.4, рд▓реЗрдХрд┐рди рд╕рд╣реА рд╕реАрдорд╛ рджреБрд╢реНрдорди рдХреЗ рдЖрдХрд╛рд░ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреА рд╣реИред [SerializeField, FloatRangeSlider(-0.4f, 0.4f)] FloatRange pathOffset = new FloatRange(0f); public Enemy Get () { Enemy instance = CreateGameObjectInstance(prefab); instance.OriginFactory = this; instance.Initialize( scale.RandomValueInRange, pathOffset.RandomValueInRange ); return instance; }
рдЪреВрдВрдХрд┐ рдорд╛рд░реНрдЧ рдХрд╛ рд╡рд┐рд╕реНрдерд╛рдкрди рдпрд╛рддреНрд░рд╛ рдХреЗ рдорд╛рд░реНрдЧ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддрд╛ рд╣реИ, Enemy
рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ рдЯреНрд░реИрдХ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред float pathOffset; тАж public void Initialize (float scale, float pathOffset) { model.localScale = new Vector3(scale, scale, scale); this.pathOffset = pathOffset; }
рдЬрдм рдмрд┐рд▓реНрдХреБрд▓ рд╕реАрдзреЗ (рдкрд░рд┐рдЪрдпрд╛рддреНрдордХ, рдЕрдВрддрд┐рдо рдпрд╛ рд╕рд╛рдорд╛рдиреНрдп рдЕрдЧреНрд░рдЧрд╛рдореА рдЧрддрд┐ рдХреЗ рджреМрд░рд╛рди) рдЪрд▓рддреА рд╣реИ, рддреЛ рд╣рдо рдмрд╕ рдСрдлрд╕реЗрдЯ рдХреЛ рд╕реАрдзреЗ рдореЙрдбрд▓ рдкрд░ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВред рдЬрдм рдЖрдк рдкреАрдЫреЗ рдореБрдбрд╝рддреЗ рд╣реИрдВ рддреЛ рд╡рд╣реА рдмрд╛рдд рд╣реЛрддреА рд╣реИред рджрд╛рдПрдВ рдпрд╛ рдмрд╛рдПрдВ рдореЛрдбрд╝ рдХреЗ рд╕рд╛рде, рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдореЙрдбрд▓ рдХреЛ рд╡рд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░ рджреЗрддреЗ рд╣реИрдВ, рдЬреЛ рдкрде рдХреЗ рд╡рд┐рд╕реНрдерд╛рдкрди рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред void PrepareForward () { transform.localRotation = direction.GetRotation(); directionAngleTo = direction.GetAngle(); model.localPosition = new Vector3(pathOffset, 0f); progressFactor = 1f; } void PrepareTurnRight () { directionAngleTo = directionAngleFrom + 90f; model.localPosition = new Vector3(pathOffset - 0.5f, 0f); transform.localPosition = positionFrom + direction.GetHalfVector(); progressFactor = 1f / (Mathf.PI * 0.25f); } void PrepareTurnLeft () { directionAngleTo = directionAngleFrom - 90f; model.localPosition = new Vector3(pathOffset + 0.5f, 0f); transform.localPosition = positionFrom + direction.GetHalfVector(); progressFactor = 1f / (Mathf.PI * 0.25f); } void PrepareTurnAround () { directionAngleTo = directionAngleFrom + 180f; model.localPosition = new Vector3(pathOffset, 0f); transform.localPosition = positionFrom; progressFactor = 2f; } void PrepareIntro () { тАж model.localPosition = new Vector3(pathOffset, 0f); transform.localRotation = direction.GetRotation(); progressFactor = 2f; } void PrepareOutro () { тАж model.localPosition = new Vector3(pathOffset, 0f); transform.localRotation = direction.GetRotation(); progressFactor = 2f; }
рдЪреВрдВрдХрд┐ рд░реЛрдЯреЗрд╢рди рдХреЗ рджреМрд░рд╛рди рдкрде рдХрд╛ рд╡рд┐рд╕реНрдерд╛рдкрди рддреНрд░рд┐рдЬреНрдпрд╛ рдмрджрд▓рддрд╛ рд╣реИ, рд╣рдореЗрдВ рдкреНрд░рдЧрддрд┐ рдЧреБрдгрдХ рдХреА рдЧрдгрдирд╛ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдореЛрдбрд╝ рдХреЗ рддреНрд░рд┐рдЬреНрдпрд╛ рдХреЛ рджрд╛рдИрдВ рдУрд░ рд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкрде рдСрдлрд╕реЗрдЯ рдХреЛ ┬╜ рд╕реЗ рдШрдЯрд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдмрд╛рдИрдВ рдУрд░ рдПрдХ рдореЛрдбрд╝ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред void PrepareTurnRight () { тАж progressFactor = 1f / (Mathf.PI * 0.5f * (0.5f - pathOffset)); } void PrepareTurnLeft () { тАж progressFactor = 1f / (Mathf.PI * 0.5f * (0.5f + pathOffset)); }
180 ┬░ рдореБрдбрд╝рдиреЗ рдкрд░ рд╣рдореЗрдВ рдореЛрдбрд╝ рддреНрд░рд┐рдЬреНрдпрд╛ рднреА рдорд┐рд▓рддрд╛ рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо рдкрде рдХреЗ рдСрдлрд╕реЗрдЯ рдХреЗ рдмрд░рд╛рдмрд░ рддреНрд░рд┐рдЬреНрдпрд╛ рдХреЗ рд╕рд╛рде рдЖрдзрд╛ рд╕рд░реНрдХрд▓ рдХреЛ рдХрд╡рд░ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рджреВрд░реА рдСрдлрд╕реЗрдЯ рд╕реЗ cover рдЧреБрдирд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рддрдм рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдЬрдм рд╡рд┐рд╕реНрдерд╛рдкрди рд╢реВрдиреНрдп рд╣реЛ, рдФрд░ рдЫреЛрдЯреЗ рд╡рд┐рд╕реНрдерд╛рдкрди рдкрд░, рдореЛрдбрд╝ рдмрд╣реБрдд рддреЗрдЬ рд╣реЛред рддреНрд╡рд░рд┐рдд рдореЛрдбрд╝ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдиреНрдпреВрдирддрдо рддреНрд░рд┐рдЬреНрдпрд╛ рдХреЛ рдЧрддрд┐ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, 0.2 рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВред void PrepareTurnAround () { directionAngleTo = directionAngleFrom + (pathOffset < 0f ? 180f : -180f); model.localPosition = new Vector3(pathOffset, 0f); transform.localPosition = positionFrom; progressFactor = 1f / (Mathf.PI * Mathf.Max(Mathf.Abs(pathOffset), 0.2f)); }
рдкрде рдСрдлрд╝рд╕реЗрдЯ тИТ0.25тАУ0.25 рд╕реАрдорд╛ рдореЗрдВ рд╣реИредрдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЕрдм рджреБрд╢реНрдорди рдЕрдкрдиреЗ рд░рд┐рд╢реНрддреЗрджрд╛рд░ рдкрде рд╡рд┐рд╕реНрдерд╛рдкрди рдХреЛ рдХрднреА рдирд╣реАрдВ рдмрджрд▓рддреЗ рд╣реИрдВ, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЬрдм рдореБрдбрд╝рддреЗ рд╣реИрдВ рдЗрд╕рд▓рд┐рдП, рдкреНрд░рддреНрдпреЗрдХ рд╢рддреНрд░реБ рдХреЗ рд▓рд┐рдП рдкрде рдХреА рдХреБрд▓ рд▓рдВрдмрд╛рдИ рдЕрдкрдиреА рд╣реИредрджреБрд╢реНрдордиреЛрдВ рдХреЛ рдкрдбрд╝реЛрд╕реА рдЯрд╛рдЗрд▓реЛрдВ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рд╕реЗ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП, рдХрд┐рд╕реА рдХреЛ рдЕрдкрдиреЗ рдЕрдзрд┐рдХрддрдо рд╕рдВрднрд╡ рдкреИрдорд╛рдиреЗ рдХреЛ рднреА рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдПред рдореИрдВрдиреЗ рдЖрдХрд╛рд░ рдХреЛ рдХреЗрд╡рд▓ 1 рдХреЗ рдЕрдзрд┐рдХрддрдо рдореВрд▓реНрдп рддрдХ рд╕реАрдорд┐рдд рдХрд░ рджрд┐рдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдШрди рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХрддрдо рд╕реНрд╡реАрдХрд╛рд░реНрдп рдСрдлрд╕реЗрдЯ 0.25 рд╣реИред рдпрджрд┐ рдЕрдзрд┐рдХрддрдо рдЖрдХрд╛рд░ 1.5 рдерд╛, рддреЛ рдЕрдзрд┐рдХрддрдо рд╡рд┐рд╕реНрдерд╛рдкрди 0.125 рддрдХ рдХрдо рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПредрдЧрддрд┐
рдЖрдЦрд┐рд░реА рдЪреАрдЬ рдЬреЛ рд╣рдо рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдХрд░рддреЗ рд╣реИрдВ рд╡рд╣ рджреБрд╢реНрдордиреЛрдВ рдХреА рдЧрддрд┐ рд╣реИред рд╣рдо рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдФрд░ рдЕрдВрддрд░рд╛рд▓ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ EnemyFactory
рдФрд░ рд╣рдо рджреБрд╢реНрдорди рдХреА рдмрдирд╛рдИ рд╣реБрдИ рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдХреЛ рдореВрд▓реНрдп рд╣рд╕реНрддрд╛рдВрддрд░рд┐рдд рдХрд░реЗрдВрдЧреЗред рдЪрд▓рд┐рдП рдЗрд╕реЗ рд╡рд┐рдзрд┐ рдХрд╛ рджреВрд╕рд░рд╛ рддрд░реНрдХ рдмрдирд╛рддреЗ рд╣реИрдВ Initialize
ред рджреБрд╢реНрдордиреЛрдВ рдХреЛ рдмрд╣реБрдд рдзреАрдорд╛ рдпрд╛ рддреЗрдЬ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рддрд╛рдХрд┐ рдЦреЗрд▓ рддреБрдЪреНрдЫ рд╕рд░рд▓ рдпрд╛ рдЕрд╕рдВрднрд╡ рдореБрд╢реНрдХрд┐рд▓ рди рд╣реЛ рдЬрд╛рдПред рдЖрдЗрдП рдЕрдВрддрд░рд╛рд▓ рдХреЛ 0.2тАУ5 рддрдХ рд╕реАрдорд┐рдд рдХрд░реЗрдВред рдЧрддрд┐ рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб рдЗрдХрд╛рдЗрдпреЛрдВ рдореЗрдВ рд╡реНрдпрдХреНрдд рдХреА рдЬрд╛рддреА рд╣реИ, рдЬреЛ рдЖрдЧреЗ рдмрдврд╝рдиреЗ рдкрд░ рдХреЗрд╡рд▓ рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб рдЯрд╛рдЗрд▓реНрд╕ рд╕реЗ рдореЗрд▓ рдЦрд╛рддреА рд╣реИред [SerializeField, FloatRangeSlider(0.2f, 5f)] FloatRange speed = new FloatRange(1f); [SerializeField, FloatRangeSlider(-0.4f, 0.4f)] FloatRange pathOffset = new FloatRange(0f); public Enemy Get () { Enemy instance = CreateGameObjectInstance(prefab); instance.OriginFactory = this; instance.Initialize( scale.RandomValueInRange, speed.RandomValueInRange, pathOffset.RandomValueInRange ); return instance; }
рдЕрдм рдореБрдЭреЗ Enemy
рдЯреНрд░реИрдХ рдФрд░ рд╕реНрдкреАрдб рдХрд░рдиреА рд╣реИред float speed; тАж public void Initialize (float scale, float speed, float pathOffset) { model.localScale = new Vector3(scale, scale, scale); this.speed = speed; this.pathOffset = pathOffset; }
рдЬрдм рд╣рдордиреЗ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЧрддрд┐ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдирд╣реАрдВ рдХреА рдереА, рддреЛ рд╣рдордиреЗ рдмрд╕ рд╣рдореЗрд╢рд╛ рдореВрд▓реНрдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдерд╛ред рдЕрдм рд╣рдореЗрдВ рдХреЗрд╡рд▓ рдЧрддрд┐ рдкрд░ рдкреНрд░рдЧрддрд┐ рдЧреБрдгрдХ рдХреА рдирд┐рд░реНрднрд░рддрд╛ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред void PrepareForward () { тАж progressFactor = speed; } void PrepareTurnRight () { тАж progressFactor = speed / (Mathf.PI * 0.5f * (0.5f - pathOffset)); } void PrepareTurnLeft () { тАж progressFactor = speed / (Mathf.PI * 0.5f * (0.5f + pathOffset)); } void PrepareTurnAround () { тАж progressFactor = speed / (Mathf.PI * Mathf.Max(Mathf.Abs(pathOffset), 0.2f)); } void PrepareIntro () { тАж progressFactor = 2f * speed; } void PrepareOutro () { тАж progressFactor = 2f * speed; }
рд░реЗрдВрдЬ рдореЗрдВ рдЧрддрд┐ 0.75-1.25редрдЗрд╕рд▓рд┐рдП, рд╣рдореЗрдВ рджреБрд╢реНрдордиреЛрдВ рдХреА рдПрдХ рд╕реБрдВрджрд░ рдзрд╛рд░рд╛ рдорд┐рд▓ рдЧрдИ рдЬреЛ рдЕрдВрддрд┐рдо рдмрд┐рдВрджреБ рдкрд░ рдЬрд╛ рд░рд╣реА рдереАред рдЕрдЧрд▓реЗ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдореЗрдВ рд╣рдо рдЬрд╛рдиреЗрдВрдЧреЗ рдХрд┐ рдЗрдирд╕реЗ рдХреИрд╕реЗ рдирд┐рдкрдЯрд╛ рдЬрд╛рдПред рдЬрд╛рдирдирд╛ рдЪрд╛рд╣реЗрдВрдЧреЗ рдХрд┐ рдпрд╣ рдХрдм рд░рд┐рд▓реАрдЬ рд╣реЛрдЧреА? Patreon рдкрд░ рдореЗрд░реЗ рдкреЗрдЬ рдХрд╛ рдкрд╛рд▓рди рдХрд░реЗрдВ !рд░рд┐рдкреЙрдЬрд┐рдЯрд░реАрдкреАрдбреАрдПрдл рд▓реЗрдЦ