This commit is contained in:
kimrdd 2024-02-03 18:02:43 +01:00
commit 17be113edc
16 changed files with 389 additions and 48 deletions

View File

@ -20,7 +20,7 @@ AnimatorStateTransition:
m_TransitionDuration: 0.25
m_TransitionOffset: 0
m_ExitTime: 0.75
m_HasExitTime: 1
m_HasExitTime: 0
m_HasFixedDuration: 1
m_InterruptionSource: 0
m_OrderedInterruption: 1

View File

@ -188,6 +188,7 @@ GameObject:
- component: {fileID: 5467488512035376674}
- component: {fileID: 3878447480781341932}
- component: {fileID: 1749848915408613053}
- component: {fileID: 1949941092232239315}
m_Layer: 7
m_Name: Player1
m_TagString: Player
@ -224,7 +225,6 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 3dbdb849a2f5df14d9e109a7776c5ac0, type: 3}
m_Name:
m_EditorClassIdentifier:
player: 0
moveSpeed: 70
stepCooldown: 0.2
stepVibrationTime: 0.05
@ -295,6 +295,7 @@ MonoBehaviour:
anchor: {fileID: 1170758327458850867}
body: {fileID: 1508323898269695585}
locked: 0
playerInput: {fileID: 1949941092232239315}
--- !u!114 &3878447480781341932
MonoBehaviour:
m_ObjectHideFlags: 0
@ -319,7 +320,25 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: b69b92d72c7244443854899c4b700d9c, type: 3}
m_Name:
m_EditorClassIdentifier:
playerInput: {fileID: 1949941092232239315}
otherPlayerAttack: {fileID: 0}
playerMovement: {fileID: 651446758998956252}
joint: {fileID: 5467488512035376674}
initialDrag: 0
--- !u!114 &1949941092232239315
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3120938410244321186}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: de340bb967770a7499e140a52a287f84, type: 3}
m_Name:
m_EditorClassIdentifier:
playerNumber: 0
movement: {x: 0, y: 0}
whipAttack: 0
ropeLengthShrinken: 0
ropeLengthExtend: 0

View File

@ -868,6 +868,7 @@ MonoBehaviour:
anchor: {fileID: 625885769}
body: {fileID: 0}
locked: 0
playerInput: {fileID: 0}
--- !u!1 &646449334
GameObject:
m_ObjectHideFlags: 0
@ -2080,6 +2081,9 @@ MonoBehaviour:
m_Bits: 1
pullForce: 65
xyGravityDampScalor: 1
ropeExtendSpeed: 15
ropeShrinkSpeed: 15
ropeMaxLength: 0
lineRenderer: {fileID: 1647138191}
--- !u!4 &1647138193
Transform:
@ -2334,6 +2338,10 @@ PrefabInstance:
propertyPath: otherPlayerAttack
value:
objectReference: {fileID: 465041015}
- target: {fileID: 1949941092232239315, guid: 99a6ff8b9591949439b620b13bd249a4, type: 3}
propertyPath: playerNumber
value: 1
objectReference: {fileID: 0}
- target: {fileID: 3120938410244321186, guid: 99a6ff8b9591949439b620b13bd249a4, type: 3}
propertyPath: m_Name
value: Player 2

View File

@ -12,6 +12,6 @@ public class EnemyList : ScriptableObject
[Serializable]
public struct EnemyPrefabInfo
{
public GameObject prefab;
public GameObject[] prefabs;
public float Difficulty;
}

View File

@ -2,51 +2,125 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UIElements;
public class NewBehaviourScript : MonoBehaviour
{
// Shared
public int Wave = 0;
public float difficulty = 0;
public float difficulty = 1;
// Inspector
[SerializeField] private float difficultyIncreasePerWave = 0.1f;
[SerializeField] private float WaveTime;
[SerializeField] private EnemyList enemyList;
[SerializeField] private float WaveTime = 20f;
[SerializeField] private List<float> enemyDifficulties;
[SerializeField] private float SpawnRadius = 10;
[SerializeField] private int NumEnemies = 6;
// Private
private bool nextWaveRequested = false;
private float timer = 0f;
private Camera mainCam;
private GameObject SpawnedEnenmyHolder;
[SerializeField] private List<EnemyPrefabInfo> enemyList;
public void StartSpawning() => StartCoroutine(SpawnLoop());
public void StartNextWave() => nextWaveRequested = true;
private bool SpawnerStarted = false;
private IEnumerator SpawnLoop()
private void Start()
{
while (true)
mainCam = Camera.main;
SpawnedEnenmyHolder = new GameObject("SpawnedEnenmyHolder");
for (int i = 0; i < 6; i++)
{
yield return new WaitUntil(() => timer > WaveTime || nextWaveRequested);
enemyList.Add(new EnemyPrefabInfo() { Difficulty = i+1, prefabs = Resources.LoadAll<GameObject>("Enemies/" + (i+1)) });
}
StartSpawning();
}
public void Update()
{
if (SpawnerStarted)
timer += Time.deltaTime;
if (timer > WaveTime || nextWaveRequested)
{
Task.Factory.StartNew(() => { Task.Delay(100); timer = 0; });
SpawnWave(difficulty);
Wave++;
difficulty *= difficultyIncreasePerWave + 1;
nextWaveRequested = false;
timer = 0;
}
}
public void StartSpawning() => SpawnerStarted = true;
public void StartNextWave() => nextWaveRequested = true;
void SpawnWave(float difficulty)
{
var decendingList = enemyList.List.OrderByDescending(x => x.Difficulty).ToArray();
SpawnStrongestFirst(difficulty);
//if (Wave != 0 && Wave % 10 == 0)
// SpawnStrongestFirst(difficulty);
//else
// SpawnRandom(difficulty);
}
void SpawnStrongestFirst(float difficulty)
{
var decendingList = enemyList.Where(x => x.Difficulty < difficulty).OrderByDescending(x => x.Difficulty).ToArray();
for (int i = 0; i < decendingList.Length; i++)
{
while (difficulty > decendingList[i].Difficulty)
{
Instantiate(decendingList[i].prefab);
GameObject enemy = Instantiate(decendingList[i].prefabs[UnityEngine.Random.Range(0, decendingList[i].prefabs.Length)], GetRandomPointOnCircle(mainCam.transform.position, SpawnRadius), Quaternion.identity, SpawnedEnenmyHolder.transform);
difficulty -= decendingList[i].Difficulty;
}
}
}
void SpawnRandom(float difficulty)
{
while (difficulty > 0.5f) // Spawn until difficulty is less than 0.5f
{
var validEnemies = enemyList.Where(x => x.Difficulty <= difficulty).ToArray();
var enemyToSpawn = validEnemies[UnityEngine.Random.Range(0, validEnemies.Length)];
difficulty -= enemyToSpawn.Difficulty;
GameObject enemy = Instantiate(enemyToSpawn.prefabs[UnityEngine.Random.Range(0, enemyToSpawn.prefabs.Length)], GetRandomPointOnCircle(mainCam.transform.position, SpawnRadius), Quaternion.identity, SpawnedEnenmyHolder.transform);
}
}
public Vector3 GetRandomPointOnCircle(Vector3 location, float radius)
{
float angle = UnityEngine.Random.Range(0f, 360f);
float radians = Mathf.Deg2Rad * angle;
Vector3 position = transform.position;
float x = position.x + radius * Mathf.Cos(radians);
float y = position.y + radius * Mathf.Sin(radians);
return new Vector3(x, y, position.z);
}
#if UNITY_EDITOR
private void OnDrawGizmosSelected()
{
Gizmos.color = Color.green;
Gizmos.DrawWireSphere(transform.position, SpawnRadius);
for (int i = 0; i < 10; i++)
{
Gizmos.DrawWireSphere(GetRandomPointOnCircle(transform.position, SpawnRadius), 0.25f);
}
}
#endif
}

View File

@ -1,6 +1,7 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class MainMenuTransitionAnimation : MonoBehaviour
{
@ -13,5 +14,20 @@ public class MainMenuTransitionAnimation : MonoBehaviour
public void AnimationMainMenuStart()
{
animator.SetTrigger("Start");
StartCoroutine(WaitBeforeSceneChange());
}
private IEnumerator WaitBeforeSceneChange()
{
var animInfo = animator.GetCurrentAnimatorStateInfo(0);
while (!(animInfo.normalizedTime >= 0.99f && animInfo.IsName("MenuTransition")))
{
animInfo = animator.GetCurrentAnimatorStateInfo(0);
yield return new WaitForSecondsRealtime(0.1f);
}
SceneManager.LoadScene(1);
}
}

View File

@ -0,0 +1,55 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System;
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerInput : MonoBehaviour
{
[SerializeField] private int playerNumber;
public Vector2 movement;
public Vector2 look;
public Gamepad controller { get; private set; }
public bool whipAttack;
public event Action<int> ropeLengthShrinken;
public event Action<int> ropeLengthExtend;
public int PlayerNum => playerNumber;
private void Awake()
{
controller = Gamepad.all.ElementAtOrDefault(playerNumber);
if (controller == null)
{
Debug.LogWarning($"No Gamepad found for player {playerNumber + 1}");
}
}
private void Update()
{
if (controller != null)
{
movement.x = controller.leftStick.x.ReadValue();
movement.y = controller.leftStick.y.ReadValue();
look.x = controller.rightStick.x.ReadValue();
look.y = controller.rightStick.y.ReadValue();
whipAttack = controller.buttonWest.IsPressed();
if (controller.rightShoulder.IsPressed()) ropeLengthShrinken?.Invoke(playerNumber);
if (controller.leftShoulder.IsPressed()) ropeLengthExtend?.Invoke(playerNumber);
}
else
{
movement.x = Input.GetAxisRaw("Horizontal");
movement.y = Input.GetAxisRaw("Vertical");
whipAttack = Input.GetKey(KeyCode.B);
}
//Debug.Log($"player {playerNumber}: move {movement}");
}
}

View File

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

View File

@ -4,13 +4,11 @@ using UnityEngine;
using UnityEngine.InputSystem;
using System.Linq;
[RequireComponent(typeof(PlayerInput))]
public class PlayerMovement : MonoBehaviour
{
public int player = 0;
public float moveSpeed = 5f;
private Rigidbody2D rb;
private Vector2 movement;
private Gamepad playerController;
private bool right = false;
@ -30,28 +28,19 @@ public class PlayerMovement : MonoBehaviour
[SerializeField]
private float maxWhipMoveSpeed = 30f;
private PlayerInput playerInput;
private void Start()
{
rb = GetComponent<Rigidbody2D>();
playerController = Gamepad.all.ElementAtOrDefault(player);
playerInput = GetComponent<PlayerInput>();
StartCoroutine(ToggleWithDelay());
}
void Update()
{
if (playerController != null)
{
movement.x = playerController.leftStick.x.ReadValue();
movement.y = playerController.leftStick.y.ReadValue();
}
else
{
movement.x = Input.GetAxisRaw("Horizontal");
movement.y = Input.GetAxisRaw("Vertical"); ;
}
if (movement.x != 0 || movement.y != 0)
if (playerInput.movement != Vector2.zero)
{
RumbleWalk();
GetComponent<PlayerAnimationHandler>().Run();
@ -66,31 +55,31 @@ public class PlayerMovement : MonoBehaviour
Vector2 ropeDir = whipAttack.otherPlayerAttack.joint.position - whipAttack.joint.position;
Vector2 tangent = new Vector2(-ropeDir.y, ropeDir.x).normalized;
rb.AddForce(Vector2.Dot(movement, tangent) * tangent * whipMoveSpeed);
rb.AddForce(Vector2.Dot(playerInput.movement, tangent) * tangent * whipMoveSpeed);
rb.velocity = Vector2.ClampMagnitude(rb.velocity, maxWhipMoveSpeed);
}
else if (whipAttack.IsWhippingOtherPlayer)
{
movement = Vector2.zero;
playerInput.movement = Vector2.zero;
}
else
{
rb.AddForce(movement * moveSpeed);
rb.AddForce(playerInput.movement * moveSpeed);
}
}
private void RumbleWalk()
{
if (vibrate && playerController != null)
if (vibrate && playerInput.controller != null)
{
if (right)
{
rumble.GetComponent<RumbleManager>().RumblePulse(0.0f, 0.004f, stepVibrationTime, player);
rumble.GetComponent<RumbleManager>().RumblePulse(0.0f, 0.004f, stepVibrationTime, playerInput.PlayerNum);
right = false;
}
else if (!right)
{
rumble.GetComponent<RumbleManager>().RumblePulse(0.004f, 0.0f, stepVibrationTime, player);
rumble.GetComponent<RumbleManager>().RumblePulse(0.004f, 0.0f, stepVibrationTime, playerInput.PlayerNum);
right = true;
}
vibrate = false;

View File

@ -6,11 +6,11 @@ using System.Linq;
public class RopeWhipAttack : MonoBehaviour
{
[SerializeField] PlayerInput playerInput;
public RopeWhipAttack otherPlayerAttack;
public PlayerMovement playerMovement;
public RopeJoint joint;
Gamepad controller;
public bool IsWhippingOtherPlayer => joint.locked;
public bool IsBeingWhipped => otherPlayerAttack.joint.locked;
@ -19,16 +19,14 @@ public class RopeWhipAttack : MonoBehaviour
private void Awake()
{
initialDrag = joint.body.drag;
controller = Gamepad.all.ElementAtOrDefault(playerMovement.player);
}
private void Update()
{
// Other player is whip attacking
if (otherPlayerAttack.joint.locked) return;
if (controller == null)
return;
if (controller.rightShoulder.IsPressed())
if (playerInput.whipAttack)
{
joint.locked = true;
otherPlayerAttack.joint.body.drag = 0f;

View File

@ -7,6 +7,13 @@ public class RopeBuilder
List<Point> points = new();
List<Stick> sticks = new();
public RopeBuilder() { }
public RopeBuilder(List<Point> points, List<Stick> sticks)
{
this.points = points;
this.sticks = sticks;
}
public RopeBuilder AddPoint(Point point)
{
points.Add(point);

View File

@ -7,6 +7,7 @@ public class RopeJoint : MonoBehaviour
public Transform anchor;
public Rigidbody2D body;
public bool locked = false;
public PlayerInput playerInput;
public Vector3 position => anchor.position;
}

View File

@ -24,7 +24,7 @@ public class RopeSimulator : MonoBehaviour
RopeJoint start, end;
[SerializeField]
int subDivision = 50;
float subDivision = 50f;
[SerializeField]
float collisionCheckDist = 0.5f;
@ -50,6 +50,12 @@ public class RopeSimulator : MonoBehaviour
[SerializeField]
float xyGravityDampScalor = 1f;
[SerializeField, Range(0f, 20f)]
public float ropeExtendSpeed, ropeShrinkSpeed;
[SerializeField]
public float ropeMaxLength, ropeMinLength;
[Header("Rendering")]
[SerializeField] LineRenderer lineRenderer;
@ -72,11 +78,86 @@ public class RopeSimulator : MonoBehaviour
// .ConnectPoints(2, 3)
// .ConnectPoints(3, 4)
// .Build();
Rebuild();
start.playerInput.ropeLengthShrinken += ShrinkenRope;
end.playerInput.ropeLengthShrinken += ShrinkenRope;
start.playerInput.ropeLengthExtend += ExtendRope;
end.playerInput.ropeLengthExtend += ExtendRope;
}
void ShrinkenRope(int playerNumber)
{
int prevSubDivision = (int) subDivision;
subDivision -= ropeShrinkSpeed * Time.deltaTime;
if (subDivision < ropeMinLength)
subDivision = ropeMinLength;
if (prevSubDivision - (int)subDivision > 0) return;
// Shrink from start
if (playerNumber == start.playerInput.PlayerNum)
{
rope.sticks.Clear();
rope.points.RemoveAt(0);
var builder = new RopeBuilder(rope.points, new List<Stick>());
// Re-gen sticks
for (int i = 0; i < (int) subDivision; i++)
{
builder.ConnectPoints(i, i + 1);
}
rope = builder.Build();
}
// Shrink from end
else if (playerNumber == end.playerInput.PlayerNum)
{
rope.points.RemoveAt(rope.points.Count - 2);
rope.sticks.Clear();
var builder = new RopeBuilder(rope.points, new List<Stick>());
// Re-gen sticks
for (int i = 0; i < (int)subDivision; i++)
{
builder.ConnectPoints(i, i + 1);
}
rope = builder.Build();
}
CreateOrderArray();
}
void ExtendRope(int playerNumber)
{
subDivision += ropeExtendSpeed * Time.deltaTime;
if (subDivision > ropeMaxLength)
subDivision = ropeMaxLength;
Rebuild();
}
private void OnDestroy()
{
start.playerInput.ropeLengthShrinken -= ShrinkenRope;
end.playerInput.ropeLengthShrinken -= ShrinkenRope;
start.playerInput.ropeLengthExtend -= ExtendRope;
end.playerInput.ropeLengthExtend -= ExtendRope;
}
private void Rebuild()
{
Debug.Log("rebuild");
ropeCollidersParent.DestroyChildren();
RopeBuilder builder = new RopeBuilder();
builder.AddPoint(new Point(start.position, locked: true));
for (int i = 1; i < subDivision; i++)
for (int i = 1; i < (int) subDivision; i++)
{
Vector3 pointPos = Vector3.Lerp(start.position, end.position, (float)i / (float)subDivision);
Vector3 pointPos = Vector3.Lerp(start.position, end.position, (float)i / (float)(int)subDivision);
//Debug.Log($"pos: {pointPos}, t={i / subDivision}");
Debug.DrawRay(pointPos, (end.position - start.position).normalized);
builder.AddPoint(new Point(pointPos));
@ -84,7 +165,7 @@ public class RopeSimulator : MonoBehaviour
builder.AddPoint(new Point(end.position, locked: true));
for (int i = 0; i < subDivision; i++)
for (int i = 0; i < (int) subDivision; i++)
{
builder.ConnectPointsWithDesiredLength(i, i + 1, desiredLength: distBetweenRopePoints);
}
@ -108,6 +189,7 @@ public class RopeSimulator : MonoBehaviour
private void Update()
{
ShrinkenRope(1);
colliderToSquezeForce.Clear();
rope.points.First().position = start.position;

View File

@ -0,0 +1,67 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Upgrade
{
public string name = "MT";
public int amount = 0;
public Upgrade(string n)
{
name = n;
}
}
public class Upgrades
{
public Upgrade mopUpgrade = new Upgrade("Mop Radius");
public Upgrade speedUpgrade = new Upgrade("Move speed");
public Upgrade ropeUpgrade = new Upgrade("Longer Rope");
public Upgrade healthUpgrade = new Upgrade("More health");
public Upgrade damageUpgrade = new Upgrade("More rope damage");
public Upgrade bloodUpgrade = new Upgrade("MORE BLOOD!");
public Upgrade reelUpgrade = new Upgrade("Faster rope reel speed");
}
public class Upgrader : MonoBehaviour
{
public GameObject player1;
public GameObject player2;
public BloodComputeShader bloodManager;
public RopeSimulator rope;
public Upgrades upgrades { get; private set; }
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
/// Increases mop radius by 10%
public void UpgradeMopSize()
{
bloodManager.CleanRadius *= 1.1f;
}
/// Increases move speed by 10%
public void UpgradeSpeed()
{
player1.GetComponent<PlayerMovement>().moveSpeed *= 1.1f;
player2.GetComponent<PlayerMovement>().moveSpeed *= 1.1f;
}
public void RopeUpgrade() {
// todo: public methods
}
// public void
}

View File

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

View File

@ -6,6 +6,9 @@ EditorBuildSettings:
serializedVersion: 2
m_Scenes:
- enabled: 1
path: Assets/Scenes/SampleScene.unity
guid: 8c9cfa26abfee488c85f1582747f6a02
path: Assets/Scenes/MainMenu.unity
guid: 33b308b02cb61b643b15ad93698b00ee
- enabled: 1
path: Assets/Scenes/Bloody Mary.unity
guid: dbc458177844bf1ceae76a97e08d3140
m_configObjects: {}