From 12c70d43115d6c5432c07266d5b4ba424a465741 Mon Sep 17 00:00:00 2001 From: Jenny Crowe Date: Mon, 21 Feb 2022 23:43:24 -0700 Subject: [PATCH] Rhythm Rally: Added "toss ball" action. Paddler now also tosses ball when you miss. --- Assets/Resources/Games/rhythmRally.prefab | 234 ++++++++++++++++-- .../Scripts/Games/RhythmRally/RhythmRally.cs | 68 ++++- Assets/Scripts/Minigames.cs | 1 + 3 files changed, 286 insertions(+), 17 deletions(-) diff --git a/Assets/Resources/Games/rhythmRally.prefab b/Assets/Resources/Games/rhythmRally.prefab index e8058d7f..9ebe4579 100644 --- a/Assets/Resources/Games/rhythmRally.prefab +++ b/Assets/Resources/Games/rhythmRally.prefab @@ -492,6 +492,53 @@ SpriteRenderer: m_WasSpriteAssigned: 1 m_MaskInteraction: 0 m_SpriteSortPoint: 0 +--- !u!1 &1904528871620876249 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7123869637936811309} + - component: {fileID: 8077471796495908552} + m_Layer: 10 + m_Name: Point 2 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &7123869637936811309 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1904528871620876249} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0.03, z: 2.079} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 9077140957458773248} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &8077471796495908552 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1904528871620876249} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b0cca3244f403c24f819a870f31cdc29, type: 3} + m_Name: + m_EditorClassIdentifier: + curve: {fileID: 10327036049174933} + handleType: 0 + leftHandleLocalPosition: {x: 0, y: 0.4, z: 0} + rightHandleLocalPosition: {x: -0, y: -0.4, z: -0} --- !u!1 &2034480636994138272 GameObject: m_ObjectHideFlags: 0 @@ -909,7 +956,7 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 3667855830336901894} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: -0.167, y: 0.03, z: 2.079} + m_LocalPosition: {x: 0, y: 0.03, z: 2.079} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 1845910055258765698} @@ -1082,7 +1129,7 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 4262381482084858378} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0.1246, y: 0, z: -2.0983} + m_LocalPosition: {x: 0, y: 0, z: -2.0983} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 1845910055258765698} @@ -1198,6 +1245,155 @@ MonoBehaviour: handleType: 1 leftHandleLocalPosition: {x: 0, y: 0.55, z: 0.88} rightHandleLocalPosition: {x: 0, y: 0.45, z: -0.4549628} +--- !u!1 &5476235103473015094 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3680569986833971144} + - component: {fileID: 4326544752565425689} + m_Layer: 10 + m_Name: Point 1 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &3680569986833971144 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5476235103473015094} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0.425, z: 2.079} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 9077140957458773248} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &4326544752565425689 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5476235103473015094} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b0cca3244f403c24f819a870f31cdc29, type: 3} + m_Name: + m_EditorClassIdentifier: + curve: {fileID: 10327036049174933} + handleType: 0 + leftHandleLocalPosition: {x: -0, y: -0, z: 0} + rightHandleLocalPosition: {x: 0, y: 0, z: -0} +--- !u!1 &5571437366825965275 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1512601611263843253} + - component: {fileID: 9099385795814476598} + m_Layer: 10 + m_Name: Point 0 + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1512601611263843253 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5571437366825965275} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0.03, z: 2.079} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 9077140957458773248} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &9099385795814476598 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5571437366825965275} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b0cca3244f403c24f819a870f31cdc29, type: 3} + m_Name: + m_EditorClassIdentifier: + curve: {fileID: 10327036049174933} + handleType: 0 + leftHandleLocalPosition: {x: 0, y: -0.4, z: 0} + rightHandleLocalPosition: {x: -0, y: 0.4, z: -0} +--- !u!1 &6399112775887748606 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 9077140957458773248} + - component: {fileID: 10327036049174933} + m_Layer: 10 + m_Name: TossCurve + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &9077140957458773248 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6399112775887748606} + m_LocalRotation: {x: -0, y: 0.029666247, z: -0, w: 0.9995599} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1512601611263843253} + - {fileID: 3680569986833971144} + - {fileID: 7123869637936811309} + m_Father: {fileID: 227248172885675867} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 3.4, z: 0} +--- !u!114 &10327036049174933 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6399112775887748606} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 066a41e004f415b4eb74d5e61a2aadbe, type: 3} + m_Name: + m_EditorClassIdentifier: + curveColor: {r: 0, g: 1, b: 0, a: 1} + startPointColor: {r: 1, g: 0, b: 0, a: 1} + endPointColor: {r: 0, g: 0, b: 1, a: 1} + sampling: 25 + keyPoints: + - {fileID: 9099385795814476598} + - {fileID: 4326544752565425689} + - {fileID: 8077471796495908552} + normalizedTime: 0.5 --- !u!1 &6878547494759724039 GameObject: m_ObjectHideFlags: 0 @@ -1222,7 +1418,7 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 6878547494759724039} - m_LocalRotation: {x: 0, y: 1, z: 0, w: 0} + m_LocalRotation: {x: 0, y: 0.9995599, z: -0, w: -0.029666154} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: @@ -1231,7 +1427,7 @@ Transform: - {fileID: 2008423486364638542} m_Father: {fileID: 227248172885675867} m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 180, z: 0} + m_LocalEulerAnglesHint: {x: 0, y: 183.4, z: 0} --- !u!114 &2715991891693212353 MonoBehaviour: m_ObjectHideFlags: 0 @@ -1442,7 +1638,7 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 7366375554666111783} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0.0433, y: 0.0281, z: -2.0833} + m_LocalPosition: {x: 0, y: 0.0281, z: -2.0833} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 2492954830728060394} @@ -1515,8 +1711,10 @@ MonoBehaviour: cameraPos: {fileID: 6509993024069972873} ball: {fileID: 1668061868608559892} ballShadow: {fileID: 7207398029238753263} + ballTrail: {fileID: 4238313091838702597} serveCurve: {fileID: 6371738825610660614} returnCurve: {fileID: 2715991891693212353} + tossCurve: {fileID: 10327036049174933} ballHitFX: {fileID: 8205255986357351166} playerAnim: {fileID: 9089436218394572253} opponentAnim: {fileID: 4559734961269837672} @@ -1524,8 +1722,11 @@ MonoBehaviour: started: 0 missed: 0 served: 0 + tossing: 0 serveBeat: 0 targetBeat: 0 + tossBeat: 0 + tossLength: 0 paddlers: {fileID: 2423225589381961324} --- !u!1 &8205255986357351166 GameObject: @@ -1638,6 +1839,7 @@ Transform: m_Children: - {fileID: 1845910055258765698} - {fileID: 2492954830728060394} + - {fileID: 9077140957458773248} m_Father: {fileID: 4631944531018638297} m_RootOrder: 4 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} @@ -1846,16 +2048,16 @@ PrefabInstance: objectReference: {fileID: 0} m_RemovedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: cebeb8610d89fb34688750080a285ddb, type: 3} ---- !u!1 &1065418898597387318 stripped -GameObject: - m_CorrespondingSourceObject: {fileID: 919132149155446097, guid: cebeb8610d89fb34688750080a285ddb, type: 3} - m_PrefabInstance: {fileID: 146447278275535207} - m_PrefabAsset: {fileID: 0} --- !u!4 &397144130134918796 stripped Transform: m_CorrespondingSourceObject: {fileID: -8679921383154817045, guid: cebeb8610d89fb34688750080a285ddb, type: 3} m_PrefabInstance: {fileID: 146447278275535207} m_PrefabAsset: {fileID: 0} +--- !u!1 &1065418898597387318 stripped +GameObject: + m_CorrespondingSourceObject: {fileID: 919132149155446097, guid: cebeb8610d89fb34688750080a285ddb, type: 3} + m_PrefabInstance: {fileID: 146447278275535207} + m_PrefabAsset: {fileID: 0} --- !u!95 &4559734961269837672 Animator: serializedVersion: 3 @@ -2500,9 +2702,9 @@ PrefabInstance: objectReference: {fileID: 0} m_RemovedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: cebeb8610d89fb34688750080a285ddb, type: 3} ---- !u!1 &7954728381481796141 stripped -GameObject: - m_CorrespondingSourceObject: {fileID: 919132149155446097, guid: cebeb8610d89fb34688750080a285ddb, type: 3} +--- !u!4 &7291063904195614871 stripped +Transform: + m_CorrespondingSourceObject: {fileID: -8679921383154817045, guid: cebeb8610d89fb34688750080a285ddb, type: 3} m_PrefabInstance: {fileID: 7108288251017691004} m_PrefabAsset: {fileID: 0} --- !u!4 &2075964892847120759 stripped @@ -2510,9 +2712,9 @@ Transform: m_CorrespondingSourceObject: {fileID: 9109367605909020171, guid: cebeb8610d89fb34688750080a285ddb, type: 3} m_PrefabInstance: {fileID: 7108288251017691004} m_PrefabAsset: {fileID: 0} ---- !u!4 &7291063904195614871 stripped -Transform: - m_CorrespondingSourceObject: {fileID: -8679921383154817045, guid: cebeb8610d89fb34688750080a285ddb, type: 3} +--- !u!1 &7954728381481796141 stripped +GameObject: + m_CorrespondingSourceObject: {fileID: 919132149155446097, guid: cebeb8610d89fb34688750080a285ddb, type: 3} m_PrefabInstance: {fileID: 7108288251017691004} m_PrefabAsset: {fileID: 0} --- !u!95 &9089436218394572253 diff --git a/Assets/Scripts/Games/RhythmRally/RhythmRally.cs b/Assets/Scripts/Games/RhythmRally/RhythmRally.cs index 13b5c4d4..0216ce5f 100644 --- a/Assets/Scripts/Games/RhythmRally/RhythmRally.cs +++ b/Assets/Scripts/Games/RhythmRally/RhythmRally.cs @@ -19,8 +19,10 @@ namespace RhythmHeavenMania.Games.RhythmRally [Header("Ball and curve info")] public GameObject ball; public GameObject ballShadow; + public TrailRenderer ballTrail; public BezierCurve3D serveCurve; public BezierCurve3D returnCurve; + public BezierCurve3D tossCurve; public GameObject ballHitFX; @@ -33,8 +35,11 @@ namespace RhythmHeavenMania.Games.RhythmRally public bool started; public bool missed; public bool served; + public bool tossing; public float serveBeat; public float targetBeat; + public float tossBeat; + public float tossLength; private bool inPose; public Paddlers paddlers; @@ -152,6 +157,13 @@ namespace RhythmHeavenMania.Games.RhythmRally curveToUse.transform.localScale = new Vector3(1f, curveHeight, 1f); ball.transform.position = curveToUse.GetPoint(Mathf.Clamp(curvePosition, 0, 1)); } + else + { + if (tossing) + { + TossUpdate(tossBeat, tossLength); + } + } // TODO: Make conditional so ball shadow only appears when over table. ballShadow.transform.position = new Vector3(ball.transform.position.x, -0.399f, ball.transform.position.z); @@ -195,7 +207,20 @@ namespace RhythmHeavenMania.Games.RhythmRally { opponentPrepping = true; if ((opponentState.IsName("Swing") && opponentAnim.IsAnimationNotPlaying()) || (!opponentState.IsName("Swing") && !opponentState.IsName("Ready1"))) + { opponentAnim.Play("Ready1"); + + // Toss ball if it fell off the table. + if (missed && !tossing) + { + float tossHeight = 3f; + + if (rallySpeed == RallySpeed.Slow || rallySpeed == RallySpeed.Fast) + tossHeight = 6f; + + Toss(hitBeat + beatDur1, beatDur2, tossHeight); + } + } // If player never swung and is still in ready state, snap them out of it. if (missed && playerState.IsName("Ready1")) @@ -203,6 +228,13 @@ namespace RhythmHeavenMania.Games.RhythmRally } } } + else + { + if (tossing) + { + TossUpdate(tossBeat, tossLength); + } + } // Paddler bop animation. @@ -213,7 +245,7 @@ namespace RhythmHeavenMania.Games.RhythmRally if (!playerPrepping && (playerAnim.IsAnimationNotPlaying() || playerState.IsName("Idle") || playerState.IsName("Beat"))) playerAnim.Play("Beat", 0, 0); - if (!opponentPrepping && !opponentServing && (opponentAnim.IsAnimationNotPlaying() || opponentState.IsName("Idle") || opponentState.IsName("Beat"))) + if (!opponentPrepping && !opponentServing && !tossing && (opponentAnim.IsAnimationNotPlaying() || opponentState.IsName("Idle") || opponentState.IsName("Beat"))) opponentAnim.Play("Beat", 0, 0); } } @@ -233,6 +265,7 @@ namespace RhythmHeavenMania.Games.RhythmRally missed = false; started = true; opponentServing = true; + tossing = false; serveBeat = beat; rallySpeed = speed; @@ -263,6 +296,39 @@ namespace RhythmHeavenMania.Games.RhythmRally paddlers.ResetState(); } + public void Toss(float beat, float length, float height, bool firstToss = false) + { + tossCurve.transform.localScale = new Vector3(1f, height, 1f); + tossBeat = beat; + tossLength = length; + tossing = true; + + if (firstToss) + { + opponentAnim.Play("Ready1"); + Jukebox.PlayOneShotGame("rhythmRally/Whistle"); + } + + StartCoroutine(TossTrailCo()); + } + + // Hide the trail for one frame to avoid shenanigans when teleporting the ball. + IEnumerator TossTrailCo() + { + ballTrail.emitting = false; + TossUpdate(tossBeat, tossLength); + + yield return null; + + ballTrail.emitting = true; + } + + private void TossUpdate(float beat, float duration) + { + var tossPosition = Conductor.instance.GetPositionFromBeat(beat, duration); + ball.transform.position = tossCurve.GetPoint(Mathf.Clamp(tossPosition, 0, 1)); + } + public void Pose() { playerAnim.Play("Pose", 0, 0); diff --git a/Assets/Scripts/Minigames.cs b/Assets/Scripts/Minigames.cs index bcaf01af..b4e5c952 100644 --- a/Assets/Scripts/Minigames.cs +++ b/Assets/Scripts/Minigames.cs @@ -231,6 +231,7 @@ namespace RhythmHeavenMania new Minigame("rhythmRally", "Rhythm Rally \n[WIP don't use]", "00e700", true, false, new List() { new GameAction("bop", delegate { RhythmRally.instance.Bop(eventCaller.currentEntity.beat, eventCaller.currentEntity.length); }, 0.5f, true), + new GameAction("toss ball", delegate { RhythmRally.instance.Toss(eventCaller.currentEntity.beat, eventCaller.currentEntity.length, 6f, true); }, 2f), new GameAction("rally", delegate { RhythmRally.instance.Serve(eventCaller.currentEntity.beat, RhythmRally.RallySpeed.Normal); }, 4f, true), new GameAction("slow rally", delegate { RhythmRally.instance.Serve(eventCaller.currentEntity.beat, RhythmRally.RallySpeed.Slow); }, 8f, true), new GameAction("fast rally", delegate { RhythmRally.instance.PrepareFastRally(eventCaller.currentEntity.beat, RhythmRally.RallySpeed.Fast); }, 6f),