Я нашёл вариант с домноженим на 1.07, но у меня целочисленные числа.
using UnityEngine;
[RequireComponent(typeof(Rigidbody))]
public class RotateRigidbody : MonoBehaviour {
[SerializeField] private Rigidbody m_Rigidbody;
[SerializeField] private Vector3 m_Speed;
private void Start() {
m_Rigidbody = GetComponent<Rigidbody>();
}
private void FixedUpdate() {
m_Rigidbody.MoveRotation(Quaternion.Euler(m_Speed));
}
}
public void SaveLvlList(string keyName, int CountStars)
{
PlayerPrefs.SetString(keyName, JsonUtility.ToJson(CountStars));
PlayerPrefs.Save();
}
public GameObject[] ObjectsForDestroy;
private void CreateDirectory()
{
if (Directory.Exists(_directoryPath) == false)
{
Directory.CreateDirectory(_directoryPath);
}
}
private void CreateFile()
{
if (File.Exists(_path)) return;
var json = JsonUtility.ToJson(CompleteStatus.Locked);
using (var writer = File.CreateText(_path))
{
writer.Write(json);
writer.Close();
}
}
namespace Levels
{
public interface ILevel : IVisualization<ILevelView>
{
void Load();
void Complete(CompleteStatus status);
}
}
namespace Levels
{
public interface IVisualization<in TView>
{
void Visualize(TView view);
}
}
namespace Levels
{
public enum CompleteStatus
{
Locked,
Uncompleted,
OneStar,
TwoStars,
ThreeStars
}
public interface ILevelView
{
void DrawCompletion(CompleteStatus status);
}
}
using System.IO;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace Levels
{
public abstract class Level : ILevel
{
private readonly string _name;
private readonly string _path;
private readonly string _directoryPath = $"{Application.persistentDataPath}/Saves";
protected Level(string name)
{
_name = name;
_path = $"{_directoryPath}/{_name}.json";
CreateDirectory();
CreateFile();
}
public void Load()
{
SceneManager.LoadScene(_name);
}
public void Complete(CompleteStatus status)
{
SaveStatus(status);
}
public void Visualize(ILevelView view)
{
view.DrawCompletion(LoadStatusFromJson());
}
private void CreateDirectory()
{
if (Directory.Exists(_directoryPath) == false)
{
Directory.CreateDirectory(_directoryPath);
}
}
private void CreateFile()
{
if (File.Exists(_path)) return;
var json = JsonUtility.ToJson(CompleteStatus.Locked);
using (var writer = File.CreateText(_path))
{
writer.Write(json);
writer.Close();
}
}
private void SaveStatus(CompleteStatus status)
{
var json = JsonUtility.ToJson(status);
File.WriteAllText(_path, json);
}
private CompleteStatus LoadStatusFromJson()
{
var file = File.ReadAllText(_path);
return JsonUtility.FromJson<CompleteStatus>(file);
}
}
}
namespace Levels
{
public class SecondLevel : Level
{
public SecondLevel() : base(nameof(SecondLevel))
{
}
}
}
using System;
using UnityEngine;
using UnityEngine.UI;
namespace Levels
{
public class LevelView : MonoBehaviour, ILevelView
{
[SerializeField] private Image _firstStar, _secondStar, _thirdStar;
[SerializeField] private Button _button;
[SerializeField] private Color _inactiveStarColor, _activeStarColor;
public void DrawCompletion(CompleteStatus status)
{
switch (status)
{
case CompleteStatus.Locked:
_firstStar.color = _inactiveStarColor;
_secondStar.color = _inactiveStarColor;
_thirdStar.color = _inactiveStarColor;
_button.interactable = false;
break;
case CompleteStatus.Uncompleted:
_button.interactable = true;
_firstStar.color = _inactiveStarColor;
_secondStar.color = _inactiveStarColor;
_thirdStar.color = _inactiveStarColor;
break;
case CompleteStatus.OneStar:
_button.interactable = true;
_firstStar.color = _activeStarColor;
_secondStar.color = _inactiveStarColor;
_thirdStar.color = _inactiveStarColor;
break;
case CompleteStatus.TwoStars:
_button.interactable = true;
_firstStar.color = _activeStarColor;
_secondStar.color = _activeStarColor;
_thirdStar.color = _inactiveStarColor;
break;
case CompleteStatus.ThreeStars:
_button.interactable = true;
_firstStar.color = _activeStarColor;
_secondStar.color = _activeStarColor;
_thirdStar.color = _activeStarColor;
break;
default: throw new ArgumentException();
}
}
}
}
using System.Collections.Generic;
using UnityEngine;
namespace Levels
{
public class LevelList : MonoBehaviour
{
[SerializeField] private LevelView _levelViewPrefab;
[SerializeField] private Transform _levelsParent;
private ILevel[] _levels;
private void Awake()
{
var first = new FirstLevel();
var second = new SecondLevel();
var third = new ThirdLevel();
var fourth = new FourthLevel();
var fifth = new FifthLevel();
_levels = new ILevel[]
{
first, second, third, fourth, fifth
};
//test
first.Complete(CompleteStatus.OneStar);
second.Complete(CompleteStatus.TwoStars);
third.Complete(CompleteStatus.ThreeStars);
fourth.Complete(CompleteStatus.Uncompleted);
fifth.Complete(CompleteStatus.Locked);
VisualizeLevels(_levels);
}
private void VisualizeLevels(IEnumerable<ILevel> levels)
{
foreach (var level in levels)
{
var view = Instantiate(_levelViewPrefab, _levelsParent);
level.Visualize(view);
}
}
}
}
if (Physics.Raycast(transform.position, _direction, out hit, 10f)) {
if (hit.collider == yourCollider) {
// some logic
}
}
private MyComponent GetTarget() {
if (Physics.Raycast(transform.position, _direction, out hit, 10f))
if (hit.transform.TryGetComponent(out MyComponent m))
return m;
return null;
}
using UnityEngine;
namespace Bullets
{
[RequireComponent(typeof(Rigidbody2D), typeof(Collider2D))]
public class Bullet : MonoBehaviour, IBullet
{
[SerializeField] private float _speed = 5f;
[SerializeField] private int _damage = 10;
[SerializeField] private int _maxReflections = 5;
private Rigidbody2D _rigidbody;
private Vector2 _direction = Vector2.zero;
private void Awake()
{
_rigidbody = GetComponent<Rigidbody2D>();
_rigidbody.isKinematic = true;
_rigidbody.useFullKinematicContacts = true;
}
public void Shoot(Vector2 direction)
{
_direction = direction.normalized;
}
private void FixedUpdate()
{
if (_direction == Vector2.zero) return;
var deltaMovement = _direction * _speed * Time.deltaTime;
_rigidbody.MovePosition(_rigidbody.position + deltaMovement);
}
private void OnCollisionEnter2D(Collision2D other)
{
if (other.transform.TryGetComponent(out IDamageable damageable))
{
damageable.ApplyDamage(_damage);
Destroy();
return;
}
var normal = other.GetContact(0).normal;
Reflect(normal);
}
private void Destroy()
{
Destroy(gameObject);
}
private void Reflect(Vector2 normal)
{
if (_maxReflections - 1 == 0) Destroy();
_maxReflections--;
_direction = Vector2.Reflect(_direction, normal).normalized;
}
}
}
using UnityEngine;
namespace Bullets
{
public class SomeGun : MonoBehaviour
{
[SerializeField] private Bullet _bulletPrefab;
[SerializeField] private Transform _bulletOrigin;
[SerializeField] private Camera _camera;
private void Update()
{
LookAtMouse(Input.mousePosition);
if (Input.GetKeyDown(KeyCode.Mouse0))
{
Shoot();
}
}
private void LookAtMouse(Vector3 mousePosition)
{
var gunScreenPosition = _camera.WorldToScreenPoint(transform.position);
var direction = mousePosition - gunScreenPosition;
direction.Scale(new Vector3(1, 1, 0));
transform.up = direction;
}
private void Shoot()
{
var bullet = Instantiate(_bulletPrefab, _bulletOrigin.position, Quaternion.identity);
bullet.Shoot(transform.up);
}
}
}