205 lines
7.4 KiB
C#
205 lines
7.4 KiB
C#
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using TMPro;
|
||
|
||
public class AstronautController : MonoBehaviour
|
||
{
|
||
[SerializeField] private float _moveSpeed = 3f;
|
||
[SerializeField] private float _jumpForce = 10f;
|
||
[SerializeField] private Planet _currentPlanet = Planet.Earth;
|
||
[SerializeField] private AstronautAnimator _astronautAnimator;
|
||
[SerializeField] private TextMeshProUGUI _planetText;
|
||
[SerializeField] private TextMeshProUGUI _gravityText;
|
||
public Planet CurrentPlanet => _currentPlanet;
|
||
|
||
public enum Planet
|
||
{
|
||
Mercury, Venus, Earth, Moon, Mars, Jupiter, Saturn, Uranus, Neptune, Sun
|
||
}
|
||
|
||
private Rigidbody _rb;
|
||
private bool _isGrounded;
|
||
private bool _isJumping;
|
||
private float _ratio = 1f;
|
||
|
||
float GetGravity(Planet planet)
|
||
{
|
||
switch (planet)
|
||
{
|
||
case Planet.Mercury: return 3.72f;
|
||
case Planet.Venus: return 8.87f;
|
||
case Planet.Earth: return 9.81f;
|
||
case Planet.Moon: return 1.62f;
|
||
case Planet.Mars: return 3.721f;
|
||
case Planet.Jupiter: return 24.79f;
|
||
case Planet.Saturn: return 10.44f;
|
||
case Planet.Uranus: return 8.69f;
|
||
case Planet.Neptune: return 11.15f;
|
||
case Planet.Sun: return 274f;
|
||
default: return 9.81f;
|
||
}
|
||
}
|
||
|
||
string GetPlanetNameUA(Planet planet)
|
||
{
|
||
switch (planet)
|
||
{
|
||
case Planet.Mercury: return "Меркурій";
|
||
case Planet.Venus: return "Венера";
|
||
case Planet.Earth: return "Земля";
|
||
case Planet.Moon: return "Місяць";
|
||
case Planet.Mars: return "Марс";
|
||
case Planet.Jupiter: return "Юпітер";
|
||
case Planet.Saturn: return "Сатурн";
|
||
case Planet.Uranus: return "Уран";
|
||
case Planet.Neptune: return "Нептун";
|
||
case Planet.Sun: return "Сонце";
|
||
default: return "";
|
||
}
|
||
}
|
||
|
||
float GetSpeedMultiplier()
|
||
{
|
||
if (_currentPlanet == Planet.Moon) return 1.5f;
|
||
return Mathf.Clamp(1f / (_ratio * 1.5f), 0.15f, 3f);
|
||
}
|
||
|
||
void ApplyGravity()
|
||
{
|
||
Physics.gravity = new Vector3(0, -GetGravity(_currentPlanet), 0);
|
||
_ratio = GetGravity(_currentPlanet) / 9.81f;
|
||
_astronautAnimator.SetRatio(_ratio);
|
||
if (_planetText != null)
|
||
_planetText.text = GetPlanetNameUA(_currentPlanet);
|
||
}
|
||
|
||
IEnumerator ShowGravityText()
|
||
{
|
||
_gravityText.text = "Прискорення падіння: " + GetGravity(_currentPlanet).ToString("F2") + " м/с²";
|
||
float t = 0f;
|
||
while (t < 1f)
|
||
{
|
||
t += Time.deltaTime * 2f;
|
||
_gravityText.alpha = t;
|
||
yield return null;
|
||
}
|
||
yield return new WaitForSeconds(4f);
|
||
t = 1f;
|
||
while (t > 0f)
|
||
{
|
||
t -= Time.deltaTime * 2f;
|
||
_gravityText.alpha = t;
|
||
yield return null;
|
||
}
|
||
}
|
||
|
||
float GetClampedMass()
|
||
{
|
||
return Mathf.Clamp(_rb.mass, 30f, 100f);
|
||
}
|
||
|
||
void Start()
|
||
{
|
||
_rb = GetComponent<Rigidbody>();
|
||
_rb.freezeRotation = true;
|
||
if (_gravityText != null)
|
||
_gravityText.alpha = 0f;
|
||
ApplyGravity();
|
||
_astronautAnimator.SetMass(GetClampedMass());
|
||
}
|
||
|
||
public void RefreshMass()
|
||
{
|
||
_astronautAnimator.SetMass(GetClampedMass());
|
||
}
|
||
|
||
void OnCollisionEnter(Collision collision)
|
||
{
|
||
if (collision.gameObject.CompareTag("Ground"))
|
||
{
|
||
_isGrounded = true;
|
||
_isJumping = false;
|
||
}
|
||
}
|
||
|
||
void OnCollisionExit(Collision collision)
|
||
{
|
||
if (collision.gameObject.CompareTag("Ground"))
|
||
{
|
||
_isGrounded = false;
|
||
}
|
||
}
|
||
|
||
void Update()
|
||
{
|
||
if (Input.GetKeyDown(KeyCode.Alpha1)) { _currentPlanet = Planet.Mercury; ApplyGravity(); }
|
||
if (Input.GetKeyDown(KeyCode.Alpha2)) { _currentPlanet = Planet.Venus; ApplyGravity(); }
|
||
if (Input.GetKeyDown(KeyCode.Alpha3)) { _currentPlanet = Planet.Earth; ApplyGravity(); }
|
||
if (Input.GetKeyDown(KeyCode.Alpha4)) { _currentPlanet = Planet.Moon; ApplyGravity(); }
|
||
if (Input.GetKeyDown(KeyCode.Alpha5)) { _currentPlanet = Planet.Mars; ApplyGravity(); }
|
||
if (Input.GetKeyDown(KeyCode.Alpha6)) { _currentPlanet = Planet.Jupiter; ApplyGravity(); }
|
||
if (Input.GetKeyDown(KeyCode.Alpha7)) { _currentPlanet = Planet.Saturn; ApplyGravity(); }
|
||
if (Input.GetKeyDown(KeyCode.Alpha8)) { _currentPlanet = Planet.Uranus; ApplyGravity(); }
|
||
if (Input.GetKeyDown(KeyCode.Alpha9)) { _currentPlanet = Planet.Neptune; ApplyGravity(); }
|
||
if (Input.GetKeyDown(KeyCode.Alpha0)) { _currentPlanet = Planet.Sun; ApplyGravity(); }
|
||
|
||
if (Input.GetKeyDown(KeyCode.Keypad1)) { _currentPlanet = Planet.Mercury; ApplyGravity(); }
|
||
if (Input.GetKeyDown(KeyCode.Keypad2)) { _currentPlanet = Planet.Venus; ApplyGravity(); }
|
||
if (Input.GetKeyDown(KeyCode.Keypad3)) { _currentPlanet = Planet.Earth; ApplyGravity(); }
|
||
if (Input.GetKeyDown(KeyCode.Keypad4)) { _currentPlanet = Planet.Moon; ApplyGravity(); }
|
||
if (Input.GetKeyDown(KeyCode.Keypad5)) { _currentPlanet = Planet.Mars; ApplyGravity(); }
|
||
if (Input.GetKeyDown(KeyCode.Keypad6)) { _currentPlanet = Planet.Jupiter; ApplyGravity(); }
|
||
if (Input.GetKeyDown(KeyCode.Keypad7)) { _currentPlanet = Planet.Saturn; ApplyGravity(); }
|
||
if (Input.GetKeyDown(KeyCode.Keypad8)) { _currentPlanet = Planet.Uranus; ApplyGravity(); }
|
||
if (Input.GetKeyDown(KeyCode.Keypad9)) { _currentPlanet = Planet.Neptune; ApplyGravity(); }
|
||
if (Input.GetKeyDown(KeyCode.Keypad0)) { _currentPlanet = Planet.Sun; ApplyGravity(); }
|
||
|
||
float currentSpeed = _moveSpeed * GetSpeedMultiplier();
|
||
float h = Input.GetAxis("Horizontal");
|
||
float v = Input.GetAxis("Vertical");
|
||
bool isWalking = Mathf.Abs(h) > 0.1f || Mathf.Abs(v) > 0.1f;
|
||
|
||
if (!_isJumping)
|
||
{
|
||
Vector3 move = new Vector3(-h, 0, -v).normalized * currentSpeed;
|
||
_rb.velocity = new Vector3(move.x, _rb.velocity.y, move.z);
|
||
if (isWalking)
|
||
transform.forward = new Vector3(-h, 0, -v).normalized;
|
||
}
|
||
|
||
_astronautAnimator.SetWalking(isWalking && !_isJumping);
|
||
|
||
bool canJump = _currentPlanet == Planet.Sun ? true : (_isGrounded && !_isJumping);
|
||
|
||
if (Input.GetKeyDown(KeyCode.Space) && canJump)
|
||
{
|
||
_isJumping = true;
|
||
_astronautAnimator.Jump();
|
||
StartCoroutine(JumpForceDelay());
|
||
}
|
||
}
|
||
|
||
IEnumerator JumpForceDelay()
|
||
{
|
||
float animSpeed = (_currentPlanet == Planet.Moon)
|
||
? 1.5f
|
||
: Mathf.Clamp(1f / (_ratio * 1.5f), 0.15f, 3f);
|
||
float delay = 0.7f / animSpeed;
|
||
yield return new WaitForSeconds(delay);
|
||
_rb.velocity = new Vector3(_rb.velocity.x, 0, _rb.velocity.z);
|
||
float clampedMass = GetClampedMass();
|
||
float savedMass = _rb.mass;
|
||
_rb.mass = 75f;
|
||
_rb.AddForce(Vector3.up * _jumpForce, ForceMode.Impulse);
|
||
_rb.mass = savedMass;
|
||
float bonus = Mathf.Lerp(1.5f, -1.5f, Mathf.InverseLerp(30f, 100f, clampedMass));
|
||
_rb.AddForce(Vector3.up * bonus, ForceMode.VelocityChange);
|
||
if (_gravityText != null)
|
||
StartCoroutine(ShowGravityText());
|
||
if (_currentPlanet == Planet.Sun)
|
||
_isJumping = false;
|
||
}
|
||
|
||
}
|