init commit

This commit is contained in:
2026-04-30 12:04:09 +03:00
commit 8bd50d5e52
1714 changed files with 355124 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 935a3af4c5fcb7c4b888179a16d74670
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,107 @@
using TMPro;
using UnityEngine;
[RequireComponent(typeof(CharacterController))]
public class AmyRunScript : MonoBehaviour
{
[Header("Amy Properties")]
public float runSpeed = 10f;
public float runSpeedOnRadiusOffset = 100f;
public float angle = 0f;
public float startAngle = 0f;
public TMP_Text speedText;
private CharacterController characterController;
private Animator animator;
private bool isRunning = false;
[Header("Runline")]
public RunlinePlacer runline;
private void Awake()
{
characterController = GetComponent<CharacterController>();
animator = GetComponent<Animator>();
}
void Start()
{
SetAmyRandomSpeed();
}
void Update()
{
if (!gameObject.activeSelf) return;
if(isRunning) MoveAmyOnTrack();
animator.SetBool("isRunning", isRunning);
}
private void MoveAmyOnTrack()
{
angle += (runSpeed / runSpeedOnRadiusOffset) * Time.deltaTime;
float x = Mathf.Cos(angle) * runline.radiusX;
float z = Mathf.Sin(angle) * runline.radiusZ;
Vector3 targetPos = new Vector3(x, runline.center.y, z);
Vector3 direction = targetPos - transform.position;
characterController.Move(direction);
if (direction != Vector3.zero)
{
transform.rotation = Quaternion.LookRotation(direction);
}
}
public void StartRun()
{
isRunning = true;
}
public void StopRun()
{
isRunning = false;
}
public void SetAngle(float newAngle)
{
angle = newAngle;
MoveAmyOnTrack();
StopRun();
}
public void PlaceOnStartAngle()
{
angle = startAngle;
transform.rotation = new Quaternion(0f, transform.rotation.y, transform.rotation.z, 0f);
SetSpeedText();
MoveAmyOnTrack();
StopRun();
}
[ContextMenu("Set Amy random speed")]
public void SetAmyRandomSpeed()
{
runSpeed = Random.Range(8, 15);
}
private void OnTriggerEnter(Collider collider)
{
if (collider.gameObject.tag == "Endline" && Lesson1Controller.Instance.activeExperiment == 2) ExperimentChooser.Instance.experiment3Button.interactable = true;
}
private void SetSpeedText()
{
if (Lesson1Controller.Instance.activeExperiment != 2)
{
speedText.text = "SPEED: " + runSpeed.ToString();
}
else
{
speedText.text = "";
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a7e7a0b02bdc64641a22e1a69e1c073c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,35 @@
using UnityEngine;
[RequireComponent (typeof(Terrain))]
public class ApplyDissolveShaderToTerrain : MonoBehaviour
{
public Terrain terrain;
public float dissolveAmount = 0f;
public Shader shader;
private Material originalMaterial;
private Material overrideMaterial;
void Start()
{
terrain = GetComponent<Terrain>();
overrideMaterial = new Material(shader);
originalMaterial = terrain.materialTemplate;
SetOriginalMaterial();
}
private void Update()
{
terrain.materialTemplate.SetFloat("_dissolveAmount", dissolveAmount);
}
public void SetOriginalMaterial()
{
terrain.materialTemplate = originalMaterial;
}
public void SetOverrideMaterial()
{
terrain.materialTemplate = overrideMaterial;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 421c37adf7a9c7d48abfd35f612c44a5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,79 @@
using UnityEngine;
[RequireComponent(typeof(LineRenderer))]
public class DrawDistanceLine : MonoBehaviour
{
private float radiusX;
private float radiusZ;
private float startAngle;
private float endAngle;
[Header("ßê³ñòü äóãè")]
public int segments = 50;
[Header("Öåíòð äóãè")]
private Vector3 center;
[Header("²íôîðìàö³ÿ (ò³ëüêè äëÿ ÷èòàííÿ)")]
[SerializeField] private float arcLength = 0f;
private LineRenderer lineRenderer;
void Start()
{
radiusX = GetComponent<RunlinePlacer>().radiusX;
radiusZ = GetComponent<RunlinePlacer>().radiusZ;
center = GetComponent<RunlinePlacer>().center;
lineRenderer = GetComponent<LineRenderer>();
lineRenderer.startColor = new Color(1f, 1f, 1f);
lineRenderer.endColor = new Color(1f, 1f, 1f);
lineRenderer.startWidth = 1f;
lineRenderer.endWidth = 1f;
lineRenderer.useWorldSpace = true;
lineRenderer.material = new Material(Shader.Find("Sprites/Default"));
}
public void DrawDistanceArc()
{
startAngle = GetComponent<RunlinePlacer>().GetStartLineAngle();
endAngle = GetComponent<RunlinePlacer>().GetEndLineAngle();
if (startAngle > endAngle) endAngle += 2 * Mathf.PI;
lineRenderer.positionCount = segments + 1;
float angleStep = (endAngle - startAngle) / segments;
Vector3 prevPos = Vector3.zero;
arcLength = 0f;
for (int i = 0; i <= segments; i++)
{
float angle = startAngle + i * angleStep;
float x = Mathf.Cos(angle) * radiusX;
float z = Mathf.Sin(angle) * radiusZ;
lineRenderer.SetPosition(i, new Vector3(x, 0f, z));
Vector3 pos = new Vector3(x, 0f, z) + center;
if (i > 0)
arcLength += Vector3.Distance(pos, prevPos);
prevPos = pos;
}
GameObject startLine = GetComponent<RunlinePlacer>().GetStartLineGameObject();
startLine.GetComponent<LineData>().SetDistanceText((int)arcLength);
ClearArc();
}
public void ClearArc()
{
if (lineRenderer != null)
{
lineRenderer.positionCount = 0;
arcLength = 0f;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1f63d66c47f906544a6eee6ccb3a8a79
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,106 @@
using UnityEngine;
using UnityEngine.UI;
public class ExperimentChooser : MonoBehaviour
{
public static ExperimentChooser Instance { get; private set; }
public Button experiment1Button;
public Button experiment2Button;
public Button experiment3Button;
[Header("All Experiments Objects")]
public RunlinePlacer runlinePlacer;
public TransitionSphere transitionSphere;
public Transform spawnPoint;
public Transform player;
public GameObject runTrack;
public GameObject amy;
[Header("First Experiment")]
public Stopwatch stopwatch;
private void Awake()
{
if (Instance == null)
{
Instance = this;
}
else if (Instance != this)
{
Destroy(gameObject);
}
}
private void Start()
{
experiment1Button.interactable = true;
experiment2Button.interactable = false;
experiment3Button.interactable = false;
experiment1Button.onClick.AddListener(StartExperiment1);
experiment2Button.onClick.AddListener(StartExperiment2);
experiment3Button.onClick.AddListener(StartExperiment3);
}
private void StartExperiment1()
{
player.position = spawnPoint.position + Vector3.up * 2f;
transitionSphere.PlayAnimation();
runTrack.SetActive(true);
amy.SetActive(true);
runlinePlacer.gameObject.SetActive(true);
player.gameObject.GetComponent<PlayerMovement>().SetPlayerEarthSpeed();
Lesson1Controller.Instance.SetForestSkybox();
experiment1Button.interactable = false;
if (Lesson1Controller.Instance.activeExperiment == 2) experiment2Button.interactable = true;
if (Lesson1Controller.Instance.activeExperiment == 3)
{
experiment2Button.interactable = true;
experiment3Button.interactable = true;
}
Lesson1Controller.Instance.activeExperiment = 1;
stopwatch.isCounting = false;
stopwatch.arrow.transform.localRotation = stopwatch.arrowStartRotation;
runlinePlacer.RuntimePlace();
}
private void StartExperiment2()
{
player.position = spawnPoint.position + Vector3.up * 2f;
transitionSphere.PlayAnimation();
runTrack.SetActive(true);
runlinePlacer.gameObject.SetActive(true);
amy.SetActive(true);
player.gameObject.GetComponent<PlayerMovement>().SetPlayerEarthSpeed();
Lesson1Controller.Instance.SetForestSkybox();
experiment1Button.interactable = true;
experiment2Button.interactable = false;
if (Lesson1Controller.Instance.activeExperiment == 3) experiment3Button.interactable = true;
Lesson1Controller.Instance.activeExperiment = 2;
stopwatch.isCounting = false;
stopwatch.arrow.transform.localRotation = stopwatch.arrowStartRotation;
runlinePlacer.RuntimePlace();
}
private void StartExperiment3()
{
player.position = spawnPoint.position + Vector3.up * 2f;
transitionSphere.PlayAnimation();
runTrack.SetActive(false);
amy.SetActive(false);
runlinePlacer.RuntimePlace();
runlinePlacer.gameObject.SetActive(false);
player.gameObject.GetComponent<PlayerMovement>().SetPlayerLunarSpeed();
Lesson1Controller.Instance.SetLunarSkybox();
experiment1Button.interactable = true;
experiment2Button.interactable = true;
experiment3Button.interactable = false;
Lesson1Controller.Instance.activeExperiment = 3;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 35ab8365be20aad40aaf611552542795
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,65 @@
using UnityEngine;
using UnityEngine.Rendering;
public class GPUGrassRenderer : MonoBehaviour
{
public Mesh grassMesh; // îäíà ìîäåëü òðàâèíêè (îäèí submesh)
public Material grassMaterial; // shader ìຠï³äòðèìóâàòè GPU instancing
public ComputeShader computeShader;
public int countX = 256;
public int countZ = 256;
public float sizeX = 50f;
public float sizeZ = 50f;
public float height = 0f;
GraphicsBuffer matricesBuffer;
GraphicsBuffer argsBuffer;
int totalCount;
void Start()
{
totalCount = countX * countZ;
// 1) create structured buffer for matrices (float4x4 = 16 floats = 64 bytes)
matricesBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, totalCount, 16 * sizeof(float));
// 2) args buffer (5 uints): indexCountPerInstance, instanceCount, startIndexLocation, baseVertexLocation, startInstanceLocation
uint[] args = new uint[5] { (uint)grassMesh.GetIndexCount(0), (uint)totalCount, (uint)grassMesh.GetIndexStart(0), (uint)grassMesh.GetBaseVertex(0), 0u };
argsBuffer = new GraphicsBuffer(GraphicsBuffer.Target.IndirectArguments, 1, sizeof(uint) * args.Length);
argsBuffer.SetData(args);
// dispatch compute to fill matrices
int kernel = computeShader.FindKernel("CSMain");
computeShader.SetInt("_CountX", countX);
computeShader.SetInt("_CountZ", countZ);
computeShader.SetFloat("_SizeX", sizeX);
computeShader.SetFloat("_SizeZ", sizeZ);
computeShader.SetFloat("_Height", height);
computeShader.SetBuffer(kernel, "matrices", matricesBuffer);
int threadGroups = Mathf.CeilToInt(totalCount / 64.0f);
computeShader.Dispatch(kernel, threadGroups, 1, 1);
// bind buffer to material for per-instance matrix access (if shader reads it)
grassMaterial.SetBuffer("matrices", matricesBuffer);
}
void OnDisable()
{
matricesBuffer?.Dispose();
argsBuffer?.Dispose();
}
void Update()
{
// set render params: use simple bounds so Unity can cull
var bounds = new Bounds(transform.position, new Vector3(sizeX, 10f, sizeZ));
RenderParams rparams = new RenderParams(grassMaterial);
// the shader must use UNITY_INDIRECT_DRAW_ARGS / UnityIndirect.cginc if it needs instance id access
// call indirect draw
rparams.worldBounds = new Bounds(transform.position, new Vector3(sizeX, 10f, sizeZ));
Graphics.RenderMeshIndirect(rparams, grassMesh, argsBuffer);
// parameters: rparams, mesh, argsBuffer, commandCount=1, startCommand=0, worldBounds
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 43221c50bf4e7fc4d90d52e26a82046a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,41 @@
using UnityEngine;
public class Lesson1Controller : MonoBehaviour
{
public static Lesson1Controller Instance { get; private set; }
public float activeExperiment = 0;
public Material forestSkybox;
public Material lunarSkybox;
public GameObject forestEnvironment;
public GameObject lunarEnvironment;
void Awake()
{
if (Instance == null)
{
Instance = this;
}
else if (Instance != this)
{
Destroy(gameObject);
}
}
public void SetForestSkybox()
{
RenderSettings.skybox = forestSkybox;
forestEnvironment.SetActive(true);
lunarEnvironment.SetActive(false);
//DynamicGI.UpdateEnvironment();
}
public void SetLunarSkybox()
{
RenderSettings.skybox = lunarSkybox;
forestEnvironment.SetActive(false);
lunarEnvironment.SetActive(true);
//DynamicGI.UpdateEnvironment();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 17d55a2c5052d424ea054a778ad967b6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,31 @@
using UnityEngine;
using TMPro;
public class LineData : MonoBehaviour
{
public float angle;
public TMP_Text distanceText;
private void Awake()
{
if (distanceText) distanceText.text = "";
}
public void FindCurrentAngle(float radiusX, float radiusZ)
{
Vector3 parentPos = transform.parent.position;
Vector3 pos = transform.position;
angle = Mathf.Atan2(pos.z / radiusZ, pos.x / radiusX);
angle = Mathf.Repeat(angle, 2f * Mathf.PI);
}
public void SetDistanceText(float distance)
{
if(Lesson1Controller.Instance.activeExperiment >= 2)
{
distanceText.text = "DISTANCE: " + distance.ToString();
} else
{
distanceText.text = "";
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 324116e4d975df644a2752e17861315e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,34 @@
using UnityEngine;
using TMPro;
public class PlayerSpeedChecker : MonoBehaviour
{
public float rayDistance = 10f;
public float raycastHeightOffset = 3f;
public TMP_Text speedText;
void Update()
{
Vector3 rayOrigin = transform.position + Vector3.up * raycastHeightOffset;
Vector3 rayDirection = transform.forward;
// ³çóàë³çàö³ÿ Ray
Debug.DrawRay(rayOrigin, rayDirection * rayDistance, Color.red);
// Raycast
if (Physics.Raycast(rayOrigin, rayDirection, out RaycastHit hit, rayDistance))
{
GameObject go = hit.collider.gameObject;
PlayerMovement pm = go.GetComponent<PlayerMovement>();
if (pm != null)
{
if (Lesson1Controller.Instance.activeExperiment == 1) speedText.text = "Speed: " + pm.playerSpeed.ToString("F0");
else speedText.text = "???";
}
} else
{
speedText.text = "";
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b1a5a99deec0f654289e24b7f30b913b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,97 @@
using System.Collections.Generic;
using UnityEngine;
public class RunlinePlacer : MonoBehaviour
{
[Header("Runway Properties")]
public float radiusX = 105f;
public float radiusZ = 55f;
public Vector3 center;
public List<Transform> linePositions = new List<Transform>();
public GameObject startLinePrefab;
public GameObject endLinePrefab;
public AmyRunScript amy;
private float largeTurnOffset = 50f;
private GameObject activeStartLine;
private GameObject activeEndLine;
private DrawDistanceLine drawDistanceLine;
private void Awake()
{
center = transform.position;
drawDistanceLine = GetComponent<DrawDistanceLine>();
}
[ContextMenu("Respawn lines")]
public void RuntimePlace()
{
drawDistanceLine.ClearArc();
foreach (Transform t in linePositions)
{
foreach (Transform child in t)
{
Destroy(child.gameObject);
}
}
int firstPositionIndex = Random.Range(0, 4);
int secondPositionIndex;
do
{
secondPositionIndex = Random.Range(0, 4);
} while (secondPositionIndex == firstPositionIndex);
PlaceLine(firstPositionIndex, startLinePrefab, true);
PlaceLine(secondPositionIndex, endLinePrefab);
amy.PlaceOnStartAngle();
// Experiment 2
if (Lesson1Controller.Instance.activeExperiment == 2) drawDistanceLine.DrawDistanceArc();
}
private void PlaceLine(int positionIndex, GameObject prefabIfSmall, bool isStart = false)
{
GameObject instantiatedLine = Instantiate(prefabIfSmall);
instantiatedLine.transform.SetParent(linePositions[positionIndex]);
instantiatedLine.transform.localPosition = Vector3.zero;
instantiatedLine.transform.localRotation = Quaternion.identity;
if (positionIndex > 1)
{
Vector3 pos = instantiatedLine.transform.localPosition;
pos.x = Random.Range(-largeTurnOffset, largeTurnOffset);
instantiatedLine.transform.localPosition = pos;
}
LineData ilinedata = instantiatedLine.GetComponent<LineData>();
ilinedata.FindCurrentAngle(radiusX, radiusZ);
if (isStart)
{
amy.SetAngle(ilinedata.angle);
amy.startAngle = ilinedata.angle;
activeStartLine = instantiatedLine;
} else
{
activeEndLine = instantiatedLine;
}
}
public float GetStartLineAngle()
{
LineData ilinedata = activeStartLine.GetComponent<LineData>();
return ilinedata.angle;
}
public float GetEndLineAngle()
{
LineData ilinedata = activeEndLine.GetComponent<LineData>();
return ilinedata.angle;
}
public GameObject GetStartLineGameObject()
{
return activeStartLine;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e95668e7c776a184782e93d5c67d3975
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,80 @@
using UnityEngine;
public class SatelliteOrbit : MonoBehaviour
{
[Tooltip("Точка, навколо якої обертається супутник")]
public Transform center;
[Tooltip("Радіус орбіти")]
public float radius = 5f;
[Tooltip("Швидкість зміни кута в градусах за секунду")]
public float angularSpeed = 50f;
[Tooltip("Чи дивитись супутнику на центр під час руху")]
public bool lookAtCenter = false;
private float angleTheta; // горизонтальний кут (навколо Y)
private float anglePhi; // вертикальний кут (від 0 до 180)
void Start()
{
radius = Random.Range(300, 600);
angularSpeed = Random.Range(5, 25);
lookAtCenter = true;
if (center == null)
{
GameObject go = new GameObject("OrbitCenter");
go.transform.position = Vector3.zero;
center = go.transform;
}
// Випадкові початкові кути для різних напрямків руху
angleTheta = Random.Range(0f, 360f);
anglePhi = Random.Range(0f, 180f);
UpdatePosition();
}
void Update()
{
// Змінюємо кути для створення сферичної орбіти
angleTheta += angularSpeed * Time.deltaTime; // обертання навколо Y
anglePhi += angularSpeed * 0.5f * Time.deltaTime; // нахил вгору/вниз
if (angleTheta > 360f) angleTheta -= 360f;
if (anglePhi > 360f) anglePhi -= 360f;
UpdatePosition();
if (lookAtCenter)
transform.LookAt(center.position);
}
private void UpdatePosition()
{
float thetaRad = angleTheta * Mathf.Deg2Rad;
float phiRad = anglePhi * Mathf.Deg2Rad;
// Сферичні координати → декартові
float x = radius * Mathf.Sin(phiRad) * Mathf.Cos(thetaRad);
float y = radius * Mathf.Cos(phiRad);
float z = radius * Mathf.Sin(phiRad) * Mathf.Sin(thetaRad);
transform.position = center.position + new Vector3(x, y, z);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 714c5c3bdbbca9149b5fa9760930afd9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,43 @@
using UnityEngine;
public class Stopwatch : MonoBehaviour
{
public GameObject arrow;
public AmyRunScript amy;
public Quaternion arrowStartRotation;
private float rotationSpeed = 360f / 60f;
public bool isCounting = false;
private float timeCounted = 0f;
void Start()
{
arrowStartRotation = arrow.transform.localRotation;
}
void Update()
{
if (Lesson1Controller.Instance.activeExperiment == 0) return;
if (isCounting)
{
arrow.transform.Rotate(0f, rotationSpeed * Time.deltaTime, 0f);
timeCounted += Time.deltaTime;
}
if (timeCounted >= 60f && Lesson1Controller.Instance.activeExperiment == 1) ExperimentChooser.Instance.experiment2Button.interactable = true;
if (Input.GetMouseButtonDown(0)) isCounting = !isCounting;
if (Input.GetMouseButtonDown(1))
{
arrow.transform.localRotation = arrowStartRotation;
isCounting = false;
if (Lesson1Controller.Instance.activeExperiment < 3) amy.PlaceOnStartAngle();
}
if (Lesson1Controller.Instance.activeExperiment < 3)
{
if(isCounting) amy.StartRun();
else amy.StopRun();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cf3c432b87a2fd8488641321aaecb33c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,69 @@
using UnityEngine;
public class TransitionSphere : MonoBehaviour
{
public float duration = 1f; // òðèâàë³ñòü àí³ìàö³¿ â ñåêóíäàõ
private Material sphereMat;
private Color initialColor;
private Coroutine currentAnimation;
void Start()
{
// Îòðèìóºìî ìàòåð³àë
Renderer rend = GetComponent<Renderer>();
sphereMat = rend.material;
// Ïåðåêîíàéñÿ, ùî øåéäåð ï³äòðèìóº ïðîçîð³ñòü (äëÿ URP Lit)
sphereMat.SetFloat("_Surface", 1); // Transparent
sphereMat.SetFloat("_Blend", 0); // Alpha Blend
initialColor = sphereMat.color;
}
// Âèêëèê ö³º¿ ôóíêö³¿ çàïóñêຠàí³ìàö³þ
public void PlayAnimation()
{
// ßêùî àí³ìàö³ÿ âæå éäå, çóïèíÿºìî ¿¿
if (currentAnimation != null)
StopCoroutine(currentAnimation);
// Ïî÷àòêîâ³ çíà÷åííÿ
transform.localScale = Vector3.zero;
Color c = initialColor;
c.a = 1f;
sphereMat.color = c;
currentAnimation = StartCoroutine(AnimateSphere());
}
private System.Collections.IEnumerator AnimateSphere()
{
float elapsed = 0f;
Vector3 startScale = Vector3.zero;
Vector3 endScale = Vector3.one * 100f;
while (elapsed < duration)
{
elapsed += Time.deltaTime;
float t = Mathf.Clamp01(elapsed / duration);
// Ìàñøòàá
transform.localScale = Vector3.Lerp(startScale, endScale, t);
// Ïðîçîð³ñòü
Color c = sphereMat.color;
c.a = Mathf.Lerp(1f, 0f, t);
sphereMat.color = c;
yield return null;
}
// Ô³íàëüíèé ñòàí
transform.localScale = endScale;
Color finalColor = sphereMat.color;
finalColor.a = 0f;
sphereMat.color = finalColor;
currentAnimation = null;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1995a23ba3627804093ef252dc4e9137
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e96bc71a5f3e9a344aad03c94616cfa8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,35 @@
using UnityEngine;
using UnityEngine.UI;
public class PlayerAmbientSound : MonoBehaviour
{
public AudioSource ambientSource; // åìᳺíò (ôîíîâà ìóçèêà)
public AudioSource cricketsSource; // ñâåð÷êè
public Slider volumeSlider;
void Start()
{
if (ambientSource != null)
{
ambientSource.loop = true;
ambientSource.Play();
}
if (cricketsSource != null)
{
cricketsSource.loop = true;
cricketsSource.Play();
}
if (volumeSlider != null)
{
volumeSlider.onValueChanged.AddListener(OnVolumeChange);
}
void OnVolumeChange(float value)
{
if (ambientSource != null)
ambientSource.volume = value;
if (cricketsSource != null)
cricketsSource.volume = value;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 667fa0519c144254f92051f01717bf3f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,120 @@
using UnityEngine;
using UnityEngine.InputSystem;
[RequireComponent(typeof(CharacterController))]
public class PlayerMovement : MonoBehaviour
{
public float playerSpeed = 10.0f;
private float earthSpeed = 10f;
private float jumpHeight = 2.5f;
private float gravityValue = -9.81f;
private CharacterController controller;
private Vector3 playerVelocity;
private bool groundedPlayer;
private float xRotation = 0f;
[Header("Input Actions")]
public InputActionReference moveAction;
public InputActionReference jumpAction;
[Header("Camera Settings")]
public Transform playerCamera;
public float mouseSensitivity = 3f;
[Header("Ground Checker")]
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;
private void Awake()
{
controller = gameObject.GetComponent<CharacterController>();
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
private void Start()
{
SetPlayerRandomSpeed();
earthSpeed = playerSpeed;
}
private void OnEnable()
{
moveAction.action.Enable();
jumpAction.action.Enable();
}
private void OnDisable()
{
moveAction.action.Disable();
jumpAction.action.Disable();
}
void Update()
{
if (MenuController.Instance.isPaused) return;
MoveMouse();
PlayerJump();
MovePlayer();
}
private void MoveMouse()
{
float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity;
float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity;
xRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, -80f, 80f);
playerCamera.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
transform.Rotate(Vector3.up * mouseX);
}
private void PlayerJump()
{
groundedPlayer = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
if (groundedPlayer && playerVelocity.y < 0)
{
playerVelocity.y = 0f;
}
if (jumpAction.action.triggered && groundedPlayer)
{
playerVelocity.y = Mathf.Sqrt(jumpHeight * -2.0f * gravityValue);
}
}
private void MovePlayer()
{
float horizontal = Input.GetAxis("Horizontal");
float vertical = Input.GetAxis("Vertical");
Vector3 move = transform.right * horizontal + transform.forward * vertical;
controller.Move(move * playerSpeed * Time.deltaTime);
playerVelocity.y += gravityValue * Time.deltaTime;
controller.Move(playerVelocity * Time.deltaTime);
}
[ContextMenu("Set player random speed")]
public void SetPlayerRandomSpeed()
{
playerSpeed = Random.Range(8, 15);
earthSpeed = playerSpeed;
}
public void SetPlayerEarthSpeed()
{
playerSpeed = earthSpeed;
gravityValue = -9.81f;
}
public void SetPlayerLunarSpeed()
{
playerSpeed *= Mathf.Sqrt(1.62f / 9.81f);
gravityValue = -1.62f;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 41bcbf4d9bcf3ae41b3f58a4767d99f6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,41 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class PlayerRaycastOnUI : MonoBehaviour
{
public Camera playerCamera;
public Canvas worldCanvas;
public KeyCode interactKey = KeyCode.E;
private GraphicRaycaster raycaster;
private EventSystem eventSystem;
void Start()
{
raycaster = worldCanvas.GetComponent<GraphicRaycaster>();
eventSystem = EventSystem.current;
}
void Update()
{
// Ñòâîðþºìî PointerEventData íà îñíîâ³ öåíòðó êàìåðè
PointerEventData pointerData = new PointerEventData(eventSystem);
pointerData.position = playerCamera.WorldToScreenPoint(playerCamera.transform.position + playerCamera.transform.forward * 2f);
List<RaycastResult> results = new List<RaycastResult>();
raycaster.Raycast(pointerData, results);
foreach (var result in results)
{
Button button = result.gameObject.GetComponent<Button>();
if (button != null)
{
if (Input.GetKeyDown(interactKey))
{
button.onClick.Invoke();
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3963846b067083f428abc18078b33ab3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0bcf5238979dd7740b9acbea616ddc37
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,15 @@
using UnityEngine;
public class GameManagerScript : MonoBehaviour
{
void Start()
{
Application.targetFrameRate = 60;
QualitySettings.vSyncCount = 0;
}
void Update()
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ef601aec25fc12a43bfbe138d049212a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,63 @@
using UnityEngine;
using UnityEngine.UI;
public class MenuController : MonoBehaviour
{
public static MenuController Instance { get; private set; }
public GameObject pauseMenuPanel;
public Button resumeButton;
public Button quitButton;
public bool isPaused = false;
private void Awake()
{
if (Instance == null)
{
Instance = this;
}
else if (Instance != this)
{
Destroy(gameObject);
}
}
private void Start()
{
resumeButton.onClick.AddListener(TogglePause);
quitButton.onClick.AddListener(CloseGame);
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
TogglePause();
}
}
void TogglePause()
{
isPaused = !isPaused;
pauseMenuPanel.SetActive(isPaused);
if (isPaused)
{
Time.timeScale = 0f;
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
else
{
Time.timeScale = 1f;
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
}
private void CloseGame()
{
Application.Quit();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4e09424ee66487a4c829b89df5fc3887
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,32 @@
using UnityEngine;
public class Screenshooter : MonoBehaviour
{
public Camera cam;
public int width = 3840;
public int height = 2160;
void Update()
{
if (Input.GetKeyDown(KeyCode.F12))
{
RenderTexture rt = new RenderTexture(width, height, 24);
cam.targetTexture = rt;
Texture2D image = new Texture2D(width, height, TextureFormat.RGB24, false);
cam.Render();
RenderTexture.active = rt;
image.ReadPixels(new Rect(0, 0, width, height), 0, 0);
image.Apply();
cam.targetTexture = null;
RenderTexture.active = null;
Destroy(rt);
System.IO.File.WriteAllBytes(
"screenshot_4k.png",
image.EncodeToPNG()
);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7c666a8f574985443b3c7630ec3de08c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: