first commit
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4725f92f23887a4d6a1b8553eb7c03cd
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,508 @@
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEditor.AI;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public static class Lab7SceneBuilder
|
||||
{
|
||||
private const string ScenePath = "Assets/_Scenes/TerritoryScene.unity";
|
||||
|
||||
[MenuItem("Tools/Lab7/Create Full Territory Scene")]
|
||||
public static void CreateFullTerritoryScene()
|
||||
{
|
||||
Time.timeScale = 1f;
|
||||
CreateFolders();
|
||||
EnsureTag("Player");
|
||||
EnsureTag("Enemy");
|
||||
|
||||
Material groundMaterial = GetOrCreateMaterial("Assets/_Materials/Ground.mat", new Color(0.25f, 0.34f, 0.25f, 1f), false);
|
||||
Material wallMaterial = GetOrCreateMaterial("Assets/_Materials/Walls.mat", new Color(0.38f, 0.39f, 0.42f, 1f), false);
|
||||
Material playerMaterial = GetOrCreateMaterial("Assets/_Materials/PlayerBlue.mat", new Color(0.1f, 0.35f, 1f, 1f), false);
|
||||
Material enemyMaterial = GetOrCreateMaterial("Assets/_Materials/EnemyRed.mat", new Color(1f, 0.12f, 0.08f, 1f), false);
|
||||
Material zoneNeutralMaterial = GetOrCreateMaterial("Assets/_Materials/ZoneTransparent.mat", new Color(0.55f, 0.55f, 0.55f, 0.45f), true);
|
||||
|
||||
Scene scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
|
||||
scene.name = "TerritoryScene";
|
||||
|
||||
GameObject ground = CreateGround(groundMaterial);
|
||||
CreateObstacles(wallMaterial);
|
||||
|
||||
Camera mainCamera = CreateCamera();
|
||||
CreateLight();
|
||||
|
||||
TerritoryUI territoryUI = CreateMainUI();
|
||||
ResourceManager resourceManager = CreateResourceManager(territoryUI);
|
||||
GameManager gameManager = CreateGameManager(territoryUI);
|
||||
|
||||
CaptureZone[] zones = new CaptureZone[]
|
||||
{
|
||||
CreateCaptureZone("Zone A", new Vector3(-8f, 0.05f, 6f), zoneNeutralMaterial, mainCamera),
|
||||
CreateCaptureZone("Zone B", new Vector3(7.5f, 0.05f, 4f), zoneNeutralMaterial, mainCamera),
|
||||
CreateCaptureZone("Zone C", new Vector3(0f, 0.05f, -7.5f), zoneNeutralMaterial, mainCamera)
|
||||
};
|
||||
|
||||
PlayerController player = CreatePlayer(playerMaterial);
|
||||
EnemyAI enemyOne = CreateEnemy("Enemy 1", new Vector3(10f, 1f, -9f), enemyMaterial);
|
||||
EnemyAI enemyTwo = CreateEnemy("Enemy 2", new Vector3(-10f, 1f, -9f), enemyMaterial);
|
||||
|
||||
enemyOne.zones = zones;
|
||||
enemyTwo.zones = zones;
|
||||
gameManager.zones = zones;
|
||||
|
||||
territoryUI.UpdateZoneStatus(zones);
|
||||
territoryUI.SetScore(0, 0);
|
||||
territoryUI.HideGameOver();
|
||||
|
||||
resourceManager.territoryUI = territoryUI;
|
||||
gameManager.territoryUI = territoryUI;
|
||||
gameManager.winPanel = territoryUI.winPanel;
|
||||
gameManager.winText = territoryUI.winText;
|
||||
|
||||
BakeNavMeshIfAvailable(ground);
|
||||
|
||||
EditorSceneManager.SaveScene(scene, ScenePath);
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
Selection.activeObject = player.gameObject;
|
||||
Debug.Log("Lab 7 territory scene created: " + ScenePath);
|
||||
}
|
||||
|
||||
private static void CreateFolders()
|
||||
{
|
||||
CreateFolderIfMissing("Assets", "_Scripts");
|
||||
CreateFolderIfMissing("Assets", "_Scenes");
|
||||
CreateFolderIfMissing("Assets", "_Materials");
|
||||
CreateFolderIfMissing("Assets", "_Prefabs");
|
||||
CreateFolderIfMissing("Assets", "Editor");
|
||||
}
|
||||
|
||||
private static void CreateFolderIfMissing(string parent, string child)
|
||||
{
|
||||
string path = parent + "/" + child;
|
||||
if (!AssetDatabase.IsValidFolder(path))
|
||||
{
|
||||
AssetDatabase.CreateFolder(parent, child);
|
||||
}
|
||||
}
|
||||
|
||||
private static void EnsureTag(string tag)
|
||||
{
|
||||
SerializedObject tagManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/TagManager.asset")[0]);
|
||||
SerializedProperty tagsProperty = tagManager.FindProperty("tags");
|
||||
|
||||
for (int i = 0; i < tagsProperty.arraySize; i++)
|
||||
{
|
||||
SerializedProperty tagProperty = tagsProperty.GetArrayElementAtIndex(i);
|
||||
if (tagProperty.stringValue == tag)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
tagsProperty.InsertArrayElementAtIndex(tagsProperty.arraySize);
|
||||
tagsProperty.GetArrayElementAtIndex(tagsProperty.arraySize - 1).stringValue = tag;
|
||||
tagManager.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
private static Material GetOrCreateMaterial(string path, Color color, bool transparent)
|
||||
{
|
||||
Material material = AssetDatabase.LoadAssetAtPath<Material>(path);
|
||||
if (material == null)
|
||||
{
|
||||
material = new Material(Shader.Find("Standard"));
|
||||
AssetDatabase.CreateAsset(material, path);
|
||||
}
|
||||
|
||||
material.color = color;
|
||||
if (transparent)
|
||||
{
|
||||
ConfigureTransparentMaterial(material);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConfigureOpaqueMaterial(material);
|
||||
}
|
||||
|
||||
EditorUtility.SetDirty(material);
|
||||
return material;
|
||||
}
|
||||
|
||||
private static void ConfigureTransparentMaterial(Material material)
|
||||
{
|
||||
material.SetFloat("_Mode", 3f);
|
||||
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
|
||||
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
|
||||
material.SetInt("_ZWrite", 0);
|
||||
material.DisableKeyword("_ALPHATEST_ON");
|
||||
material.EnableKeyword("_ALPHABLEND_ON");
|
||||
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
|
||||
material.renderQueue = 3000;
|
||||
}
|
||||
|
||||
private static void ConfigureOpaqueMaterial(Material material)
|
||||
{
|
||||
material.SetFloat("_Mode", 0f);
|
||||
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
|
||||
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
|
||||
material.SetInt("_ZWrite", 1);
|
||||
material.DisableKeyword("_ALPHATEST_ON");
|
||||
material.DisableKeyword("_ALPHABLEND_ON");
|
||||
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
|
||||
material.renderQueue = -1;
|
||||
}
|
||||
|
||||
private static GameObject CreateGround(Material material)
|
||||
{
|
||||
GameObject ground = GameObject.CreatePrimitive(PrimitiveType.Plane);
|
||||
ground.name = "Ground";
|
||||
ground.transform.position = Vector3.zero;
|
||||
ground.transform.localScale = new Vector3(3f, 1f, 3f);
|
||||
ground.GetComponent<Renderer>().sharedMaterial = material;
|
||||
GameObjectUtility.SetStaticEditorFlags(ground, StaticEditorFlags.NavigationStatic);
|
||||
return ground;
|
||||
}
|
||||
|
||||
private static void CreateObstacles(Material material)
|
||||
{
|
||||
CreateWall("Wall North", new Vector3(0f, 1f, 14f), new Vector3(28f, 2f, 1f), material);
|
||||
CreateWall("Wall South", new Vector3(0f, 1f, -14f), new Vector3(28f, 2f, 1f), material);
|
||||
CreateWall("Wall West", new Vector3(-14f, 1f, 0f), new Vector3(1f, 2f, 28f), material);
|
||||
CreateWall("Wall East", new Vector3(14f, 1f, 0f), new Vector3(1f, 2f, 28f), material);
|
||||
CreateWall("Center Block", new Vector3(0f, 1f, 0f), new Vector3(4f, 2f, 2f), material);
|
||||
CreateWall("Left Cover", new Vector3(-6f, 1f, -2f), new Vector3(2f, 2f, 6f), material);
|
||||
CreateWall("Right Cover", new Vector3(6f, 1f, -1.5f), new Vector3(2f, 2f, 5f), material);
|
||||
}
|
||||
|
||||
private static GameObject CreateWall(string name, Vector3 position, Vector3 scale, Material material)
|
||||
{
|
||||
GameObject wall = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
||||
wall.name = name;
|
||||
wall.transform.position = position;
|
||||
wall.transform.localScale = scale;
|
||||
wall.GetComponent<Renderer>().sharedMaterial = material;
|
||||
GameObjectUtility.SetStaticEditorFlags(wall, StaticEditorFlags.NavigationStatic);
|
||||
return wall;
|
||||
}
|
||||
|
||||
private static Camera CreateCamera()
|
||||
{
|
||||
GameObject cameraObject = new GameObject("Main Camera");
|
||||
Camera camera = cameraObject.AddComponent<Camera>();
|
||||
camera.tag = "MainCamera";
|
||||
camera.transform.position = new Vector3(0f, 22f, -20f);
|
||||
camera.transform.rotation = Quaternion.Euler(55f, 0f, 0f);
|
||||
camera.orthographic = true;
|
||||
camera.orthographicSize = 16f;
|
||||
camera.clearFlags = CameraClearFlags.Skybox;
|
||||
camera.nearClipPlane = 0.3f;
|
||||
camera.farClipPlane = 100f;
|
||||
return camera;
|
||||
}
|
||||
|
||||
private static void CreateLight()
|
||||
{
|
||||
GameObject lightObject = new GameObject("Directional Light");
|
||||
Light light = lightObject.AddComponent<Light>();
|
||||
light.type = LightType.Directional;
|
||||
light.intensity = 1.1f;
|
||||
light.transform.rotation = Quaternion.Euler(50f, -30f, 0f);
|
||||
}
|
||||
|
||||
private static TerritoryUI CreateMainUI()
|
||||
{
|
||||
Font font = GetBuiltinFont();
|
||||
|
||||
GameObject canvasObject = new GameObject("Main UI Canvas");
|
||||
Canvas canvas = canvasObject.AddComponent<Canvas>();
|
||||
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
||||
CanvasScaler scaler = canvasObject.AddComponent<CanvasScaler>();
|
||||
scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
|
||||
scaler.referenceResolution = new Vector2(1920f, 1080f);
|
||||
canvasObject.AddComponent<GraphicRaycaster>();
|
||||
|
||||
TerritoryUI territoryUI = canvasObject.AddComponent<TerritoryUI>();
|
||||
|
||||
Text title = CreateOverlayText("Title", canvasObject.transform, font, "Лабораторная работа №7 — Контроль территории", 24, TextAnchor.UpperLeft);
|
||||
SetRect(title.rectTransform, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(18f, -18f), new Vector2(760f, 38f));
|
||||
|
||||
Text controls = CreateOverlayText("Controls", canvasObject.transform, font, "WASD — движение\nЗахватите все контрольные точки", 18, TextAnchor.UpperLeft);
|
||||
SetRect(controls.rectTransform, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(18f, -56f), new Vector2(430f, 62f));
|
||||
|
||||
Text playerPoints = CreateOverlayText("Player Points", canvasObject.transform, font, "Player Points: 0", 20, TextAnchor.UpperLeft);
|
||||
playerPoints.color = new Color(0.25f, 0.55f, 1f);
|
||||
SetRect(playerPoints.rectTransform, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(18f, -124f), new Vector2(300f, 32f));
|
||||
|
||||
Text enemyPoints = CreateOverlayText("Enemy Points", canvasObject.transform, font, "Enemy Points: 0", 20, TextAnchor.UpperLeft);
|
||||
enemyPoints.color = new Color(1f, 0.32f, 0.25f);
|
||||
SetRect(enemyPoints.rectTransform, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(18f, -158f), new Vector2(300f, 32f));
|
||||
|
||||
Text zoneStatus = CreateOverlayText("Zone Status", canvasObject.transform, font, "Zone A: Neutral, 50%\nZone B: Neutral, 50%\nZone C: Neutral, 50%", 19, TextAnchor.UpperRight);
|
||||
SetRect(zoneStatus.rectTransform, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-18f, -18f), new Vector2(360f, 110f));
|
||||
|
||||
GameObject winPanel = CreateWinPanel(canvasObject.transform, font, out Text winText);
|
||||
|
||||
territoryUI.playerPointsText = playerPoints;
|
||||
territoryUI.enemyPointsText = enemyPoints;
|
||||
territoryUI.zoneStatusText = zoneStatus;
|
||||
territoryUI.winPanel = winPanel;
|
||||
territoryUI.winText = winText;
|
||||
|
||||
return territoryUI;
|
||||
}
|
||||
|
||||
private static GameObject CreateWinPanel(Transform parent, Font font, out Text winText)
|
||||
{
|
||||
GameObject panel = new GameObject("Win Panel");
|
||||
panel.transform.SetParent(parent, false);
|
||||
Image image = panel.AddComponent<Image>();
|
||||
image.color = new Color(0f, 0f, 0f, 0.72f);
|
||||
RectTransform rectTransform = panel.GetComponent<RectTransform>();
|
||||
SetRect(rectTransform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(760f, 180f));
|
||||
|
||||
winText = CreateOverlayText("Win Text", panel.transform, font, "", 32, TextAnchor.MiddleCenter);
|
||||
winText.color = Color.white;
|
||||
SetRect(winText.rectTransform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(720f, 150f));
|
||||
panel.SetActive(false);
|
||||
return panel;
|
||||
}
|
||||
|
||||
private static Text CreateOverlayText(string name, Transform parent, Font font, string text, int fontSize, TextAnchor alignment)
|
||||
{
|
||||
GameObject textObject = new GameObject(name);
|
||||
textObject.transform.SetParent(parent, false);
|
||||
Text uiText = textObject.AddComponent<Text>();
|
||||
uiText.font = font;
|
||||
uiText.text = text;
|
||||
uiText.fontSize = fontSize;
|
||||
uiText.alignment = alignment;
|
||||
uiText.color = Color.white;
|
||||
uiText.horizontalOverflow = HorizontalWrapMode.Wrap;
|
||||
uiText.verticalOverflow = VerticalWrapMode.Overflow;
|
||||
return uiText;
|
||||
}
|
||||
|
||||
private static Font GetBuiltinFont()
|
||||
{
|
||||
Font font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
|
||||
if (font == null)
|
||||
{
|
||||
font = Resources.GetBuiltinResource<Font>("Arial.ttf");
|
||||
}
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
private static void SetRect(RectTransform rectTransform, Vector2 anchorMin, Vector2 anchorMax, Vector2 anchoredPosition, Vector2 size)
|
||||
{
|
||||
rectTransform.anchorMin = anchorMin;
|
||||
rectTransform.anchorMax = anchorMax;
|
||||
rectTransform.pivot = anchorMin == anchorMax ? anchorMin : new Vector2(0.5f, 0.5f);
|
||||
rectTransform.anchoredPosition = anchoredPosition;
|
||||
rectTransform.sizeDelta = size;
|
||||
}
|
||||
|
||||
private static ResourceManager CreateResourceManager(TerritoryUI territoryUI)
|
||||
{
|
||||
GameObject managerObject = new GameObject("ResourceManager");
|
||||
ResourceManager resourceManager = managerObject.AddComponent<ResourceManager>();
|
||||
resourceManager.pointsText = territoryUI.playerPointsText;
|
||||
resourceManager.enemyPointsText = territoryUI.enemyPointsText;
|
||||
resourceManager.territoryUI = territoryUI;
|
||||
return resourceManager;
|
||||
}
|
||||
|
||||
private static GameManager CreateGameManager(TerritoryUI territoryUI)
|
||||
{
|
||||
GameObject managerObject = new GameObject("GameManager");
|
||||
GameManager gameManager = managerObject.AddComponent<GameManager>();
|
||||
gameManager.territoryUI = territoryUI;
|
||||
gameManager.winPanel = territoryUI.winPanel;
|
||||
gameManager.winText = territoryUI.winText;
|
||||
gameManager.scoreLimit = 100;
|
||||
return gameManager;
|
||||
}
|
||||
|
||||
private static PlayerController CreatePlayer(Material material)
|
||||
{
|
||||
GameObject playerObject = GameObject.CreatePrimitive(PrimitiveType.Capsule);
|
||||
playerObject.name = "Player";
|
||||
playerObject.tag = "Player";
|
||||
playerObject.transform.position = new Vector3(0f, 1f, 10f);
|
||||
playerObject.GetComponent<Renderer>().sharedMaterial = material;
|
||||
Object.DestroyImmediate(playerObject.GetComponent<CapsuleCollider>());
|
||||
|
||||
CharacterController controller = playerObject.AddComponent<CharacterController>();
|
||||
controller.radius = 0.5f;
|
||||
controller.height = 2f;
|
||||
controller.center = Vector3.zero;
|
||||
|
||||
PlayerController player = playerObject.AddComponent<PlayerController>();
|
||||
player.moveSpeed = 6f;
|
||||
return player;
|
||||
}
|
||||
|
||||
private static EnemyAI CreateEnemy(string name, Vector3 position, Material material)
|
||||
{
|
||||
GameObject enemyObject = GameObject.CreatePrimitive(PrimitiveType.Capsule);
|
||||
enemyObject.name = name;
|
||||
enemyObject.tag = "Enemy";
|
||||
enemyObject.transform.position = position;
|
||||
enemyObject.GetComponent<Renderer>().sharedMaterial = material;
|
||||
Object.DestroyImmediate(enemyObject.GetComponent<CapsuleCollider>());
|
||||
|
||||
CharacterController controller = enemyObject.AddComponent<CharacterController>();
|
||||
controller.radius = 0.5f;
|
||||
controller.height = 2f;
|
||||
controller.center = Vector3.zero;
|
||||
|
||||
Rigidbody rigidbody = enemyObject.AddComponent<Rigidbody>();
|
||||
rigidbody.isKinematic = true;
|
||||
rigidbody.useGravity = false;
|
||||
|
||||
NavMeshAgent agent = enemyObject.AddComponent<NavMeshAgent>();
|
||||
agent.speed = 3.5f;
|
||||
agent.angularSpeed = 360f;
|
||||
agent.acceleration = 12f;
|
||||
agent.stoppingDistance = 0.7f;
|
||||
|
||||
EnemyAI enemyAI = enemyObject.AddComponent<EnemyAI>();
|
||||
enemyAI.moveSpeed = 3.5f;
|
||||
enemyAI.retargetInterval = 2f;
|
||||
enemyAI.randomFactor = 4f;
|
||||
return enemyAI;
|
||||
}
|
||||
|
||||
private static CaptureZone CreateCaptureZone(string name, Vector3 position, Material sharedZoneMaterial, Camera mainCamera)
|
||||
{
|
||||
GameObject zoneObject = new GameObject(name);
|
||||
zoneObject.transform.position = position;
|
||||
|
||||
SphereCollider trigger = zoneObject.AddComponent<SphereCollider>();
|
||||
trigger.isTrigger = true;
|
||||
trigger.radius = 3.1f;
|
||||
|
||||
CaptureZone zone = zoneObject.AddComponent<CaptureZone>();
|
||||
zone.zoneName = name;
|
||||
zone.captureTime = 5f;
|
||||
zone.pointsPerSecond = 5;
|
||||
zone.currentOwner = CaptureZone.Owner.Neutral;
|
||||
zone.captureProgress = 0.5f;
|
||||
|
||||
GameObject visual = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
|
||||
visual.name = "Visual";
|
||||
visual.transform.SetParent(zoneObject.transform, false);
|
||||
visual.transform.localPosition = Vector3.zero;
|
||||
visual.transform.localScale = new Vector3(6f, 0.035f, 6f);
|
||||
Object.DestroyImmediate(visual.GetComponent<Collider>());
|
||||
|
||||
Renderer renderer = visual.GetComponent<Renderer>();
|
||||
Material runtimeMaterial = new Material(sharedZoneMaterial);
|
||||
runtimeMaterial.name = name + " Runtime Zone Material";
|
||||
renderer.sharedMaterial = runtimeMaterial;
|
||||
zone.zoneRenderer = renderer;
|
||||
|
||||
CreateWorldZoneUI(zoneObject.transform, zone, mainCamera);
|
||||
return zone;
|
||||
}
|
||||
|
||||
private static void CreateWorldZoneUI(Transform parent, CaptureZone zone, Camera mainCamera)
|
||||
{
|
||||
Font font = GetBuiltinFont();
|
||||
|
||||
GameObject canvasObject = new GameObject("World UI");
|
||||
canvasObject.transform.SetParent(parent, false);
|
||||
canvasObject.transform.localPosition = new Vector3(0f, 3f, 0f);
|
||||
canvasObject.transform.localRotation = Quaternion.identity;
|
||||
canvasObject.transform.localScale = Vector3.one * 0.025f;
|
||||
|
||||
Canvas canvas = canvasObject.AddComponent<Canvas>();
|
||||
canvas.renderMode = RenderMode.WorldSpace;
|
||||
canvas.worldCamera = mainCamera;
|
||||
RectTransform canvasRect = canvas.GetComponent<RectTransform>();
|
||||
canvasRect.sizeDelta = new Vector2(220f, 80f);
|
||||
|
||||
canvasObject.AddComponent<GraphicRaycaster>();
|
||||
|
||||
Text label = CreateOverlayText("Label", canvasObject.transform, font, zone.zoneName + ": Neutral", 18, TextAnchor.MiddleCenter);
|
||||
label.color = Color.white;
|
||||
SetRect(label.rectTransform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -18f), new Vector2(220f, 34f));
|
||||
|
||||
Slider slider = CreateWorldSlider(canvasObject.transform, out Image fillImage);
|
||||
slider.value = 0.5f;
|
||||
|
||||
ZoneUI zoneUI = canvasObject.AddComponent<ZoneUI>();
|
||||
zoneUI.zone = zone;
|
||||
zoneUI.progressSlider = slider;
|
||||
zoneUI.labelText = label;
|
||||
zoneUI.fillImage = fillImage;
|
||||
zoneUI.targetCamera = mainCamera;
|
||||
}
|
||||
|
||||
private static Slider CreateWorldSlider(Transform parent, out Image fillImage)
|
||||
{
|
||||
GameObject sliderObject = new GameObject("Progress Slider");
|
||||
sliderObject.transform.SetParent(parent, false);
|
||||
Slider slider = sliderObject.AddComponent<Slider>();
|
||||
RectTransform sliderRect = sliderObject.GetComponent<RectTransform>();
|
||||
SetRect(sliderRect, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 20f), new Vector2(190f, 18f));
|
||||
slider.minValue = 0f;
|
||||
slider.maxValue = 1f;
|
||||
slider.interactable = false;
|
||||
slider.transition = Selectable.Transition.None;
|
||||
|
||||
GameObject backgroundObject = new GameObject("Background");
|
||||
backgroundObject.transform.SetParent(sliderObject.transform, false);
|
||||
Image background = backgroundObject.AddComponent<Image>();
|
||||
background.color = new Color(0f, 0f, 0f, 0.75f);
|
||||
RectTransform backgroundRect = background.GetComponent<RectTransform>();
|
||||
backgroundRect.anchorMin = Vector2.zero;
|
||||
backgroundRect.anchorMax = Vector2.one;
|
||||
backgroundRect.offsetMin = Vector2.zero;
|
||||
backgroundRect.offsetMax = Vector2.zero;
|
||||
|
||||
GameObject fillAreaObject = new GameObject("Fill Area");
|
||||
fillAreaObject.transform.SetParent(sliderObject.transform, false);
|
||||
RectTransform fillAreaRect = fillAreaObject.AddComponent<RectTransform>();
|
||||
fillAreaRect.anchorMin = Vector2.zero;
|
||||
fillAreaRect.anchorMax = Vector2.one;
|
||||
fillAreaRect.offsetMin = new Vector2(2f, 2f);
|
||||
fillAreaRect.offsetMax = new Vector2(-2f, -2f);
|
||||
|
||||
GameObject fillObject = new GameObject("Fill");
|
||||
fillObject.transform.SetParent(fillAreaObject.transform, false);
|
||||
fillImage = fillObject.AddComponent<Image>();
|
||||
fillImage.color = new Color(1f, 0.82f, 0.08f, 1f);
|
||||
RectTransform fillRect = fillImage.GetComponent<RectTransform>();
|
||||
fillRect.anchorMin = Vector2.zero;
|
||||
fillRect.anchorMax = Vector2.one;
|
||||
fillRect.offsetMin = Vector2.zero;
|
||||
fillRect.offsetMax = Vector2.zero;
|
||||
|
||||
slider.fillRect = fillRect;
|
||||
slider.targetGraphic = fillImage;
|
||||
return slider;
|
||||
}
|
||||
|
||||
private static void BakeNavMeshIfAvailable(GameObject ground)
|
||||
{
|
||||
if (ground == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
UnityEditor.AI.NavMeshBuilder.ClearAllNavMeshes();
|
||||
UnityEditor.AI.NavMeshBuilder.BuildNavMesh();
|
||||
}
|
||||
catch (System.Exception exception)
|
||||
{
|
||||
Debug.LogWarning("NavMesh bake was skipped. EnemyAI fallback movement will still work. " + exception.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eb22434d216ca3c32b79d1cc8f4ba469
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69a07a010fd8628149482576272348b2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,267 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!29 &1
|
||||
OcclusionCullingSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_OcclusionBakeSettings:
|
||||
smallestOccluder: 5
|
||||
smallestHole: 0.25
|
||||
backfaceThreshold: 100
|
||||
m_SceneGUID: 00000000000000000000000000000000
|
||||
m_OcclusionCullingData: {fileID: 0}
|
||||
--- !u!104 &2
|
||||
RenderSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 9
|
||||
m_Fog: 0
|
||||
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
|
||||
m_FogMode: 3
|
||||
m_FogDensity: 0.01
|
||||
m_LinearFogStart: 0
|
||||
m_LinearFogEnd: 300
|
||||
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
|
||||
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
|
||||
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
|
||||
m_AmbientIntensity: 1
|
||||
m_AmbientMode: 0
|
||||
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
|
||||
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_HaloStrength: 0.5
|
||||
m_FlareStrength: 1
|
||||
m_FlareFadeSpeed: 3
|
||||
m_HaloTexture: {fileID: 0}
|
||||
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_DefaultReflectionMode: 0
|
||||
m_DefaultReflectionResolution: 128
|
||||
m_ReflectionBounces: 1
|
||||
m_ReflectionIntensity: 1
|
||||
m_CustomReflection: {fileID: 0}
|
||||
m_Sun: {fileID: 705507994}
|
||||
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
m_UseRadianceAmbientProbe: 0
|
||||
--- !u!157 &3
|
||||
LightmapSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 12
|
||||
m_GIWorkflowMode: 1
|
||||
m_GISettings:
|
||||
serializedVersion: 2
|
||||
m_BounceScale: 1
|
||||
m_IndirectOutputScale: 1
|
||||
m_AlbedoBoost: 1
|
||||
m_EnvironmentLightingMode: 0
|
||||
m_EnableBakedLightmaps: 1
|
||||
m_EnableRealtimeLightmaps: 0
|
||||
m_LightmapEditorSettings:
|
||||
serializedVersion: 12
|
||||
m_Resolution: 2
|
||||
m_BakeResolution: 40
|
||||
m_AtlasSize: 1024
|
||||
m_AO: 0
|
||||
m_AOMaxDistance: 1
|
||||
m_CompAOExponent: 1
|
||||
m_CompAOExponentDirect: 0
|
||||
m_ExtractAmbientOcclusion: 0
|
||||
m_Padding: 2
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_LightmapsBakeMode: 1
|
||||
m_TextureCompression: 1
|
||||
m_FinalGather: 0
|
||||
m_FinalGatherFiltering: 1
|
||||
m_FinalGatherRayCount: 256
|
||||
m_ReflectionCompression: 2
|
||||
m_MixedBakeMode: 2
|
||||
m_BakeBackend: 1
|
||||
m_PVRSampling: 1
|
||||
m_PVRDirectSampleCount: 32
|
||||
m_PVRSampleCount: 500
|
||||
m_PVRBounces: 2
|
||||
m_PVREnvironmentSampleCount: 500
|
||||
m_PVREnvironmentReferencePointCount: 2048
|
||||
m_PVRFilteringMode: 2
|
||||
m_PVRDenoiserTypeDirect: 0
|
||||
m_PVRDenoiserTypeIndirect: 0
|
||||
m_PVRDenoiserTypeAO: 0
|
||||
m_PVRFilterTypeDirect: 0
|
||||
m_PVRFilterTypeIndirect: 0
|
||||
m_PVRFilterTypeAO: 0
|
||||
m_PVREnvironmentMIS: 0
|
||||
m_PVRCulling: 1
|
||||
m_PVRFilteringGaussRadiusDirect: 1
|
||||
m_PVRFilteringGaussRadiusIndirect: 5
|
||||
m_PVRFilteringGaussRadiusAO: 2
|
||||
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
|
||||
m_PVRFilteringAtrousPositionSigmaIndirect: 2
|
||||
m_PVRFilteringAtrousPositionSigmaAO: 1
|
||||
m_ExportTrainingData: 0
|
||||
m_TrainingDataDestination: TrainingData
|
||||
m_LightProbeSampleCountMultiplier: 4
|
||||
m_LightingDataAsset: {fileID: 0}
|
||||
m_LightingSettings: {fileID: 0}
|
||||
--- !u!196 &4
|
||||
NavMeshSettings:
|
||||
serializedVersion: 2
|
||||
m_ObjectHideFlags: 0
|
||||
m_BuildSettings:
|
||||
serializedVersion: 2
|
||||
agentTypeID: 0
|
||||
agentRadius: 0.5
|
||||
agentHeight: 2
|
||||
agentSlope: 45
|
||||
agentClimb: 0.4
|
||||
ledgeDropHeight: 0
|
||||
maxJumpAcrossDistance: 0
|
||||
minRegionArea: 2
|
||||
manualCellSize: 0
|
||||
cellSize: 0.16666667
|
||||
manualTileSize: 0
|
||||
tileSize: 256
|
||||
accuratePlacement: 0
|
||||
debug:
|
||||
m_Flags: 0
|
||||
m_NavMeshData: {fileID: 0}
|
||||
--- !u!1 &705507993
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 705507995}
|
||||
- component: {fileID: 705507994}
|
||||
m_Layer: 0
|
||||
m_Name: Directional Light
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!108 &705507994
|
||||
Light:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 705507993}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 8
|
||||
m_Type: 1
|
||||
m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
|
||||
m_Intensity: 1
|
||||
m_Range: 10
|
||||
m_SpotAngle: 30
|
||||
m_CookieSize: 10
|
||||
m_Shadows:
|
||||
m_Type: 2
|
||||
m_Resolution: -1
|
||||
m_CustomResolution: -1
|
||||
m_Strength: 1
|
||||
m_Bias: 0.05
|
||||
m_NormalBias: 0.4
|
||||
m_NearPlane: 0.2
|
||||
m_Cookie: {fileID: 0}
|
||||
m_DrawHalo: 0
|
||||
m_Flare: {fileID: 0}
|
||||
m_RenderMode: 0
|
||||
m_CullingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_Lightmapping: 1
|
||||
m_LightShadowCasterMode: 0
|
||||
m_AreaSize: {x: 1, y: 1}
|
||||
m_BounceIntensity: 1
|
||||
m_ColorTemperature: 6570
|
||||
m_UseColorTemperature: 0
|
||||
m_ShadowRadius: 0
|
||||
m_ShadowAngle: 0
|
||||
--- !u!4 &705507995
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 705507993}
|
||||
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
|
||||
m_LocalPosition: {x: 0, y: 3, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
|
||||
--- !u!1 &963194225
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 963194228}
|
||||
- component: {fileID: 963194227}
|
||||
- component: {fileID: 963194226}
|
||||
m_Layer: 0
|
||||
m_Name: Main Camera
|
||||
m_TagString: MainCamera
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!81 &963194226
|
||||
AudioListener:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 963194225}
|
||||
m_Enabled: 1
|
||||
--- !u!20 &963194227
|
||||
Camera:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 963194225}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 2
|
||||
m_ClearFlags: 1
|
||||
m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
|
||||
m_projectionMatrixMode: 1
|
||||
m_SensorSize: {x: 36, y: 24}
|
||||
m_LensShift: {x: 0, y: 0}
|
||||
m_GateFitMode: 2
|
||||
m_FocalLength: 50
|
||||
m_NormalizedViewPortRect:
|
||||
serializedVersion: 2
|
||||
x: 0
|
||||
y: 0
|
||||
width: 1
|
||||
height: 1
|
||||
near clip plane: 0.3
|
||||
far clip plane: 1000
|
||||
field of view: 60
|
||||
orthographic: 0
|
||||
orthographic size: 5
|
||||
m_Depth: -1
|
||||
m_CullingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
m_RenderingPath: -1
|
||||
m_TargetTexture: {fileID: 0}
|
||||
m_TargetDisplay: 0
|
||||
m_TargetEye: 3
|
||||
m_HDR: 1
|
||||
m_AllowMSAA: 1
|
||||
m_AllowDynamicResolution: 0
|
||||
m_ForceIntoRT: 0
|
||||
m_OcclusionCulling: 1
|
||||
m_StereoConvergence: 10
|
||||
m_StereoSeparation: 0.022
|
||||
--- !u!4 &963194228
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 963194225}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 1, z: -10}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9fc0d4010bbf28b4594072e72b8655ab
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4da91fdbdbc47edb68eb2535a2116546
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,83 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: EnemyRed
|
||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Parent: {fileID: 0}
|
||||
m_ModifiedSerializedProperties: 0
|
||||
m_ValidKeywords: []
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_LockedProperties:
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _Color: {r: 1, g: 0.12, b: 0.08, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
m_BuildTextureStacks: []
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c73dfa3c03cd1383ba83a1275485fa61
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,83 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Ground
|
||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Parent: {fileID: 0}
|
||||
m_ModifiedSerializedProperties: 0
|
||||
m_ValidKeywords: []
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_LockedProperties:
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _Color: {r: 0.25, g: 0.34, b: 0.25, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
m_BuildTextureStacks: []
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e3700fd777def39fb328b85b854c276
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,83 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: PlayerBlue
|
||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Parent: {fileID: 0}
|
||||
m_ModifiedSerializedProperties: 0
|
||||
m_ValidKeywords: []
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_LockedProperties:
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _Color: {r: 0.1, g: 0.35, b: 1, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
m_BuildTextureStacks: []
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 88729d4c833ca6618b5127bec88ff139
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,83 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: Walls
|
||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Parent: {fileID: 0}
|
||||
m_ModifiedSerializedProperties: 0
|
||||
m_ValidKeywords: []
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_LockedProperties:
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _Color: {r: 0.38, g: 0.39, b: 0.42, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
m_BuildTextureStacks: []
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 059a03151f98d5642b51e37f7f7fc232
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,85 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: ZoneTransparent
|
||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Parent: {fileID: 0}
|
||||
m_ModifiedSerializedProperties: 0
|
||||
m_ValidKeywords:
|
||||
- _ALPHABLEND_ON
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: 3000
|
||||
stringTagMap:
|
||||
RenderType: Transparent
|
||||
disabledShaderPasses: []
|
||||
m_LockedProperties:
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 10
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 3
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 5
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 0
|
||||
m_Colors:
|
||||
- _Color: {r: 0.55, g: 0.55, b: 0.55, a: 0.45}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
m_BuildTextureStacks: []
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 761751ecbdfc67a299ae582b945c036c
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e4000455ffc2542dfbe152410528e20c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b68a93597ec40ee62a77c0251734486e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bed4a0624d70f30e49cba9b37aebcd5f
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a35d6aebd713d42d1bbfbc3e2f3b0972
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,313 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
[RequireComponent(typeof(SphereCollider))]
|
||||
public class CaptureZone : MonoBehaviour
|
||||
{
|
||||
public enum Owner
|
||||
{
|
||||
Neutral,
|
||||
Player,
|
||||
Enemy
|
||||
}
|
||||
|
||||
public enum CaptureState
|
||||
{
|
||||
Neutral,
|
||||
CapturingByPlayer,
|
||||
CapturedByPlayer,
|
||||
CapturingByEnemy,
|
||||
CapturedByEnemy,
|
||||
Contested
|
||||
}
|
||||
|
||||
[Header("Identity")]
|
||||
public string zoneName = "Zone";
|
||||
|
||||
[Header("Capture")]
|
||||
public Owner currentOwner = Owner.Neutral;
|
||||
[Range(0f, 1f)] public float captureProgress = 0.5f;
|
||||
public float captureTime = 5f;
|
||||
public int playersInside;
|
||||
public int enemiesInside;
|
||||
public int pointsPerSecond = 5;
|
||||
|
||||
[Header("Visuals")]
|
||||
public Renderer zoneRenderer;
|
||||
public Color neutralColor = new Color(0.55f, 0.55f, 0.55f, 0.45f);
|
||||
public Color playerColor = new Color(0.1f, 0.35f, 1f, 0.55f);
|
||||
public Color enemyColor = new Color(1f, 0.12f, 0.08f, 0.55f);
|
||||
public Color contestedColor = new Color(1f, 0.82f, 0.05f, 0.65f);
|
||||
|
||||
public event Action<CaptureZone> onCapturedByPlayer;
|
||||
public event Action<CaptureZone> onCapturedByEnemy;
|
||||
|
||||
private Owner lastNotifiedOwner;
|
||||
private Vector3 baseScale;
|
||||
private float pulseTimer;
|
||||
private float scoreTimer;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
SphereCollider trigger = GetComponent<SphereCollider>();
|
||||
trigger.isTrigger = true;
|
||||
|
||||
lastNotifiedOwner = currentOwner;
|
||||
baseScale = transform.localScale;
|
||||
ApplyOwnerProgress(currentOwner);
|
||||
UpdateVisual();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
UpdateCaptureProgress();
|
||||
TickScoreIncome();
|
||||
UpdateVisual();
|
||||
UpdateCapturePulse();
|
||||
}
|
||||
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
if (other.CompareTag("Player"))
|
||||
{
|
||||
playersInside++;
|
||||
}
|
||||
else if (other.CompareTag("Enemy"))
|
||||
{
|
||||
enemiesInside++;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTriggerExit(Collider other)
|
||||
{
|
||||
if (other.CompareTag("Player"))
|
||||
{
|
||||
playersInside = Mathf.Max(0, playersInside - 1);
|
||||
}
|
||||
else if (other.CompareTag("Enemy"))
|
||||
{
|
||||
enemiesInside = Mathf.Max(0, enemiesInside - 1);
|
||||
}
|
||||
}
|
||||
|
||||
public float GetProgress()
|
||||
{
|
||||
return captureProgress;
|
||||
}
|
||||
|
||||
public Owner GetOwner()
|
||||
{
|
||||
return currentOwner;
|
||||
}
|
||||
|
||||
public string GetStateLabel()
|
||||
{
|
||||
switch (GetCaptureState())
|
||||
{
|
||||
case CaptureState.CapturingByPlayer:
|
||||
return "Capturing by Player";
|
||||
case CaptureState.CapturedByPlayer:
|
||||
return "Player";
|
||||
case CaptureState.CapturingByEnemy:
|
||||
return "Capturing by Enemy";
|
||||
case CaptureState.CapturedByEnemy:
|
||||
return "Enemy";
|
||||
case CaptureState.Contested:
|
||||
return "Contested";
|
||||
default:
|
||||
return "Neutral";
|
||||
}
|
||||
}
|
||||
|
||||
public CaptureState GetCaptureState()
|
||||
{
|
||||
bool hasPlayer = playersInside > 0;
|
||||
bool hasEnemy = enemiesInside > 0;
|
||||
|
||||
if (hasPlayer && hasEnemy)
|
||||
{
|
||||
return CaptureState.Contested;
|
||||
}
|
||||
|
||||
if (hasPlayer && currentOwner != Owner.Player)
|
||||
{
|
||||
return CaptureState.CapturingByPlayer;
|
||||
}
|
||||
|
||||
if (hasEnemy && currentOwner != Owner.Enemy)
|
||||
{
|
||||
return CaptureState.CapturingByEnemy;
|
||||
}
|
||||
|
||||
if (currentOwner == Owner.Player)
|
||||
{
|
||||
return CaptureState.CapturedByPlayer;
|
||||
}
|
||||
|
||||
if (currentOwner == Owner.Enemy)
|
||||
{
|
||||
return CaptureState.CapturedByEnemy;
|
||||
}
|
||||
|
||||
return CaptureState.Neutral;
|
||||
}
|
||||
|
||||
public void ForceSetOwner(Owner owner)
|
||||
{
|
||||
SetOwner(owner, true);
|
||||
}
|
||||
|
||||
private void UpdateCaptureProgress()
|
||||
{
|
||||
bool hasPlayer = playersInside > 0;
|
||||
bool hasEnemy = enemiesInside > 0;
|
||||
|
||||
// Спорная зона замораживает прогресс, чтобы игрок видел механику contest.
|
||||
if (hasPlayer == hasEnemy)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float step = Time.deltaTime / Mathf.Max(0.1f, captureTime);
|
||||
|
||||
if (hasPlayer)
|
||||
{
|
||||
captureProgress = Mathf.MoveTowards(captureProgress, 1f, step);
|
||||
if (Mathf.Approximately(captureProgress, 1f))
|
||||
{
|
||||
SetOwner(Owner.Player, false);
|
||||
}
|
||||
}
|
||||
else if (hasEnemy)
|
||||
{
|
||||
captureProgress = Mathf.MoveTowards(captureProgress, 0f, step);
|
||||
if (Mathf.Approximately(captureProgress, 0f))
|
||||
{
|
||||
SetOwner(Owner.Enemy, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void TickScoreIncome()
|
||||
{
|
||||
if (currentOwner == Owner.Neutral || ResourceManager.Instance == null)
|
||||
{
|
||||
scoreTimer = 0f;
|
||||
return;
|
||||
}
|
||||
|
||||
scoreTimer += Time.deltaTime;
|
||||
if (scoreTimer < 1f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int ticks = Mathf.FloorToInt(scoreTimer);
|
||||
scoreTimer -= ticks;
|
||||
int amount = pointsPerSecond * ticks;
|
||||
|
||||
if (currentOwner == Owner.Player)
|
||||
{
|
||||
ResourceManager.Instance.AddPlayerPoints(amount);
|
||||
}
|
||||
else if (currentOwner == Owner.Enemy)
|
||||
{
|
||||
ResourceManager.Instance.AddEnemyPoints(amount);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetOwner(Owner owner, bool forceNotify)
|
||||
{
|
||||
if (currentOwner == owner && !forceNotify)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Owner previousOwner = currentOwner;
|
||||
currentOwner = owner;
|
||||
ApplyOwnerProgress(owner);
|
||||
pulseTimer = 0.25f;
|
||||
|
||||
if (previousOwner == owner && !forceNotify)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (lastNotifiedOwner != currentOwner || forceNotify)
|
||||
{
|
||||
lastNotifiedOwner = currentOwner;
|
||||
|
||||
if (currentOwner == Owner.Player)
|
||||
{
|
||||
onCapturedByPlayer?.Invoke(this);
|
||||
}
|
||||
else if (currentOwner == Owner.Enemy)
|
||||
{
|
||||
onCapturedByEnemy?.Invoke(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyOwnerProgress(Owner owner)
|
||||
{
|
||||
if (owner == Owner.Player)
|
||||
{
|
||||
captureProgress = 1f;
|
||||
}
|
||||
else if (owner == Owner.Enemy)
|
||||
{
|
||||
captureProgress = 0f;
|
||||
}
|
||||
else if (Mathf.Approximately(captureProgress, 0f) || Mathf.Approximately(captureProgress, 1f))
|
||||
{
|
||||
captureProgress = 0.5f;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateVisual()
|
||||
{
|
||||
if (zoneRenderer == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Color color = GetVisualColor();
|
||||
zoneRenderer.material.color = color;
|
||||
}
|
||||
|
||||
private Color GetVisualColor()
|
||||
{
|
||||
CaptureState state = GetCaptureState();
|
||||
if (state == CaptureState.Contested || state == CaptureState.CapturingByPlayer || state == CaptureState.CapturingByEnemy)
|
||||
{
|
||||
float pulse = Mathf.Lerp(0.75f, 1f, Mathf.PingPong(Time.time * 3f, 1f));
|
||||
return contestedColor * pulse;
|
||||
}
|
||||
|
||||
if (currentOwner == Owner.Player)
|
||||
{
|
||||
return playerColor;
|
||||
}
|
||||
|
||||
if (currentOwner == Owner.Enemy)
|
||||
{
|
||||
return enemyColor;
|
||||
}
|
||||
|
||||
return neutralColor;
|
||||
}
|
||||
|
||||
private void UpdateCapturePulse()
|
||||
{
|
||||
if (pulseTimer <= 0f)
|
||||
{
|
||||
transform.localScale = baseScale;
|
||||
return;
|
||||
}
|
||||
|
||||
pulseTimer -= Time.deltaTime;
|
||||
float t = Mathf.Clamp01(pulseTimer / 0.25f);
|
||||
float scale = 1f + Mathf.Sin(t * Mathf.PI) * 0.12f;
|
||||
transform.localScale = baseScale * scale;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f3db71fa977ba6416b4d4c8af7de96a0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,164 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
|
||||
[RequireComponent(typeof(CharacterController))]
|
||||
public class EnemyAI : MonoBehaviour
|
||||
{
|
||||
public CaptureZone[] zones;
|
||||
public float moveSpeed = 3.5f;
|
||||
public float retargetInterval = 2f;
|
||||
public float stoppingDistance = 0.7f;
|
||||
public float randomFactor = 4f;
|
||||
|
||||
private CharacterController characterController;
|
||||
private NavMeshAgent navMeshAgent;
|
||||
private CaptureZone targetZone;
|
||||
private Vector3 targetOffset;
|
||||
private float retargetTimer;
|
||||
private Vector3 verticalVelocity;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
characterController = GetComponent<CharacterController>();
|
||||
navMeshAgent = GetComponent<NavMeshAgent>();
|
||||
|
||||
if (navMeshAgent != null)
|
||||
{
|
||||
navMeshAgent.speed = moveSpeed;
|
||||
navMeshAgent.stoppingDistance = stoppingDistance;
|
||||
}
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
ChooseTarget();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
retargetTimer -= Time.deltaTime;
|
||||
|
||||
if (targetZone == null || targetZone.GetOwner() == CaptureZone.Owner.Enemy || retargetTimer <= 0f)
|
||||
{
|
||||
ChooseTarget();
|
||||
}
|
||||
|
||||
MoveToTarget();
|
||||
}
|
||||
|
||||
private void ChooseTarget()
|
||||
{
|
||||
retargetTimer = retargetInterval + Random.Range(0f, 0.75f);
|
||||
targetZone = null;
|
||||
|
||||
CaptureZone bestPlayerZone = FindBestZone(CaptureZone.Owner.Player);
|
||||
if (bestPlayerZone != null)
|
||||
{
|
||||
SetTarget(bestPlayerZone);
|
||||
return;
|
||||
}
|
||||
|
||||
CaptureZone bestNeutralZone = FindBestZone(CaptureZone.Owner.Neutral);
|
||||
if (bestNeutralZone != null)
|
||||
{
|
||||
SetTarget(bestNeutralZone);
|
||||
}
|
||||
}
|
||||
|
||||
private CaptureZone FindBestZone(CaptureZone.Owner owner)
|
||||
{
|
||||
if (zones == null || zones.Length == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
CaptureZone best = null;
|
||||
float bestScore = float.MaxValue;
|
||||
|
||||
for (int i = 0; i < zones.Length; i++)
|
||||
{
|
||||
CaptureZone zone = zones[i];
|
||||
if (zone == null || zone.GetOwner() != owner)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
float distance = Vector3.Distance(transform.position, zone.transform.position);
|
||||
float score = distance + Random.Range(0f, randomFactor);
|
||||
if (score < bestScore)
|
||||
{
|
||||
bestScore = score;
|
||||
best = zone;
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
private void SetTarget(CaptureZone zone)
|
||||
{
|
||||
targetZone = zone;
|
||||
Vector2 randomCircle = Random.insideUnitCircle * 1.5f;
|
||||
targetOffset = new Vector3(randomCircle.x, 0f, randomCircle.y);
|
||||
|
||||
if (CanUseNavMeshAgent())
|
||||
{
|
||||
navMeshAgent.SetDestination(GetTargetPosition());
|
||||
}
|
||||
}
|
||||
|
||||
private void MoveToTarget()
|
||||
{
|
||||
if (targetZone == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 targetPosition = GetTargetPosition();
|
||||
|
||||
if (CanUseNavMeshAgent())
|
||||
{
|
||||
if (!navMeshAgent.hasPath || Vector3.Distance(navMeshAgent.destination, targetPosition) > 0.5f)
|
||||
{
|
||||
navMeshAgent.SetDestination(targetPosition);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 direction = targetPosition - transform.position;
|
||||
direction.y = 0f;
|
||||
|
||||
if (direction.magnitude <= stoppingDistance)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 horizontalMove = direction.normalized * moveSpeed;
|
||||
if (characterController.isGrounded && verticalVelocity.y < 0f)
|
||||
{
|
||||
verticalVelocity.y = -1f;
|
||||
}
|
||||
|
||||
verticalVelocity.y += Physics.gravity.y * Time.deltaTime;
|
||||
characterController.Move((horizontalMove + verticalVelocity) * Time.deltaTime);
|
||||
|
||||
if (horizontalMove.sqrMagnitude > 0.001f)
|
||||
{
|
||||
transform.rotation = Quaternion.LookRotation(horizontalMove.normalized, Vector3.up);
|
||||
}
|
||||
}
|
||||
|
||||
private Vector3 GetTargetPosition()
|
||||
{
|
||||
return targetZone.transform.position + targetOffset;
|
||||
}
|
||||
|
||||
private bool CanUseNavMeshAgent()
|
||||
{
|
||||
return navMeshAgent != null &&
|
||||
navMeshAgent.enabled &&
|
||||
navMeshAgent.isActiveAndEnabled &&
|
||||
navMeshAgent.isOnNavMesh;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 84755881e5af5195ea4faf7db39fdb29
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,153 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class GameManager : MonoBehaviour
|
||||
{
|
||||
public CaptureZone[] zones;
|
||||
public TerritoryUI territoryUI;
|
||||
public GameObject winPanel;
|
||||
public Text winText;
|
||||
public int scoreLimit = 100;
|
||||
|
||||
private bool gameOver;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
Time.timeScale = 1f;
|
||||
|
||||
if (territoryUI != null)
|
||||
{
|
||||
territoryUI.HideGameOver();
|
||||
}
|
||||
|
||||
SubscribeToZones();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (gameOver)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (territoryUI != null)
|
||||
{
|
||||
territoryUI.UpdateZoneStatus(zones);
|
||||
}
|
||||
|
||||
CheckVictoryConditions();
|
||||
}
|
||||
|
||||
private void SubscribeToZones()
|
||||
{
|
||||
if (zones == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < zones.Length; i++)
|
||||
{
|
||||
if (zones[i] == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
zones[i].onCapturedByPlayer += OnZoneCaptured;
|
||||
zones[i].onCapturedByEnemy += OnZoneCaptured;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (zones == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < zones.Length; i++)
|
||||
{
|
||||
if (zones[i] == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
zones[i].onCapturedByPlayer -= OnZoneCaptured;
|
||||
zones[i].onCapturedByEnemy -= OnZoneCaptured;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnZoneCaptured(CaptureZone zone)
|
||||
{
|
||||
CheckVictoryConditions();
|
||||
}
|
||||
|
||||
private void CheckVictoryConditions()
|
||||
{
|
||||
if (zones == null || zones.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool allPlayer = true;
|
||||
bool allEnemy = true;
|
||||
|
||||
for (int i = 0; i < zones.Length; i++)
|
||||
{
|
||||
if (zones[i] == null)
|
||||
{
|
||||
allPlayer = false;
|
||||
allEnemy = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
allPlayer &= zones[i].GetOwner() == CaptureZone.Owner.Player;
|
||||
allEnemy &= zones[i].GetOwner() == CaptureZone.Owner.Enemy;
|
||||
}
|
||||
|
||||
if (allPlayer)
|
||||
{
|
||||
GameOver("Победа игрока: все зоны захвачены!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (allEnemy)
|
||||
{
|
||||
GameOver("Победа врага: все зоны потеряны!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ResourceManager.Instance != null && ResourceManager.Instance.playerScore >= scoreLimit)
|
||||
{
|
||||
GameOver("Победа игрока: достигнут лимит очков!");
|
||||
}
|
||||
}
|
||||
|
||||
private void GameOver(string message)
|
||||
{
|
||||
if (gameOver)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gameOver = true;
|
||||
|
||||
if (territoryUI != null)
|
||||
{
|
||||
territoryUI.ShowGameOver(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (winPanel != null)
|
||||
{
|
||||
winPanel.SetActive(true);
|
||||
}
|
||||
|
||||
if (winText != null)
|
||||
{
|
||||
winText.text = message;
|
||||
}
|
||||
}
|
||||
|
||||
Time.timeScale = 0f;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 333c0b0a17a11865b8bced65a4497db2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,43 @@
|
||||
using UnityEngine;
|
||||
|
||||
[RequireComponent(typeof(CharacterController))]
|
||||
public class PlayerController : MonoBehaviour
|
||||
{
|
||||
[Header("Movement")]
|
||||
public float moveSpeed = 6f;
|
||||
public float gravity = -20f;
|
||||
|
||||
private CharacterController characterController;
|
||||
private Vector3 verticalVelocity;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
characterController = GetComponent<CharacterController>();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
float horizontal = Input.GetAxisRaw("Horizontal");
|
||||
float vertical = Input.GetAxisRaw("Vertical");
|
||||
|
||||
Vector3 input = new Vector3(horizontal, 0f, vertical);
|
||||
input = Vector3.ClampMagnitude(input, 1f);
|
||||
|
||||
Vector3 move = input * moveSpeed;
|
||||
|
||||
if (characterController.isGrounded && verticalVelocity.y < 0f)
|
||||
{
|
||||
verticalVelocity.y = -1f;
|
||||
}
|
||||
|
||||
verticalVelocity.y += gravity * Time.deltaTime;
|
||||
move += verticalVelocity;
|
||||
|
||||
characterController.Move(move * Time.deltaTime);
|
||||
|
||||
if (input.sqrMagnitude > 0.001f)
|
||||
{
|
||||
transform.rotation = Quaternion.LookRotation(input, Vector3.up);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 853685d0012a45352a9b673f28614946
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,60 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class ResourceManager : MonoBehaviour
|
||||
{
|
||||
public static ResourceManager Instance { get; private set; }
|
||||
|
||||
public int playerScore;
|
||||
public int enemyScore;
|
||||
|
||||
public Text pointsText;
|
||||
public Text enemyPointsText;
|
||||
public TerritoryUI territoryUI;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance != null && Instance != this)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
UpdateScoreUI();
|
||||
}
|
||||
|
||||
public void AddPlayerPoints(int amount)
|
||||
{
|
||||
playerScore += Mathf.Max(0, amount);
|
||||
UpdateScoreUI();
|
||||
}
|
||||
|
||||
public void AddEnemyPoints(int amount)
|
||||
{
|
||||
enemyScore += Mathf.Max(0, amount);
|
||||
UpdateScoreUI();
|
||||
}
|
||||
|
||||
private void UpdateScoreUI()
|
||||
{
|
||||
if (pointsText != null)
|
||||
{
|
||||
pointsText.text = "Player Points: " + playerScore;
|
||||
}
|
||||
|
||||
if (enemyPointsText != null)
|
||||
{
|
||||
enemyPointsText.text = "Enemy Points: " + enemyScore;
|
||||
}
|
||||
|
||||
if (territoryUI != null)
|
||||
{
|
||||
territoryUI.SetScore(playerScore, enemyScore);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bebf81aaa988aac5487915a1a02b5bed
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,81 @@
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class TerritoryUI : MonoBehaviour
|
||||
{
|
||||
public Text playerPointsText;
|
||||
public Text enemyPointsText;
|
||||
public Text zoneStatusText;
|
||||
public GameObject winPanel;
|
||||
public Text winText;
|
||||
|
||||
private readonly StringBuilder zoneStatusBuilder = new StringBuilder();
|
||||
|
||||
public void UpdateZoneStatus(CaptureZone[] zones)
|
||||
{
|
||||
if (zoneStatusText == null || zones == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
zoneStatusBuilder.Length = 0;
|
||||
for (int i = 0; i < zones.Length; i++)
|
||||
{
|
||||
CaptureZone zone = zones[i];
|
||||
if (zone == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int percent = Mathf.RoundToInt(zone.GetProgress() * 100f);
|
||||
zoneStatusBuilder.Append(zone.zoneName)
|
||||
.Append(": ")
|
||||
.Append(zone.GetOwner())
|
||||
.Append(", ")
|
||||
.Append(percent)
|
||||
.Append('%');
|
||||
|
||||
if (i < zones.Length - 1)
|
||||
{
|
||||
zoneStatusBuilder.AppendLine();
|
||||
}
|
||||
}
|
||||
|
||||
zoneStatusText.text = zoneStatusBuilder.ToString();
|
||||
}
|
||||
|
||||
public void ShowGameOver(string message)
|
||||
{
|
||||
if (winPanel != null)
|
||||
{
|
||||
winPanel.SetActive(true);
|
||||
}
|
||||
|
||||
if (winText != null)
|
||||
{
|
||||
winText.text = message;
|
||||
}
|
||||
}
|
||||
|
||||
public void HideGameOver()
|
||||
{
|
||||
if (winPanel != null)
|
||||
{
|
||||
winPanel.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetScore(int playerScore, int enemyScore)
|
||||
{
|
||||
if (playerPointsText != null)
|
||||
{
|
||||
playerPointsText.text = "Player Points: " + playerScore;
|
||||
}
|
||||
|
||||
if (enemyPointsText != null)
|
||||
{
|
||||
enemyPointsText.text = "Enemy Points: " + enemyScore;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 49dcf13b53d69fbb9b2208d2160e6de5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,70 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class ZoneUI : MonoBehaviour
|
||||
{
|
||||
public CaptureZone zone;
|
||||
public Slider progressSlider;
|
||||
public Text labelText;
|
||||
public Image fillImage;
|
||||
public Camera targetCamera;
|
||||
|
||||
public Color neutralColor = Color.gray;
|
||||
public Color playerColor = new Color(0.2f, 0.45f, 1f);
|
||||
public Color enemyColor = new Color(1f, 0.2f, 0.15f);
|
||||
public Color contestedColor = new Color(1f, 0.82f, 0.08f);
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
if (zone == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (progressSlider != null)
|
||||
{
|
||||
progressSlider.value = zone.GetProgress();
|
||||
}
|
||||
|
||||
Color color = GetColorForZone();
|
||||
if (fillImage != null)
|
||||
{
|
||||
fillImage.color = color;
|
||||
}
|
||||
|
||||
if (labelText != null)
|
||||
{
|
||||
labelText.text = zone.zoneName + ": " + zone.GetOwner();
|
||||
labelText.color = color;
|
||||
}
|
||||
|
||||
Camera cameraToUse = targetCamera != null ? targetCamera : Camera.main;
|
||||
if (cameraToUse != null)
|
||||
{
|
||||
transform.rotation = Quaternion.LookRotation(transform.position - cameraToUse.transform.position, Vector3.up);
|
||||
}
|
||||
}
|
||||
|
||||
private Color GetColorForZone()
|
||||
{
|
||||
CaptureZone.CaptureState state = zone.GetCaptureState();
|
||||
if (state == CaptureZone.CaptureState.Contested ||
|
||||
state == CaptureZone.CaptureState.CapturingByPlayer ||
|
||||
state == CaptureZone.CaptureState.CapturingByEnemy)
|
||||
{
|
||||
return contestedColor;
|
||||
}
|
||||
|
||||
if (zone.GetOwner() == CaptureZone.Owner.Player)
|
||||
{
|
||||
return playerColor;
|
||||
}
|
||||
|
||||
if (zone.GetOwner() == CaptureZone.Owner.Enemy)
|
||||
{
|
||||
return enemyColor;
|
||||
}
|
||||
|
||||
return neutralColor;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 245f8e31fc2a8036db5d5bf4201e986a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user