3D: камера как на карте мира, расчистка только в зоне, почта под Наградами, старт с City3D
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 030e644cb052c0f4d959e499015370fd
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 904233d7647ed024d920bdbbd4058aba
|
||||
@@ -3,11 +3,13 @@ using UnityEditor;
|
||||
|
||||
// Следит, чтобы сцена карты мира (WorldMap, от Саши) была в Build Settings --
|
||||
// иначе переход город -> карта не работает. Срабатывает сам после каждой компиляции.
|
||||
// Стартовая сцена (05.11): 3D-поселение City3D, если оно есть в проекте, иначе 2D-город MVP1.
|
||||
[InitializeOnLoad]
|
||||
public static class SceneListFixer
|
||||
{
|
||||
const string CityScene = "Assets/Scenes/MVP1.unity";
|
||||
const string WorldScene = "Assets/Scenes/WorldMap.unity";
|
||||
const string City3DScene = "Assets/Scenes/City3D.unity";
|
||||
|
||||
static SceneListFixer() { EditorApplication.delayCall += Ensure; }
|
||||
|
||||
@@ -15,15 +17,16 @@ public static class SceneListFixer
|
||||
{
|
||||
var scenes = new List<EditorBuildSettingsScene>(EditorBuildSettings.scenes);
|
||||
bool changed = false;
|
||||
foreach (var path in new[] { CityScene, WorldScene })
|
||||
string start = AssetDatabase.LoadAssetAtPath<SceneAsset>(City3DScene) != null ? City3DScene : CityScene;
|
||||
foreach (var path in new[] { start, CityScene, WorldScene })
|
||||
{
|
||||
if (AssetDatabase.LoadAssetAtPath<SceneAsset>(path) == null) continue;
|
||||
if (scenes.Exists(s => s.path == path)) continue;
|
||||
scenes.Add(new EditorBuildSettingsScene(path, true));
|
||||
changed = true;
|
||||
}
|
||||
// город должен быть первым (с него стартует игра)
|
||||
int city = scenes.FindIndex(s => s.path == CityScene);
|
||||
// стартовый город должен быть первым (с него стартует игра)
|
||||
int city = scenes.FindIndex(s => s.path == start);
|
||||
if (city > 0) { var c = scenes[city]; scenes.RemoveAt(city); scenes.Insert(0, c); changed = true; }
|
||||
if (changed)
|
||||
{
|
||||
|
||||
@@ -574,11 +574,11 @@ RectTransform:
|
||||
- {fileID: 8073695889979356888}
|
||||
m_Father: {fileID: 3982763195980837839}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 432, y: 0}
|
||||
m_AnchorMin: {x: 0.416667, y: 1}
|
||||
m_AnchorMax: {x: 0.416667, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 216, y: 190}
|
||||
m_Pivot: {x: 0, y: 1}
|
||||
m_Pivot: {x: 0.5, y: 1}
|
||||
--- !u!222 &1161890866068155973
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -949,11 +949,11 @@ RectTransform:
|
||||
- {fileID: 6625169345854146367}
|
||||
m_Father: {fileID: 3982763195980837839}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 1625, y: 0}
|
||||
m_AnchorMin: {x: 0.75, y: 1}
|
||||
m_AnchorMax: {x: 0.75, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 216, y: 190}
|
||||
m_Pivot: {x: 0, y: 1}
|
||||
m_Pivot: {x: 0.5, y: 1}
|
||||
--- !u!222 &1574865706497193506
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -2083,11 +2083,11 @@ RectTransform:
|
||||
- {fileID: 5819281947737217065}
|
||||
m_Father: {fileID: 3982763195980837839}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 1409, y: 0}
|
||||
m_AnchorMin: {x: 0.583333, y: 1}
|
||||
m_AnchorMax: {x: 0.583333, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 216, y: 190}
|
||||
m_Pivot: {x: 0, y: 1}
|
||||
m_Pivot: {x: 0.5, y: 1}
|
||||
--- !u!222 &8054631941258821217
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -2724,11 +2724,11 @@ RectTransform:
|
||||
- {fileID: 6422401267007934049}
|
||||
m_Father: {fileID: 3982763195980837839}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchorMin: {x: 0.083333, y: 1}
|
||||
m_AnchorMax: {x: 0.083333, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 216, y: 190}
|
||||
m_Pivot: {x: 0, y: 1}
|
||||
m_Pivot: {x: 0.5, y: 1}
|
||||
--- !u!222 &1319220892576480966
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -3692,11 +3692,11 @@ RectTransform:
|
||||
- {fileID: 4996814669716176554}
|
||||
m_Father: {fileID: 3982763195980837839}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 216, y: 0}
|
||||
m_AnchorMin: {x: 0.25, y: 1}
|
||||
m_AnchorMax: {x: 0.25, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 216, y: 190}
|
||||
m_Pivot: {x: 0, y: 1}
|
||||
m_Pivot: {x: 0.5, y: 1}
|
||||
--- !u!222 &5060908328969132528
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -4111,13 +4111,14 @@ RectTransform:
|
||||
- {fileID: 3561707029477629692}
|
||||
- {fileID: 3476476116216033849}
|
||||
- {fileID: 628544459168404126}
|
||||
- {fileID: 113684291289998490}
|
||||
m_Father: {fileID: 2090086157864901368}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 1, y: 1}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: -145, y: -425}
|
||||
m_AnchoredPosition: {x: -145, y: -190}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
m_Pivot: {x: 0.5, y: 1}
|
||||
--- !u!114 &4213699917549184054
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -9582,13 +9583,13 @@ RectTransform:
|
||||
- {fileID: 8503115147530003650}
|
||||
- {fileID: 3734242786053216068}
|
||||
- {fileID: 1570549891241898707}
|
||||
m_Father: {fileID: 3982763195980837839}
|
||||
m_Father: {fileID: 4178416176766117917}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 1, y: 1}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: -162, y: 172.02252}
|
||||
m_SizeDelta: {x: 128.34, y: 102.34}
|
||||
m_Pivot: {x: 0, y: 1}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 118, y: 118}
|
||||
m_Pivot: {x: 1, y: 1}
|
||||
--- !u!222 &2919605703939985733
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -10263,11 +10264,11 @@ RectTransform:
|
||||
- {fileID: 8771264060587801238}
|
||||
m_Father: {fileID: 3982763195980837839}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 1808, y: 0}
|
||||
m_AnchorMin: {x: 0.916667, y: 1}
|
||||
m_AnchorMax: {x: 0.916667, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 216, y: 190}
|
||||
m_Pivot: {x: 0, y: 1}
|
||||
m_Pivot: {x: 0.5, y: 1}
|
||||
--- !u!222 &7841802503944609977
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -14658,7 +14659,6 @@ RectTransform:
|
||||
- {fileID: 3980605506120029191}
|
||||
- {fileID: 6797326426102539044}
|
||||
- {fileID: 6246972527393936552}
|
||||
- {fileID: 113684291289998490}
|
||||
m_Father: {fileID: 2090086157864901368}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
|
||||
@@ -20,7 +20,6 @@ public class City3DCamera : MonoBehaviour
|
||||
bool focusing;
|
||||
Vector3 lastPointer;
|
||||
bool panning;
|
||||
float lastPinch;
|
||||
|
||||
// Перемещение камеры пальцем можно выключить на время перетаскивания здания
|
||||
public bool AllowPan { get; set; } = true;
|
||||
@@ -43,6 +42,10 @@ public class City3DCamera : MonoBehaviour
|
||||
public void BeginPan(Vector3 screen) { panning = AllowPan; lastPointer = screen; focusing = false; }
|
||||
public void EndPan() { panning = false; }
|
||||
|
||||
// Палец ещё не сдвинулся настолько, чтобы считать это перетаскиванием: камера стоит, но точка запоминается --
|
||||
// когда перетаскивание начнётся, карта не прыгнет (как на карте мира, 05.11)
|
||||
public void Track(Vector3 screen) { lastPointer = screen; }
|
||||
|
||||
public void Pan(Vector3 screen)
|
||||
{
|
||||
if (!panning || cam == null) return;
|
||||
@@ -50,6 +53,7 @@ public class City3DCamera : MonoBehaviour
|
||||
target += a - b;
|
||||
lastPointer = screen;
|
||||
Clamp();
|
||||
Apply(); // сразу: иначе следующий шаг считался бы от старого положения камеры -- камера дёргалась (05.11)
|
||||
}
|
||||
|
||||
public void Zoom(float delta)
|
||||
@@ -65,14 +69,19 @@ public class City3DCamera : MonoBehaviour
|
||||
if (UIBlocker.IsPointerOverUI()) wheel = 0f; // колесо над окнами HUD -- не приближать камеру (05.11)
|
||||
if (Mathf.Abs(wheel) > 0.01f) Zoom(wheel * 0.1f);
|
||||
|
||||
// Два пальца -- приближение
|
||||
if (Input.touchCount == 2)
|
||||
// Два пальца -- приближение, как на карте мира: расстояние камеры меняется во столько раз,
|
||||
// во сколько изменилось расстояние между пальцами за кадр (не зависит от того, увидели ли касание) (05.11)
|
||||
if (Input.touchCount >= 2)
|
||||
{
|
||||
float d = Vector2.Distance(Input.GetTouch(0).position, Input.GetTouch(1).position);
|
||||
if (Input.GetTouch(1).phase == TouchPhase.Began) lastPinch = d;
|
||||
else if (lastPinch > 0) { Zoom((d - lastPinch) / Mathf.Max(200f, Screen.height)); lastPinch = d; }
|
||||
Touch a = Input.GetTouch(0), b = Input.GetTouch(1);
|
||||
float previous = ((a.position - a.deltaPosition) - (b.position - b.deltaPosition)).magnitude;
|
||||
float current = (a.position - b.position).magnitude;
|
||||
if (previous > 0.01f && current > 0.01f)
|
||||
{
|
||||
focusing = false;
|
||||
distance = Mathf.Clamp(distance * previous / current, minDistance, maxDistance);
|
||||
}
|
||||
}
|
||||
else lastPinch = 0;
|
||||
|
||||
if (focusing)
|
||||
{
|
||||
|
||||
@@ -677,7 +677,8 @@ public class City3DController : MonoBehaviour, City3DSave.ILive
|
||||
{
|
||||
if ((pos - pointerDown).magnitude > Screen.height * 0.015f) pointerMoved = true;
|
||||
if (draggingGhost) DragGhost(pos);
|
||||
else cameraRig.Pan(pos);
|
||||
else if (pointerMoved) cameraRig.Pan(pos); // карта едет только при настоящем перетаскивании
|
||||
else cameraRig.Track(pos); // а мелкое дрожание пальца при тапе её не трогает
|
||||
}
|
||||
else if (up && !pointerOverGui)
|
||||
{
|
||||
@@ -730,6 +731,12 @@ public class City3DController : MonoBehaviour, City3DSave.ILive
|
||||
}
|
||||
selectedBuilding = building;
|
||||
selectedObstacle = building == null ? map.ObstacleAt(cx, cy) : null;
|
||||
// Расчищать можно только в открытой зоне стройки (за её пределами -- после улучшения Ратуши) (05.11)
|
||||
if (selectedObstacle != null && !map.IsOpen(cx, cy, townHallLevel))
|
||||
{
|
||||
selectedObstacle = null;
|
||||
Say("Это за пределами зоны стройки -- откроется после улучшения Ратуши");
|
||||
}
|
||||
}
|
||||
|
||||
// Клетка под пальцем. groundOnly -- только земля (перетаскивание призрака); иначе здание под пальцем -- его клетка
|
||||
@@ -845,10 +852,13 @@ public class City3DController : MonoBehaviour, City3DSave.ILive
|
||||
// Окно HUD открыто -- временные кнопки сцены не показываем (и не ловим нажатия)
|
||||
if (UIPanelManager.Instance != null && UIPanelManager.Instance.CurrentId != "") return;
|
||||
|
||||
// Под верхней панелью HUD, справа: Ратуша (тест), редактирование
|
||||
Box(new Rect(w - 480, HudTop, 290, 44), $"3D (прототип) • Ратуша {townHallLevel} ур.");
|
||||
if (Button(new Rect(w - 185, HudTop, 55, 44), "−")) ChangeTownHall(-1);
|
||||
if (Button(new Rect(w - 125, HudTop, 55, 44), "+")) ChangeTownHall(+1);
|
||||
// Под верхней панелью HUD, справа: Ратуша −/+ -- только в редакторе и отладочной сборке (тест зон), редактирование
|
||||
if (Application.isEditor || Debug.isDebugBuild)
|
||||
{
|
||||
Box(new Rect(w - 480, HudTop, 290, 44), $"3D (тест) • Ратуша {townHallLevel} ур.");
|
||||
if (Button(new Rect(w - 185, HudTop, 55, 44), "−")) ChangeTownHall(-1);
|
||||
if (Button(new Rect(w - 125, HudTop, 55, 44), "+")) ChangeTownHall(+1);
|
||||
}
|
||||
if (mode == Mode.View || mode == Mode.Edit)
|
||||
{
|
||||
if (Button(new Rect(w - 250, HudTop + 50, 240, 44), mode == Mode.Edit ? "Готово" : "Редактировать"))
|
||||
|
||||
@@ -187,9 +187,19 @@ public static class City3DGameplay
|
||||
if (!canvas.isRootCanvas || canvas.renderMode != RenderMode.ScreenSpaceCamera) continue;
|
||||
canvas.worldCamera = cam;
|
||||
canvas.planeDistance = cam.nearClipPlane + 0.05f;
|
||||
HideWorldSprites(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
// В HUD есть картинка-спрайт мира (SpriteRenderer) -- плашка с мечом по центру нижней панели. На холсте у
|
||||
// камеры она рисуется поверх всего HUD, даже поверх открытых окон, а сама картинка без прозрачности
|
||||
// ("шахматка"). Решение 05.11 (Миша, Володя): в 3D-сцене её убираем, пока не будет новой картинки или кнопки.
|
||||
static void HideWorldSprites(Canvas canvas)
|
||||
{
|
||||
foreach (var sr in canvas.GetComponentsInChildren<SpriteRenderer>(true))
|
||||
sr.enabled = false;
|
||||
}
|
||||
|
||||
// Награда за расчистку (решение 04.11): +10 дерева за дерево или +10 камня за валун, один раз, в пределах склада
|
||||
public static void RewardClearing(bool tree)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user