Refactoring, Code cleanup, Player Width

main
Benjamin Kraft 1 year ago
parent 2f1d19c094
commit 13d5237c6b
  1. 2
      Assets/Prefabs/Player.prefab
  2. 47
      Assets/Scripts/Dimensions.cs
  3. 103
      Assets/Scripts/Game/AIPlayer.cs
  4. 21
      Assets/Scripts/Game/Ball.cs
  5. 3
      Assets/Scripts/Game/Collectable.cs
  6. 8
      Assets/Scripts/Game/DeathGate.cs
  7. 57
      Assets/Scripts/Game/GameManager.cs
  8. 4
      Assets/Scripts/Game/Modification.cs
  9. 5
      Assets/Scripts/Game/ModificationProperties.cs
  10. 95
      Assets/Scripts/Game/Player.cs
  11. 8
      Assets/Scripts/Game/RealPlayer.cs
  12. 2
      Assets/Scripts/Game/Settings.cs
  13. 6
      Assets/Scripts/Game/Wormhole.cs
  14. 21
      Assets/Scripts/GameUI.cs
  15. 16
      Assets/Scripts/MenuUI.cs
  16. 3
      Assets/Scripts/NetworkCommandLine.cs

@ -113,7 +113,7 @@ Transform:
m_GameObject: {fileID: 5402279313309450415} m_GameObject: {fileID: 5402279313309450415}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 4, y: 1, z: 1} m_LocalScale: {x: 5, y: 1, z: 1}
m_ConstrainProportionsScale: 0 m_ConstrainProportionsScale: 0
m_Children: m_Children:
- {fileID: 4352057116839657264} - {fileID: 4352057116839657264}

@ -1,10 +1,11 @@
using System;
using UnityEngine; using UnityEngine;
using UnityEngine.Serialization; using UnityEngine.Serialization;
[ExecuteInEditMode] [ExecuteInEditMode]
public class Dimensions : MonoBehaviour { public class Dimensions : MonoBehaviour {
public static Dimensions Singleton;
public bool isUpdating; public bool isUpdating;
[FormerlySerializedAs("panelHeightPixels")] [FormerlySerializedAs("panelHeightPixels")]
@ -25,7 +26,14 @@ public class Dimensions : MonoBehaviour {
public SpriteRenderer playerPanelBottom; public SpriteRenderer playerPanelBottom;
public SpriteRenderer background; public SpriteRenderer background;
public static Dimensions Singleton; private LineRenderer topL, bottomL;
public Vector2 PlaySize { get; private set; }
public Vector2 PlaySizeBoards { get; private set; }
public float PanelHeightPixels { get; private set; }
private void Awake() { private void Awake() {
Singleton = this; Singleton = this;
GetComponents(); GetComponents();
@ -34,29 +42,28 @@ public class Dimensions : MonoBehaviour {
isUpdating = false; isUpdating = false;
} }
private void Update() {
if (!isUpdating)
return;
SetDimensions();
}
private void GetComponents() { private void GetComponents() {
topL = topC.GetComponent<LineRenderer>(); topL = topC.GetComponent<LineRenderer>();
bottomL = bottomC.GetComponent<LineRenderer>(); bottomL = bottomC.GetComponent<LineRenderer>();
} }
public Vector2 PlaySize { get; private set; }
public Vector2 PlaySizeBoards { get; private set; }
public float PanelHeightPixels { get; private set; }
private LineRenderer topL, bottomL;
private void SetDimensions() { private void SetDimensions() {
float heightByPanels = 1 / (1 - 2 * panelHeightPixelsMinimum / mainCamera.pixelHeight) * playGroundSize.y; var heightByPanels = 1 / (1 - 2 * panelHeightPixelsMinimum / mainCamera.pixelHeight) * playGroundSize.y;
float heightByPlayground = playGroundSize.x / mainCamera.aspect; var heightByPlayground = playGroundSize.x / mainCamera.aspect;
float height = Mathf.Max(heightByPanels, heightByPlayground); var height = Mathf.Max(heightByPanels, heightByPlayground);
float width = mainCamera.aspect * height; var width = mainCamera.aspect * height;
float panelHeight = (height - playGroundSize.y) / 2; var panelHeight = (height - playGroundSize.y) / 2;
mainCamera.orthographicSize = height / 2; mainCamera.orthographicSize = height / 2;
float top = playGroundSize.y / 2; var top = playGroundSize.y / 2;
float right = playGroundSize.x / 2; var right = playGroundSize.x / 2;
PanelHeightPixels = panelHeight / height * mainCamera.pixelHeight; PanelHeightPixels = panelHeight / height * mainCamera.pixelHeight;
PlaySize = playGroundSize; PlaySize = playGroundSize;
@ -80,7 +87,7 @@ public class Dimensions : MonoBehaviour {
playGround.size = new Vector2(playGroundSize.y, playGroundSize.x); playGround.size = new Vector2(playGroundSize.y, playGroundSize.x);
const float lineWidth = 0.5f; const float lineWidth = 0.5f;
Vector3 offset = Vector3.up * lineWidth / 2; var offset = Vector3.up * lineWidth / 2;
topL.positionCount = bottomL.positionCount = 2; topL.positionCount = bottomL.positionCount = 2;
var v12 = new[] {(Vector3) v1 - offset, (Vector3) v2 - offset}; var v12 = new[] {(Vector3) v1 - offset, (Vector3) v2 - offset};
@ -95,10 +102,4 @@ public class Dimensions : MonoBehaviour {
background.size = new Vector2(width, playGroundSize.y); background.size = new Vector2(width, playGroundSize.y);
} }
private void Update() {
if (!isUpdating)
return;
SetDimensions();
}
} }

@ -1,15 +1,45 @@
using System;
using System.Linq; using System.Linq;
using UnityEngine; using UnityEngine;
namespace Game { namespace Game {
public class AIPlayer : Player { public class AIPlayer : Player {
private const float SmoothTime = 0.2f;
private float currentSmoothV;
private bool isApproaching;
private float lastDirection;
public Difficulty Difficulty { get; set; } public Difficulty Difficulty { get; set; }
private float FutureSeconds => (float) Difficulty * 0.5f; private float FutureSeconds => (float) Difficulty * 0.5f;
private float IdlePosition => Difficulty >= Difficulty.Medium ? 0 : X;
private float DistortAmount => 1 - 1 / ((float) Difficulty + 1);
private void FixedUpdate() {
var dt = Time.fixedDeltaTime;
var target = GetTargetPosition();
var h = Mathf.Max(Speed * dt, Width / 2);
goingLeft = target < X - h;
goingRight = target > X + h;
if (goingLeft || goingRight) {
isApproaching = false;
lastDirection = goingLeft ? -1 : 1;
TryLinearMove(dt);
} else {
if (!isApproaching) {
isApproaching = true;
currentSmoothV = Speed * lastDirection;
}
ApproachPosition(target);
}
}
// True if ball y velocity points towards player // True if ball y velocity points towards player
private bool BallApproaches(Ball ball) { private bool BallApproaches(Ball ball) {
var ballVy = ball.Rb.velocity.y; var ballVy = ball.Rb.velocity.y;
@ -26,8 +56,8 @@ namespace Game {
point = Vector2.zero; point = Vector2.zero;
rs = Vector2.zero; rs = Vector2.zero;
Vector2 m1 = e1 - o1; var m1 = e1 - o1;
Vector2 m2 = e2 - o2; var m2 = e2 - o2;
/* /*
* *
@ -62,12 +92,10 @@ namespace Game {
return false; return false;
} }
private float IdlePosition => Difficulty >= Difficulty.Medium ? 0 : X;
// TODO Also must include fact that players have a height, maybe check the incoming angle // TODO Also must include fact that players have a height, maybe check the incoming angle
// angle: 0 -> perpendicular, from -90 to 90 // angle: 0 -> perpendicular, from -90 to 90
private bool IsPositionReachableInTime(float futurePosition, float seconds, float radius, float angle) { private bool IsPositionReachableInTime(float futurePosition, float seconds, float radius, float angle) {
float requiredDistance = Mathf.Abs(futurePosition - X) - Width / 2 - radius; var requiredDistance = Mathf.Abs(futurePosition - X) - Width / 2 - radius;
if (requiredDistance < 0) if (requiredDistance < 0)
return true; return true;
if (Mathf.Abs(futurePosition) > Border) if (Mathf.Abs(futurePosition) > Border)
@ -77,33 +105,33 @@ namespace Game {
private float Simulate(Vector2 origin, Vector2 velocity, float radius, float secondsLeft, float secondsUsed, out bool ignore) { private float Simulate(Vector2 origin, Vector2 velocity, float radius, float secondsLeft, float secondsUsed, out bool ignore) {
ignore = false; ignore = false;
Vector2 r = new Vector2(radius, radius); var r = new Vector2(radius, radius);
Vector2 validAreaOrigin = -Dimensions.Singleton.PlaySizeBoards / 2 + r; var validAreaOrigin = -Dimensions.Singleton.PlaySizeBoards / 2 + r;
Vector2 validAreaSize = Dimensions.Singleton.PlaySizeBoards - r * 2; var validAreaSize = Dimensions.Singleton.PlaySizeBoards - r * 2;
Rect area = new Rect(validAreaOrigin, validAreaSize); var area = new Rect(validAreaOrigin, validAreaSize);
// Try to follow this line from origin -> end // Try to follow this line from origin -> end
Vector2 end = origin + velocity * secondsLeft; var end = origin + velocity * secondsLeft;
// Line ends in playground // Line ends in playground
if (area.Contains(end)) if (area.Contains(end))
return end.x; return end.x;
float playerY = Side == Side.Bottom ? area.yMin : area.yMax; var playerY = Side == Side.Bottom ? area.yMin : area.yMax;
Vector2 playerLeft = new Vector2(area.xMin, playerY); var playerLeft = new Vector2(area.xMin, playerY);
Vector2 playerRight = new Vector2(area.xMax, playerY); var playerRight = new Vector2(area.xMax, playerY);
// Horizontal line (player line) -> stop simulating // Horizontal line (player line) -> stop simulating
if (Intersect(origin, end, playerLeft, playerRight, out Vector2 point, out Vector2 rs)) { if (Intersect(origin, end, playerLeft, playerRight, out var point, out var rs)) {
secondsUsed += secondsLeft * rs.x; secondsUsed += secondsLeft * rs.x;
if (!IsPositionReachableInTime(point.x, secondsUsed, radius, Vector2.Angle(velocity, transform.up))) if (!IsPositionReachableInTime(point.x, secondsUsed, radius, Vector2.Angle(velocity, transform.up)))
ignore = true; ignore = true;
return point.x; return point.x;
} }
bool borderHit = false; var borderHit = false;
Vector2 borderHitPoint = Vector2.zero; var borderHitPoint = Vector2.zero;
Vector2 borderRs = Vector2.zero; var borderRs = Vector2.zero;
// Left vertical border // Left vertical border
if (Intersect(origin, end, new Vector2(area.xMin, area.yMin), new Vector2(area.xMin, area.yMax), out point, out rs)) { if (Intersect(origin, end, new Vector2(area.xMin, area.yMin), new Vector2(area.xMin, area.yMax), out point, out rs)) {
@ -121,7 +149,7 @@ namespace Game {
// Any border -> invert x velocity and simulate again from there // Any border -> invert x velocity and simulate again from there
if (borderHit) { if (borderHit) {
float secondsUsedHere = borderRs.x * secondsLeft; var secondsUsedHere = borderRs.x * secondsLeft;
secondsLeft -= secondsUsedHere; secondsLeft -= secondsUsedHere;
secondsUsed += secondsUsedHere; secondsUsed += secondsUsedHere;
velocity = new Vector2(-velocity.x, velocity.y); velocity = new Vector2(-velocity.x, velocity.y);
@ -134,11 +162,9 @@ namespace Game {
return 0; return 0;
} }
private float DistortAmount => 1 - 1 / ((float) Difficulty + 1);
private float Distort(float target) { private float Distort(float target) {
float max = Width / 3; var max = Width / 3;
float distortionOffset = DistortAmount * max; var distortionOffset = DistortAmount * max;
distortionOffset *= target > X ? -1 : 1; distortionOffset *= target > X ? -1 : 1;
return target + distortionOffset; return target + distortionOffset;
} }
@ -149,9 +175,9 @@ namespace Game {
while (approaching.Count > 0) { while (approaching.Count > 0) {
// Nearest by Y-Distance // Nearest by Y-Distance
Ball ball = approaching.Aggregate(approaching[0], (prev, current) => YDistanceToBall(current) < YDistanceToBall(prev) ? current : prev); var ball = approaching.Aggregate(approaching[0], (prev, current) => YDistanceToBall(current) < YDistanceToBall(prev) ? current : prev);
float target = Simulate(ball.Rb.position, ball.Rb.velocity, ball.Radius, FutureSeconds, 0, out bool ignore); var target = Simulate(ball.Rb.position, ball.Rb.velocity, ball.Radius, FutureSeconds, 0, out var ignore);
if (!ignore) if (!ignore)
return Distort(target); return Distort(target);
@ -162,35 +188,10 @@ namespace Game {
return IdlePosition; return IdlePosition;
} }
private float currentSmoothV;
private const float SmoothTime = 0.2f;
private void ApproachPosition(float pos) { private void ApproachPosition(float pos) {
float result = Mathf.SmoothDamp(X, pos, ref currentSmoothV, SmoothTime, Speed); var result = Mathf.SmoothDamp(X, pos, ref currentSmoothV, SmoothTime, Speed);
transform.position = new Vector2(result, Y); transform.position = new Vector2(result, Y);
ClampInsideBorders(); ClampInsideBorders();
} }
private bool isApproaching;
private float lastDirection;
private void FixedUpdate() {
float dt = Time.fixedDeltaTime;
float target = GetTargetPosition();
float h = Mathf.Max(Speed * dt, Width / 2);
goingLeft = target < X - h;
goingRight = target > X + h;
if (goingLeft || goingRight) {
isApproaching = false;
lastDirection = goingLeft ? -1 : 1;
TryLinearMove(dt);
}
else {
if (!isApproaching) {
isApproaching = true;
currentSmoothV = Speed * lastDirection;
}
ApproachPosition(target);
}
}
} }
} }

@ -1,26 +1,29 @@
using System;
using System.Collections;
using Unity.Netcode; using Unity.Netcode;
using UnityEngine; using UnityEngine;
using UnityEngine.Serialization;
using Random = UnityEngine.Random;
namespace Game { namespace Game {
public class Ball : NetworkBehaviour { public class Ball : NetworkBehaviour {
private const float SpeedGain = 1.025f;
public Rigidbody2D Rb { get; private set; } public Rigidbody2D Rb { get; private set; }
public Player LastContactPlayer { get; private set; } public Player LastContactPlayer { get; private set; }
public bool IsPermanent { get; set; } public bool IsPermanent { get; set; }
private CircleCollider2D Collider { get; set; } private CircleCollider2D Collider { get; set; }
private const float SpeedGain = 1.025f;
public float Radius { public float Radius {
get => transform.localScale.x * Collider.radius; get => transform.localScale.x * Collider.radius;
set => transform.localScale = new Vector3(1, 1, 1) * value * 2; set => transform.localScale = new Vector3(1, 1, 1) * value * 2;
} }
private void Awake() {
Rb = GetComponent<Rigidbody2D>();
Collider = GetComponent<CircleCollider2D>();
}
private void OnCollisionEnter2D(Collision2D other) { private void OnCollisionEnter2D(Collision2D other) {
if (other.gameObject.TryGetComponent(out Player player)) if (other.gameObject.TryGetComponent(out Player player))
PlayerContact(player); PlayerContact(player);
@ -30,11 +33,5 @@ namespace Game {
LastContactPlayer = player; LastContactPlayer = player;
Rb.velocity *= SpeedGain; Rb.velocity *= SpeedGain;
} }
private void Awake() {
Rb = GetComponent<Rigidbody2D>();
Collider = GetComponent<CircleCollider2D>();
}
} }
} }

@ -1,11 +1,10 @@
using System;
using Unity.Netcode; using Unity.Netcode;
using UnityEngine; using UnityEngine;
namespace Game { namespace Game {
public abstract class Collectable : NetworkBehaviour { public abstract class Collectable : NetworkBehaviour {
private void OnTriggerEnter2D(Collider2D other) { private void OnTriggerEnter2D(Collider2D other) {
Player player = other.GetComponent<Ball>().LastContactPlayer; var player = other.GetComponent<Ball>().LastContactPlayer;
if (player != null) { if (player != null) {
Destroy(gameObject); Destroy(gameObject);
OnCollect(player); OnCollect(player);

@ -1,4 +1,3 @@
using System;
using UnityEngine; using UnityEngine;
namespace Game { namespace Game {
@ -9,8 +8,8 @@ namespace Game {
private Player thisPlayer, otherPlayer; private Player thisPlayer, otherPlayer;
private void Start() { private void Start() {
Player p1 = GameManager.Singleton.Player1; var p1 = GameManager.Singleton.Player1;
Player p2 = GameManager.Singleton.Player2; var p2 = GameManager.Singleton.Player2;
if (p1.Side == side) { if (p1.Side == side) {
thisPlayer = p1; thisPlayer = p1;
otherPlayer = p2; otherPlayer = p2;
@ -21,7 +20,7 @@ namespace Game {
} }
private void OnTriggerEnter2D(Collider2D ballCollider2D) { private void OnTriggerEnter2D(Collider2D ballCollider2D) {
Ball ball = ballCollider2D.GetComponent<Ball>(); var ball = ballCollider2D.GetComponent<Ball>();
if (ball.LastContactPlayer != null) if (ball.LastContactPlayer != null)
otherPlayer.GainScore(); otherPlayer.GainScore();
@ -31,6 +30,5 @@ namespace Game {
if (ball.IsPermanent) if (ball.IsPermanent)
GameManager.Singleton.SpawnBall(thisPlayer, true); GameManager.Singleton.SpawnBall(thisPlayer, true);
} }
} }
} }

@ -1,19 +1,34 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Unity.Netcode; using Unity.Netcode;
using Unity.VisualScripting; using Unity.VisualScripting;
using UnityEngine; using UnityEngine;
using UnityEngine.Assertions;
using Object = UnityEngine.Object; using Object = UnityEngine.Object;
using Random = UnityEngine.Random; using Random = UnityEngine.Random;
namespace Game { namespace Game {
public class GameManager : NetworkBehaviour { public class GameManager : NetworkBehaviour {
public Object ballPrefab;
public Object playerPrefab;
public Object modificationPrefab;
public ModificationProperties[] modifications;
public Object wormholePrefab;
public static GameManager Singleton { get; private set; } public static GameManager Singleton { get; private set; }
public List<Ball> Balls { get; } = new();
public Player Player1 { get; private set; }
public Player Player2 { get; private set; }
private void Awake() {
SetupPlayers();
SpawnBall(Player1, true);
}
private void OnEnable() { private void OnEnable() {
Singleton = this; Singleton = this;
@ -22,15 +37,12 @@ namespace Game {
QualitySettings.vSyncCount = 0; QualitySettings.vSyncCount = 0;
} }
public Object ballPrefab; private IEnumerator Start() {
public Object playerPrefab; while (Application.isPlaying) {
public Object modificationPrefab; yield return new WaitForSeconds(1);
public ModificationProperties[] modifications; SpawnModification();
public Object wormholePrefab; }
}
public List<Ball> Balls { get; } = new();
public Player Player1 { get; private set; }
public Player Player2 { get; private set; }
private void SetupPlayers() { private void SetupPlayers() {
Settings.Type = Type.Hybrid; Settings.Type = Type.Hybrid;
@ -67,6 +79,7 @@ namespace Game {
default: default:
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
} }
p1.Side = Side.Bottom; p1.Side = Side.Bottom;
p2.Side = Side.Top; p2.Side = Side.Top;
@ -74,25 +87,18 @@ namespace Game {
Player2 = p2; Player2 = p2;
} }
private void Awake() { private void SpawnWormhole() { }
SetupPlayers();
SpawnBall(Player1, true);
}
private void SpawnWormhole() {
}
private void SpawnModification() { private void SpawnModification() {
Vector2 pos = new Vector2(Random.Range(0, Dimensions.Singleton.PlaySize.x) - Dimensions.Singleton.PlaySize.x / 2, Random.Range(-2, 2)); var pos = new Vector2(Random.Range(0, Dimensions.Singleton.PlaySize.x) - Dimensions.Singleton.PlaySize.x / 2, Random.Range(-2, 2));
ModificationProperties properties = modifications[Random.Range(0, modifications.Length)]; var properties = modifications[Random.Range(0, modifications.Length)];
var mod = Instantiate(modificationPrefab, pos, Quaternion.identity).GetComponent<Modification>(); var mod = Instantiate(modificationPrefab, pos, Quaternion.identity).GetComponent<Modification>();
mod.Properties = properties; mod.Properties = properties;
} }
public void SpawnBall(Player towards, bool isPermanent) { public void SpawnBall(Player towards, bool isPermanent) {
const float startSpeed = 15; const float startSpeed = 15;
Vector2 position = new Vector2(0, -towards.transform.position.y * 0.5f); var position = new Vector2(0, -towards.transform.position.y * 0.5f);
var ball = Instantiate(ballPrefab, position, Quaternion.identity).GetComponent<Ball>(); var ball = Instantiate(ballPrefab, position, Quaternion.identity).GetComponent<Ball>();
ball.Rb.velocity = RandomDirectionTowards(towards) * startSpeed; ball.Rb.velocity = RandomDirectionTowards(towards) * startSpeed;
ball.IsPermanent = isPermanent; ball.IsPermanent = isPermanent;
@ -103,9 +109,9 @@ namespace Game {
private static Vector2 RandomDirectionTowards(Player player) { private static Vector2 RandomDirectionTowards(Player player) {
const float maxAngle = 45; const float maxAngle = 45;
float radians = Random.Range(-maxAngle, maxAngle) * Mathf.PI / 180; var radians = Random.Range(-maxAngle, maxAngle) * Mathf.PI / 180;
float x = Mathf.Sin(radians); var x = Mathf.Sin(radians);
float y = Mathf.Cos(radians) * player.Side switch { var y = Mathf.Cos(radians) * player.Side switch {
Side.Top => 1, Side.Top => 1,
Side.Bottom => -1, Side.Bottom => -1,
_ => throw new ArgumentOutOfRangeException() _ => throw new ArgumentOutOfRangeException()
@ -117,6 +123,5 @@ namespace Game {
Balls.Remove(ball); Balls.Remove(ball);
Destroy(ball.gameObject); Destroy(ball.gameObject);
} }
} }
} }

@ -1,9 +1,5 @@
using System;
using System.Collections; using System.Collections;
using System.Collections.Generic;
using Unity.Netcode;
using UnityEngine; using UnityEngine;
using UnityEngine.UIElements;
namespace Game { namespace Game {

@ -1,10 +1,9 @@
using UnityEngine; using UnityEngine;
using UnityEngine.Serialization;
namespace Game { namespace Game {
public enum ModType { Nerf, Buff } public enum ModType { Nerf, Buff }
public enum ModEffect { Speed, Border } public enum ModEffect { Speed, Border, Width }
[CreateAssetMenu(fileName = "Data", menuName = "ScriptableObjects/ModificationProperties", order = 0)] [CreateAssetMenu(fileName = "Data", menuName = "ScriptableObjects/ModificationProperties", order = 0)]
public class ModificationProperties : ScriptableObject { public class ModificationProperties : ScriptableObject {
@ -15,5 +14,3 @@ namespace Game {
public Sprite image; public Sprite image;
} }
} }

@ -4,7 +4,6 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using Unity.Netcode; using Unity.Netcode;
using UnityEngine; using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UIElements; using UnityEngine.UIElements;
namespace Game { namespace Game {
@ -13,55 +12,82 @@ namespace Game {
public class Player : NetworkBehaviour { public class Player : NetworkBehaviour {
public Side Side { get; set; } private const float BaseSpeed = 15;
private const float SpeedMultiplier = 1.5f;
// Unit distance from zero
private readonly float baseBorder = Dimensions.Singleton.PlaySize.x / 2 * 0.85f;
private readonly float borderSummand = Dimensions.Singleton.PlaySize.x / 2 * 0.15f;
private const float BaseWidth = 6;
private const float WidthMultiplier = 1.5f;
protected bool goingLeft, goingRight; protected bool goingLeft, goingRight;
public Side Side { get; set; }
private VisualElement Panel { get; set; } private VisualElement Panel { get; set; }
private List<ModificationProperties> Modifications { get; } = new(); private List<ModificationProperties> Modifications { get; } = new();
private int Score { get; set; } private int Score { get; set; }
// Units per second private float GetModified(ModEffect effect, float baseValue, float modValue, Func<float, float, float> combineFunc, Func<float, float> invertFunc) {
private const float BaseSpeed = 15; return Modifications.Where(m => m.effect == effect)
private const float SpeedMultiplier = 1.5f; .Aggregate(baseValue,
(current, mod) => combineFunc(current, mod.type switch {
ModType.Buff => modValue,
ModType.Nerf => invertFunc(modValue),
_ => throw new ArgumentOutOfRangeException()
})
);
}
protected float Speed { protected float Speed {
get { get {
return Modifications.Where(m => m.effect == ModEffect.Speed) float value = GetModified(ModEffect.Speed, BaseSpeed, SpeedMultiplier, (f, f1) => f * f1, f => 1 / f);
.Aggregate(BaseSpeed, (current, speedMod) => current * speedMod.type switch { return value;
ModType.Buff => SpeedMultiplier,
ModType.Nerf => 1 / SpeedMultiplier,
_ => throw new ArgumentOutOfRangeException()
});
} }
} }
// Unit distance from zero
private readonly float baseBorder = Dimensions.Singleton.PlaySize.x / 2 * 0.85f;
private readonly float borderSummand = Dimensions.Singleton.PlaySize.x / 2 * 0.15f;
protected float Border { protected float Border {
get { get {
return Mathf.Min(Modifications.Where(m => m.effect == ModEffect.Border) float value = GetModified(ModEffect.Border, baseBorder, borderSummand, (f, f1) => f + f1, f => -f);
.Aggregate(baseBorder, (current, borderMod) => current + borderMod.type switch { return Mathf.Clamp(value, Width / 2, Dimensions.Singleton.PlaySize.x / 2);
ModType.Buff => borderSummand,
ModType.Nerf => -borderSummand,
_ => throw new ArgumentOutOfRangeException()
}),
Dimensions.Singleton.PlaySize.x / 2
);
} }
} }
protected float Width => transform.localScale.x; protected float Width {
get {
float value = GetModified(ModEffect.Width, BaseWidth, WidthMultiplier, (f, f1) => f * f1, f => 1 / f);
return Mathf.Clamp(value, 0.1f, Dimensions.Singleton.PlaySize.x);
}
}
private float LeftEdge => X - Width / 2; private float LeftEdge => X - Width / 2;
private float RightEdge => X + Width / 2; private float RightEdge => X + Width / 2;
protected float X => transform.position.x; protected float X => transform.position.x;
protected float Y => transform.position.y; protected float Y => transform.position.y;
private void Update() {
transform.localScale = new Vector3(Width, 1, 1);
}
protected void Start() {
var y = Side switch {
Side.Bottom => -Dimensions.Singleton.PlaySizeBoards.y / 2,
Side.Top => Dimensions.Singleton.PlaySizeBoards.y / 2,
_ => throw new ArgumentOutOfRangeException()
};
transform.position = new Vector2(0, y);
if (Side == Side.Top)
transform.Rotate(transform.forward, 180);
Panel = GameUI.Singleton.PlayerPanel(Side);
UpdatePanel();
}
public void GainScore() { public void GainScore() {
Score++; Score++;
UpdatePanel(); UpdatePanel();
@ -73,10 +99,10 @@ namespace Game {
public IEnumerator ProcessModification(ModificationProperties properties) { public IEnumerator ProcessModification(ModificationProperties properties) {
Modifications.Add(properties); Modifications.Add(properties);
VisualElement element = GameUI.AddModification(Panel, properties); var element = GameUI.AddModification(Panel, properties);
float doNothingTime = properties.activeDuration * 0.7f; var doNothingTime = properties.activeDuration * 0.7f;
float animateTime = properties.activeDuration * 0.3f; var animateTime = properties.activeDuration * 0.3f;
yield return new WaitForSeconds(doNothingTime); yield return new WaitForSeconds(doNothingTime);
@ -100,23 +126,10 @@ namespace Game {
} }
protected void TryLinearMove(float h) { protected void TryLinearMove(float h) {
Vector2 trans = new Vector2((goingLeft ? -1 : 0) + (goingRight ? 1 : 0), 0); var trans = new Vector2((goingLeft ? -1 : 0) + (goingRight ? 1 : 0), 0);
trans *= Speed * h; trans *= Speed * h;
transform.Translate(trans, Space.World); transform.Translate(trans, Space.World);
ClampInsideBorders(); ClampInsideBorders();
} }
protected void Start() {
float y = Side switch {
Side.Bottom => -Dimensions.Singleton.PlaySizeBoards.y / 2,
Side.Top => Dimensions.Singleton.PlaySizeBoards.y / 2,
_ => throw new ArgumentOutOfRangeException()
};
transform.position = new Vector2(0, y);
if (Side == Side.Top)
transform.Rotate(transform.forward, 180);
Panel = GameUI.Singleton.PlayerPanel(Side);
UpdatePanel();
}
} }
} }

@ -33,13 +33,13 @@ namespace Game {
var keyboard = Keyboard.current; var keyboard = Keyboard.current;
switch (Side) { switch (Side) {
case Side.Top: case Side.Top:
goingLeft = keyboard.aKey.isPressed;
goingRight = keyboard.dKey.isPressed;
break;
case Side.Bottom:
goingLeft = keyboard.leftArrowKey.isPressed; goingLeft = keyboard.leftArrowKey.isPressed;
goingRight = keyboard.rightArrowKey.isPressed; goingRight = keyboard.rightArrowKey.isPressed;
break; break;
case Side.Bottom:
goingLeft = keyboard.aKey.isPressed;
goingRight = keyboard.dKey.isPressed;
break;
} }
} }

@ -6,5 +6,5 @@ namespace Game {
public struct Settings { public struct Settings {
public static Type Type; public static Type Type;
public static Difficulty AIDifficulty; public static Difficulty AIDifficulty;
}; }
} }

@ -1,4 +1,3 @@
using System;
using Unity.Netcode; using Unity.Netcode;
using UnityEngine; using UnityEngine;
@ -12,10 +11,7 @@ namespace Game {
} }
private void FixedUpdate() { private void FixedUpdate() {
foreach (var ball in GameManager.Singleton.Balls) { foreach (var ball in GameManager.Singleton.Balls) { }
}
} }
} }
} }

@ -7,16 +7,22 @@ using UnityEngine.UIElements;
public class GameUI : MonoBehaviour { public class GameUI : MonoBehaviour {
private UIDocument document; public delegate void ButtonDown(Side verticalSide, string horizontalSide);
public delegate void ButtonUp(Side side, string direction);
public static GameUI Singleton; public static GameUI Singleton;
public ButtonDown buttonDown;
public ButtonUp buttonUp;
private UIDocument document;
private List<VisualElement> PlayerPanels => document.rootVisualElement.Children().Where(e => e.ClassListContains("player_panel")).ToList();
private void Awake() { private void Awake() {
Singleton = this; Singleton = this;
document = GetComponent<UIDocument>(); document = GetComponent<UIDocument>();
PreparePlayerPanels(); PreparePlayerPanels();
} }
private List<VisualElement> PlayerPanels => document.rootVisualElement.Children().Where(e => e.ClassListContains("player_panel")).ToList();
public VisualElement PlayerPanel(Side side) { public VisualElement PlayerPanel(Side side) {
return side switch { return side switch {
Side.Top => PlayerPanels[0], Side.Top => PlayerPanels[0],
@ -26,7 +32,7 @@ public class GameUI : MonoBehaviour {
} }
public static VisualElement AddModification(VisualElement playerPanel, ModificationProperties properties) { public static VisualElement AddModification(VisualElement playerPanel, ModificationProperties properties) {
VisualElement listElement = ModsList(playerPanel, properties.type); var listElement = ModsList(playerPanel, properties.type);
VisualElement newElement = new() { VisualElement newElement = new() {
style = { style = {
@ -47,7 +53,7 @@ public class GameUI : MonoBehaviour {
} }
private void PreparePlayerPanels() { private void PreparePlayerPanels() {
float pixelHeight = Dimensions.Singleton.PanelHeightPixels; var pixelHeight = Dimensions.Singleton.PanelHeightPixels;
PlayerPanel(Side.Top).style.height = PlayerPanel(Side.Bottom).style.height = new Length(pixelHeight, LengthUnit.Pixel); PlayerPanel(Side.Top).style.height = PlayerPanel(Side.Bottom).style.height = new Length(pixelHeight, LengthUnit.Pixel);
SetupGoButton(Side.Top, "left"); SetupGoButton(Side.Top, "left");
@ -56,11 +62,6 @@ public class GameUI : MonoBehaviour {
SetupGoButton(Side.Bottom, "right"); SetupGoButton(Side.Bottom, "right");
} }
public delegate void ButtonDown(Side verticalSide, string horizontalSide);
public delegate void ButtonUp(Side side, string direction);
public ButtonDown buttonDown;
public ButtonUp buttonUp;
private Label GetGoButton(Side sideVertical, string sideHorizontal) { private Label GetGoButton(Side sideVertical, string sideHorizontal) {
return PlayerPanel(sideVertical).Q<Label>("go_" + sideHorizontal); return PlayerPanel(sideVertical).Q<Label>("go_" + sideHorizontal);
} }

@ -5,10 +5,10 @@ using UnityEngine.UIElements;
public class MenuUI : MonoBehaviour { public class MenuUI : MonoBehaviour {
private VisualElement root;
private VisualElement mainMenu, playMenu, settingsMenu; private VisualElement mainMenu, playMenu, settingsMenu;
private VisualElement root;
private void OnEnable() { private void OnEnable() {
root = GetComponent<UIDocument>().rootVisualElement; root = GetComponent<UIDocument>().rootVisualElement;
@ -39,17 +39,11 @@ public class MenuUI : MonoBehaviour {
settingsMenu.style.display = DisplayStyle.Flex; settingsMenu.style.display = DisplayStyle.Flex;
} }
private void FindPressed(ClickEvent evt) { private void FindPressed(ClickEvent evt) { }
}
private void HostPressed(ClickEvent evt) {
} private void HostPressed(ClickEvent evt) { }
private void JoinPressed(ClickEvent evt) { private void JoinPressed(ClickEvent evt) { }
}
private void BotPressed(ClickEvent evt) { private void BotPressed(ClickEvent evt) {
Settings.Type = Type.Hybrid; Settings.Type = Type.Hybrid;

@ -9,9 +9,8 @@ public class NetworkCommandLine : MonoBehaviour {
private void Start() { private void Start() {
_netManager = GetComponentInParent<NetworkManager>(); _netManager = GetComponentInParent<NetworkManager>();
if (Application.isEditor) { if (Application.isEditor)
return; return;
}
var args = GetCommandlineArgs(); var args = GetCommandlineArgs();

Loading…
Cancel
Save