From 52d3ca57bd530dfc12fa352f7e8db338dd4014a1 Mon Sep 17 00:00:00 2001 From: minenice55 Date: Mon, 18 Dec 2023 23:04:45 -0500 Subject: [PATCH] curves for meat trajectory --- Assets/Resources/Games/meatGrinder.prefab | 155 ++++++++++++++++-- Assets/Scripts/Games/MeatGrinder/Meat.cs | 114 +++++++++++-- .../Scripts/Games/MeatGrinder/MeatGrinder.cs | 49 ++++-- 3 files changed, 281 insertions(+), 37 deletions(-) diff --git a/Assets/Resources/Games/meatGrinder.prefab b/Assets/Resources/Games/meatGrinder.prefab index a06d0334b..74a844f08 100644 --- a/Assets/Resources/Games/meatGrinder.prefab +++ b/Assets/Resources/Games/meatGrinder.prefab @@ -31,7 +31,7 @@ Transform: m_Children: - {fileID: 6108272155782336078} m_Father: {fileID: 544937591884515791} - m_RootOrder: 4 + m_RootOrder: 7 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!95 &8490229799144356405 Animator: @@ -207,8 +207,13 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: f5e4b8f117d68e142ae364804ec945d3, type: 3} m_Name: m_EditorClassIdentifier: - startBeat: 0 - meatType: 0 + startPosition: {fileID: 7449121522870419912} + startPositionALt: {fileID: 4782971190098862075} + hitPosition: {fileID: 2492873460742809070} + missPosition: {fileID: 7533979600266239065} + meatFlyHeight: 4.4 + meatFlyHeightAlt: 3.64 + showAltCurve: 0 meats: - {fileID: -9124615959790710355, guid: adbc5b443bdc23e469209cc4f602d17d, type: 3} - {fileID: -4224877059003839859, guid: adbc5b443bdc23e469209cc4f602d17d, type: 3} @@ -234,6 +239,37 @@ Animator: m_AllowConstantClipSamplingOptimization: 1 m_KeepAnimatorStateOnDisable: 0 m_WriteDefaultValuesOnDisable: 0 +--- !u!1 &344575782839395223 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4782971190098862075} + m_Layer: 0 + m_Name: MeatStartPosAlt + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4782971190098862075 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 344575782839395223} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: -25, y: 4, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 544937591884515791} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &471691632641964123 GameObject: m_ObjectHideFlags: 0 @@ -354,7 +390,7 @@ Transform: - {fileID: 8401927975952338944} - {fileID: 4149366084315632544} m_Father: {fileID: 544937591884515791} - m_RootOrder: 2 + m_RootOrder: 5 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!95 &8591333713642157499 Animator: @@ -491,7 +527,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1113279616887289042} - m_RootOrder: 1 + m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!212 &1495044360246153142 SpriteRenderer: @@ -1268,6 +1304,9 @@ Transform: m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: + - {fileID: 7449121522870419912} + - {fileID: 4782971190098862075} + - {fileID: 2492873460742809070} - {fileID: 2932735252070355021} - {fileID: 4773680412020886884} - {fileID: 7318783844351071632} @@ -1299,6 +1338,37 @@ MonoBehaviour: cartBeat: 1.7976931348623157e+308 cartLength: 0 cartSpider: 0 +--- !u!1 &2707801222513399487 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2492873460742809070} + m_Layer: 0 + m_Name: MeatHitPos + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2492873460742809070 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2707801222513399487} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 2.67, y: -0.29, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 544937591884515791} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &3432557403964010436 GameObject: m_ObjectHideFlags: 0 @@ -1413,7 +1483,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1113279616887289042} - m_RootOrder: 3 + m_RootOrder: 4 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!212 &5553728808981219509 SpriteRenderer: @@ -1805,7 +1875,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1113279616887289042} - m_RootOrder: 0 + m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!212 &2744829955141411905 SpriteRenderer: @@ -2003,7 +2073,7 @@ Transform: - {fileID: 6181761682720629539} - {fileID: 267186869494077813} m_Father: {fileID: 544937591884515791} - m_RootOrder: 3 + m_RootOrder: 6 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!95 &8611037719571569512 Animator: @@ -2055,6 +2125,7 @@ Transform: m_LocalScale: {x: 0.71, y: 0.71, z: 0.71} m_ConstrainProportionsScale: 0 m_Children: + - {fileID: 7533979600266239065} - {fileID: 612581083556194476} - {fileID: 5343923506035710304} - {fileID: 789457928850181753} @@ -2213,7 +2284,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!4 &2932735252070355021 Transform: m_ObjectHideFlags: 0 @@ -2228,6 +2299,37 @@ Transform: m_Children: - {fileID: 4035877382569997717} m_Father: {fileID: 544937591884515791} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &5713667132269415626 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7533979600266239065} + m_Layer: 0 + m_Name: MeatMissPos + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &7533979600266239065 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 5713667132269415626} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: -1.7, y: -0.11, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1113279616887289042} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &5905250936621372194 @@ -2260,7 +2362,7 @@ Transform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1113279616887289042} - m_RootOrder: 2 + m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!212 &8851705103136115615 SpriteRenderer: @@ -2541,7 +2643,7 @@ Transform: - {fileID: 3600842165078314753} - {fileID: 4316543350587402345} m_Father: {fileID: 544937591884515791} - m_RootOrder: 1 + m_RootOrder: 4 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &6809729426963480446 GameObject: @@ -3083,6 +3185,37 @@ SpriteRenderer: m_WasSpriteAssigned: 1 m_MaskInteraction: 0 m_SpriteSortPoint: 0 +--- !u!1 &8541881261740536524 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7449121522870419912} + m_Layer: 0 + m_Name: MeatStartPos + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &7449121522870419912 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8541881261740536524} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: -16, y: -4, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 544937591884515791} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &8600032524474789486 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/Games/MeatGrinder/Meat.cs b/Assets/Scripts/Games/MeatGrinder/Meat.cs index ddd4bf4fd..f468408d0 100644 --- a/Assets/Scripts/Games/MeatGrinder/Meat.cs +++ b/Assets/Scripts/Games/MeatGrinder/Meat.cs @@ -9,8 +9,16 @@ namespace HeavenStudio.Games.Scripts_MeatGrinder { public class Meat : MonoBehaviour { - public double startBeat; - public MeatType meatType; + [SerializeField] Transform startPosition; + [SerializeField] Transform startPositionALt; + [SerializeField] Transform hitPosition; + [SerializeField] Transform missPosition; + [SerializeField] float meatFlyHeight = 1f; + [SerializeField] float meatFlyHeightAlt = 1f; + [SerializeField] bool showAltCurve; + + [NonSerialized] public double startBeat; + [NonSerialized] public MeatType meatType; private string meatTypeStr; private bool isHit = false; @@ -52,15 +60,41 @@ namespace HeavenStudio.Games.Scripts_MeatGrinder private void Update() { + Conductor cond = Conductor.instance; // if (Input.GetKey(KeyCode.G)) { // Insane. // anim.enabled = true; // } Debug.Log(sr.sprite.name); - if (!isHit) { - float normalizedBeat = Conductor.instance.GetPositionFromBeat(startBeat, 1); - float newX = Mathf.LerpUnclamped(-14f, 1.7f, normalizedBeat); - Debug.Log(newX); - transform.position = new Vector3(newX, -1.2f); + if (!isHit) + { + double startTime = cond.GetSongPosFromBeat(startBeat); + double hitTime = cond.GetSongPosFromBeat(startBeat + 1); + double missTime = cond.GetSongPosFromBeat(startBeat + 1) + MeatGrinder.ngLateTime; + double currentTime = cond.songPositionAsDouble; + Vector3 lastPos = transform.position; + Vector3 startPos = meatType == MeatType.LightMeat ? startPositionALt.position : startPosition.position; + + float hitAlongMissRatio = Vector3.Dot((startPos - missPosition.position), (startPos - hitPosition.position)); + hitAlongMissRatio /= Vector3.Dot((startPos - missPosition.position), (startPos - missPosition.position)); + Vector3 hitOnMissPos = startPos + (missPosition.position - startPos) * hitAlongMissRatio; + + float totalProg = (float)((currentTime - startTime) / (missTime - startTime)); + + if (currentTime >= hitTime) + { + float prog = (float)((currentTime - hitTime) / (missTime - hitTime)); + transform.position = Vector3.Lerp(hitOnMissPos, missPosition.position, prog); + } + else + { + float prog = (float)((currentTime - startTime) / (hitTime - startTime)); + transform.position = Vector3.Lerp(startPos, hitOnMissPos, prog); + } + float yMul = totalProg * 2f - 1f; + float yWeight = -(yMul * yMul) + 1f; + transform.position += Vector3.up * (meatType == MeatType.LightMeat ? meatFlyHeightAlt : meatFlyHeight) * yWeight; + // point towards the next position + transform.right = transform.position - lastPos; // anim.DoNormalizedAnimation("MeatThrown", normalizedBeat); } @@ -72,7 +106,7 @@ namespace HeavenStudio.Games.Scripts_MeatGrinder isHit = true; game.TackAnim.SetBool("tackMeated", false); anim.DoScaledAnimationAsync(meatTypeStr + "Hit", 0.5f); - + bool isBarely = state is >= 1f or <= -1f; game.bossAnnoyed = isBarely; @@ -95,12 +129,72 @@ namespace HeavenStudio.Games.Scripts_MeatGrinder private void Nothing(PlayerActionEvent caller) { } - public void SetSprite() { + public void SetSprite() + { sr.sprite = meats[(int)meatType]; } - public void DestroySelf() { + public void DestroySelf() + { Destroy(gameObject); } + + /// + /// Callback to draw gizmos that are pickable and always drawn. + /// + private void OnDrawGizmos() + { + // draw a line showing the direction from the miss position to the hit position + if (startPosition == null) return; + if (startPositionALt == null) return; + + Vector3 startPos = showAltCurve ? startPositionALt.position : startPosition.position; + if (hitPosition != null && missPosition != null && startPos != null) + { + Gizmos.color = Color.red; + Gizmos.DrawLine(startPos, hitPosition.position); + Gizmos.color = Color.blue; + Gizmos.DrawLine(startPos, missPosition.position); + Gizmos.color = Color.green; + Vector3 direction = (hitPosition.position - missPosition.position).normalized; + Gizmos.DrawRay(missPosition.position, direction * 10); + + // project start position -> hit position onto start position -> miss position + float hitAlongMissRatio = Vector3.Dot((startPos - missPosition.position), (startPos - hitPosition.position)); + hitAlongMissRatio /= Vector3.Dot((startPos - missPosition.position), (startPos - missPosition.position)); + Gizmos.color = Color.yellow; + Gizmos.DrawRay(startPos, (missPosition.position - startPos) * hitAlongMissRatio); + + DrawCurveGizmo(startPos, missPosition.position, Vector3.up * (showAltCurve ? meatFlyHeightAlt : meatFlyHeight), Color.yellow, 0.1f); + } + } + + void DrawCurveGizmo(Vector3 start, Vector3 end, Vector3 height, Color colour, float interval) + { + Gizmos.color = colour; + Vector3 lastPos = start; + Vector3 pos; + float t, yMul, yWeight; + for (float i = 0; i < 1; i += interval) + { + t = i; + pos = Vector3.Lerp(start, end, t); + + yMul = t * 2f - 1f; + yWeight = -(yMul * yMul) + 1f; + + pos += height * yWeight; + Gizmos.DrawLine(lastPos, pos); + lastPos = pos; + } + t = 1f; + pos = end; + + yMul = t * 2f - 1f; + yWeight = -(yMul * yMul) + 1f; + + pos += height * yWeight; + Gizmos.DrawLine(lastPos, pos); + } } } diff --git a/Assets/Scripts/Games/MeatGrinder/MeatGrinder.cs b/Assets/Scripts/Games/MeatGrinder/MeatGrinder.cs index 824d1c370..bc2df3792 100644 --- a/Assets/Scripts/Games/MeatGrinder/MeatGrinder.cs +++ b/Assets/Scripts/Games/MeatGrinder/MeatGrinder.cs @@ -83,9 +83,9 @@ namespace HeavenStudio.Games.Loaders MeatGrinder.instance.CartGuy(e.beat, e.length, e["spider"]); }, resizable = true, - defaultLength = 8, + defaultLength = 16, parameters = new List() { - new Param("spider", false, "Spider", "Put a spider in the box?"), + new Param("spider", false, "On Phone", "Put a spider in the box?"), } }, } @@ -151,13 +151,14 @@ namespace HeavenStudio.Games } public static PlayerInput.InputAction InputAction_Press = - new("PcoMeatPress", new int[] { IAPressCat, IAFlickCat, IAPressCat }, + new("PcoMeatPress", new int[] { IAPressCat, IAPressCat, IAPressCat }, IA_PadAny, IA_TouchBasicPress, IA_BatonBasicPress); - + private void Awake() { instance = this; SetupBopRegion("meatGrinder", "bop", "bossBop"); + MeatBase.SetActive(false); } private void Update() @@ -174,13 +175,15 @@ namespace HeavenStudio.Games if (passedTurns.Count > 0) { - foreach (var pass in passedTurns) { + foreach (var pass in passedTurns) + { PassTurnStandalone(pass); } passedTurns.Clear(); } - if (cartLength != 0) { + if (cartLength != 0) + { // CartGuyParentAnim.gameObject.SetActive(true); if (cartSpider) CartGuyAnim.Play("Phone", 0, 0); float beatPos = Conductor.instance.GetPositionFromBeat(cartBeat, cartLength); @@ -194,7 +197,8 @@ namespace HeavenStudio.Games { BossAnim.DoScaledAnimationAsync(bossAnnoyed ? "BossMiss" : "Bop", 0.5f); } - if (!cartSpider && CartGuyParentAnim.gameObject.activeSelf) { + if (!cartSpider && CartGuyParentAnim.gameObject.activeSelf) + { CartGuyAnim.DoScaledAnimationAsync("Bop", 0.5f); } } @@ -217,7 +221,8 @@ namespace HeavenStudio.Games public override void OnPlay(double beat) { RiqEntity cg = GameManager.instance.Beatmap.Entities.Find(c => c.datamodel == "meatGrinder/cartGuy"); - if (cg != null) { + if (cg != null) + { CartGuy(cg.beat, cg.length, cg["spider"]); } } @@ -263,10 +268,14 @@ namespace HeavenStudio.Games { SoundByte.PlayOneShotGame(sfxName + "startSignal", beat - 1, forcePlay: true); - if (GameManager.instance.currentGame == "meatGrinder") { + if (GameManager.instance.currentGame == "meatGrinder") + { instance.StartInterval(beat, length, beat, autoPassTurn); - } else { - queuedIntervals.Add(new QueuedInterval() { + } + else + { + queuedIntervals.Add(new QueuedInterval() + { beat = beat, length = length, autoPassTurn = autoPassTurn @@ -286,8 +295,10 @@ namespace HeavenStudio.Games { double eventBeat = allCallEvents[i].beat; - if (eventBeat >= gameSwitchBeat) { - actions.Add(new BeatAction.Action(eventBeat, delegate { + if (eventBeat >= gameSwitchBeat) + { + actions.Add(new BeatAction.Action(eventBeat, delegate + { BossAnim.DoScaledAnimationAsync("BossCall", 0.5f); SoundByte.PlayOneShotGame(sfxName + "signal"); })); @@ -312,15 +323,19 @@ namespace HeavenStudio.Games SoundByte.PlayOneShotGame(sfxName + "toss"); Meat meat = Instantiate(MeatBase, transform).GetComponent(); + meat.gameObject.SetActive(true); meat.startBeat = beat; meat.meatType = bacon ? Meat.MeatType.BaconBall : Meat.MeatType.DarkMeat; } public static void PrePassTurn(double beat) { - if (GameManager.instance.currentGame == "meatGrinder") { + if (GameManager.instance.currentGame == "meatGrinder") + { instance.PassTurnStandalone(beat); - } else { + } + else + { passedTurns.Add(beat); } } @@ -341,8 +356,10 @@ namespace HeavenStudio.Games for (int i = 0; i < allCallEvents.Count; i++) { double relativeBeat = allCallEvents[i].beat - intervalBeat; - meatCalls.Add(new BeatAction.Action(beat + relativeBeat - 1, delegate { + meatCalls.Add(new BeatAction.Action(beat + relativeBeat - 1, delegate + { Meat Meat = Instantiate(MeatBase, transform).GetComponent(); + Meat.gameObject.SetActive(true); Meat.startBeat = beat + relativeBeat - 1; Meat.meatType = Meat.MeatType.LightMeat; }));