Air Rally Rework/Finalization (#512)

* smol tweaks

* air rally is now recursive and has the bg sheet

* everything has been reworked now

* oopsie

* toss + constant anims

* catch

* catch and alt ba bum bum bum

* day/night cycle, needs accurate colors

* enter, daynight fixes and start on cloud density options

* cloud density options

* fixes

* islands basics

* islands progress

* island tweaks

* more tweaks

* final tweaks

* Birds implemented

* snowflakes, cloud speed changes, snowflake speed changes and forward pose

* rainbow added, so gay

* el background clouds

* oop

* boat and balloons

* Trees added

* reduced tree amounts

---------

Co-authored-by: ev <85412919+evdial@users.noreply.github.com>
This commit is contained in:
Rapandrasmus
2023-07-31 04:32:04 +02:00
committed by GitHub
parent 83d24b661e
commit fc5614dae2
83 changed files with 30725 additions and 7385 deletions

File diff suppressed because it is too large Load Diff

View File

@ -6,15 +6,35 @@ namespace HeavenStudio.Games.Scripts_AirRally
{
public class Cloud : MonoBehaviour
{
private enum Type
{
Cloud,
Snowflake,
Tree
}
[SerializeField] private CloudsManager manager;
[SerializeField] private Type type = Type.Cloud;
[SerializeField] Sprite[] sprites;
[SerializeField] Vector3 spawnRange;
[SerializeField] float baseSpeed = 1f;
[SerializeField] float fadeDist = 10f;
[SerializeField] float lifeTime = 6f;
[SerializeField] float fadeInTime = 0.25f;
[SerializeField] private Animator treeAnim;
[System.Serializable]
public struct Weight
{
public int weight;
public int type;
}
[SerializeField] private Weight[] weights;
private int weightSum;
Camera cam;
SpriteRenderer spriteRenderer;
[SerializeField] private SpriteRenderer spriteRenderer;
[SerializeField] private SpriteRenderer crownRenderer;
[SerializeField] private SpriteRenderer reflectionRenderer;
private float reflectionOpacity = 1f;
float time = 0f;
public bool isWorking = false;
@ -22,25 +42,41 @@ namespace HeavenStudio.Games.Scripts_AirRally
public void Init()
{
cam = GameCamera.GetCamera();
spriteRenderer = GetComponent<SpriteRenderer>();
if (type == Type.Tree)
{
reflectionOpacity = reflectionRenderer.color.a;
reflectionRenderer.color = new Color(1, 1, 1, 0);
crownRenderer.color = new Color(1, 1, 1, 0);
}
spriteRenderer.color = new Color(1, 1, 1, 0);
if (weights.Length > 0) weightSum = weights[0].weight;
}
// Update is called once per frame
void Update()
{
time += Time.deltaTime;
transform.position += Vector3.forward * -baseSpeed * Time.deltaTime;
time += Time.deltaTime * manager.speedMult;
transform.position += Vector3.forward * -baseSpeed * manager.speedMult * Time.deltaTime;
// get distance to camera
float dist = Vector3.Distance(cam.transform.position, transform.position);
if (dist <= fadeDist)
{
spriteRenderer.color = new Color(1, 1, 1, Mathf.Clamp01(dist / fadeDist));
if (type == Type.Tree)
{
crownRenderer.color = new Color(1, 1, 1, Mathf.Clamp01(dist / fadeDist));
reflectionRenderer.color = new Color(1, 1, 1, Mathf.Clamp(dist / fadeDist, 0, reflectionOpacity));
}
}
else if (time < fadeInTime)
{
spriteRenderer.color = new Color(1, 1, 1, Mathf.Clamp01(time/fadeInTime));
if (type == Type.Tree)
{
crownRenderer.color = new Color(1, 1, 1, Mathf.Clamp01(time / fadeInTime));
reflectionRenderer.color = new Color(1, 1, 1, Mathf.Clamp(time / fadeInTime, 0, reflectionOpacity));
}
}
if (time > lifeTime)
@ -48,6 +84,11 @@ namespace HeavenStudio.Games.Scripts_AirRally
isWorking = false;
gameObject.SetActive(false);
spriteRenderer.color = new Color(1, 1, 1, 0);
if (type == Type.Tree)
{
reflectionRenderer.color = new Color(1, 1, 1, 0);
crownRenderer.color = new Color(1, 1, 1, 0);
}
}
}
@ -56,7 +97,34 @@ namespace HeavenStudio.Games.Scripts_AirRally
isWorking = true;
time = 0f;
gameObject.SetActive(true);
spriteRenderer.sprite = sprites[Random.Range(0, sprites.Length)];
switch (type)
{
case Type.Cloud:
spriteRenderer.sprite = sprites[Random.Range(0, sprites.Length)];
break;
case Type.Snowflake:
transform.localEulerAngles = new Vector3(0, 0, Random.Range(0f, 360f));
break;
case Type.Tree:
int randomNumber = Random.Range(0, weightSum);
for (int i = weights.Length - 1; i >= 0; i--)
{
if (randomNumber < weights[i].weight)
{
if (weights[i].type != 5)
{
treeAnim.Play("Tree" + weights[i].type, 0, 0);
}
else
{
treeAnim.Play("Threefish", 0, 0);
}
break;
}
}
break;
default: break;
}
transform.position = origin;
transform.position += new Vector3(Random.Range(-spawnRange.x, spawnRange.x), Random.Range(-spawnRange.y, spawnRange.y), Random.Range(-spawnRange.z, spawnRange.z));
if (prebake)
@ -65,6 +133,11 @@ namespace HeavenStudio.Games.Scripts_AirRally
transform.position += Vector3.forward * -baseSpeed * time;
float dist = Vector3.Distance(cam.transform.position, transform.position);
spriteRenderer.color = new Color(1, 1, 1, Mathf.Clamp01(dist / fadeDist));
if (type == Type.Tree)
{
crownRenderer.color = new Color(1, 1, 1, Mathf.Clamp01(dist / fadeDist));
reflectionRenderer.color = new Color(1, 1, 1, Mathf.Clamp(dist / fadeDist, 0, reflectionOpacity));
}
}
}
}

View File

@ -1,3 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
@ -9,8 +10,10 @@ namespace HeavenStudio.Games.Scripts_AirRally
[SerializeField] Transform cloudRoot;
[SerializeField] GameObject cloudPrefab;
[SerializeField] int maxCloudAmt = 32;
[SerializeField] int cloudsToPreBake = 10;
[SerializeField] float cloudRepeatRate = 0.1f;
[SerializeField] float prebakeMultiplier = 2.5f;
[SerializeField] private float cloudsPerSecond = 67;
private float cloudRepeatRate = 0.1f;
[NonSerialized] public float speedMult = 1f;
Cloud[] pool;
@ -18,8 +21,13 @@ namespace HeavenStudio.Games.Scripts_AirRally
float lastTime = 0f;
// Start is called before the first frame update
void Start()
public void Init()
{
SetCloudRate();
int cloudsToPreBake = Mathf.RoundToInt(cloudsPerSecond * prebakeMultiplier);
if (maxCloudAmt < cloudsToPreBake) maxCloudAmt = cloudsToPreBake;
pool = new Cloud[maxCloudAmt];
for (int i = 0; i < maxCloudAmt; i++)
{
@ -61,5 +69,23 @@ namespace HeavenStudio.Games.Scripts_AirRally
GetAvailableCloud()?.StartCloud(cloudRoot.position, false);
}
}
public void SetCloudsPerSecond(int cloudsPerSec)
{
cloudsPerSecond = cloudsPerSec;
SetCloudRate();
}
private void SetCloudRate()
{
if (cloudsPerSecond == 0)
{
cloudRepeatRate = float.MaxValue;
}
else
{
cloudRepeatRate = 1 / cloudsPerSecond;
}
}
}
}

View File

@ -0,0 +1,48 @@
using Starpelly;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace HeavenStudio.Games.Scripts_AirRally
{
public class IslandsManager : MonoBehaviour
{
[Header("Properties")]
[SerializeField] private float loopMult = 1f;
[NonSerialized] public float endZ;
public float speedMult = 1f;
[NonSerialized] public float additionalSpeedMult = 1;
[SerializeField] private RvlIsland[] islands;
private float fullLengthZ;
private void Start()
{
speedMult /= loopMult;
float[] allZ = new float[islands.Length];
for (int i = 0; i < islands.Length; i++)
{
islands[i].manager = this;
allZ[i] = islands[i].startPos.z;
}
if (islands.Length > 0)
{
float minValueZ = Mathf.Min(allZ);
float maxValueZ = Mathf.Max(allZ);
fullLengthZ = maxValueZ - minValueZ;
endZ = -fullLengthZ * loopMult;
foreach (var island in islands)
{
island.normalizedOffset = 1 - Mathp.Normalize(island.startPos.z, minValueZ, maxValueZ);
island.normalizedOffset /= loopMult;
}
}
}
}
}

View File

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

View File

@ -0,0 +1,62 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace HeavenStudio.Games.Scripts_AirRally
{
public class RvlBirds : MonoBehaviour
{
[Header("Birds")]
[SerializeField] private SpriteRenderer[] srs;
[SerializeField] private Animator[] birdAnims;
[Header("Properties")]
[SerializeField] private float birdSpeedX = 0.2f;
[SerializeField] private float birdSpeedZ = 0.5f;
[NonSerialized] public float speedMultX = 1f;
[NonSerialized] public float speedMultZ = 1f;
[SerializeField] private bool isRainbow = false;
private double fadeInBeat = double.MinValue;
private float defaultOpacity;
private void Awake()
{
if (srs.Length != 0) defaultOpacity = srs[0].color.a;
foreach (var anim in birdAnims)
{
anim.Play("Idle", 0, UnityEngine.Random.Range(0f, 1f));
}
RainbowUpdate();
}
private void Update()
{
if (!Conductor.instance.isPlaying) return;
float moveX = birdSpeedX * speedMultX * Time.deltaTime;
float moveZ = birdSpeedZ * speedMultZ * Time.deltaTime;
transform.position = new Vector3(transform.position.x - moveX, transform.position.y, transform.position.z - moveZ);
if (isRainbow) RainbowUpdate();
}
private void RainbowUpdate()
{
float normalizedBeat = Conductor.instance.GetPositionFromBeat(fadeInBeat, 1);
float newA = Mathf.Lerp(0, defaultOpacity, normalizedBeat);
foreach (var sr in srs)
{
sr.color = new Color(1, 1, 1, newA);
}
}
public void FadeIn(double beat)
{
fadeInBeat = beat;
}
}
}

View File

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

View File

@ -0,0 +1,44 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
namespace HeavenStudio.Games.Scripts_AirRally
{
public class RvlIsland : MonoBehaviour
{
[NonSerialized] public IslandsManager manager;
[NonSerialized] public Vector3 startPos;
private float normalized = 0f;
[NonSerialized] public float normalizedOffset = 0f;
[SerializeField] private SpriteRenderer[] srs;
private Tween[] fadeInTweens;
private void Awake()
{
startPos = transform.position;
fadeInTweens = new Tween[srs.Length];
}
private void Update()
{
if (!Conductor.instance.isPlaying) return;
float moveZ = Mathf.LerpUnclamped(startPos.z, startPos.z + manager.endZ, normalized);
transform.position = new Vector3(transform.position.x, transform.position.y, moveZ);
normalized += manager.speedMult * manager.additionalSpeedMult * Time.deltaTime;
if (transform.position.z < manager.endZ)
{
normalized = -normalizedOffset;
for(int i = 0; i < srs.Length; i++)
{
srs[i].color = new Color(1, 1, 1, 0);
if (fadeInTweens[i] != null) fadeInTweens[i].Kill(true);
fadeInTweens[i] = srs[i].DOColor(Color.white, 0.4f);
}
}
}
}
}

View File

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

View File

@ -1,9 +1,8 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using NaughtyBezierCurves;
using HeavenStudio.Util;
using System;
namespace HeavenStudio.Games.Scripts_AirRally
{
@ -13,20 +12,25 @@ namespace HeavenStudio.Games.Scripts_AirRally
[SerializeField] Transform OtherTarget;
[SerializeField] float TargetHeight;
[SerializeField] float TargetHeightLong;
[SerializeField] float TargetHeightToss = 2.5f;
[SerializeField] ParticleSystem hitEffect;
public double startBeat;
public double flyBeats;
private Rigidbody2D rb;
public bool flyType;
[NonSerialized] public double startBeat;
[NonSerialized] public double flyBeats;
[NonSerialized] public bool flyType;
bool miss = false;
public float flyPos;
public bool isReturning;
[NonSerialized] public float flyPos;
[NonSerialized] public bool isReturning;
[NonSerialized] public bool isTossed = false;
AirRally game;
private void Awake()
{
game = AirRally.instance;
rb = GetComponent<Rigidbody2D>();
}
void Start()
@ -41,8 +45,13 @@ namespace HeavenStudio.Games.Scripts_AirRally
Vector3 startPos = isReturning ? PlayerTarget.position : OtherTarget.position;
Vector3 endPos = isReturning ? OtherTarget.position : PlayerTarget.position;
if (isTossed)
{
startPos = OtherTarget.position;
endPos = OtherTarget.position;
}
Vector3 lastPos = transform.position;
if (!GetComponent<Rigidbody2D>().simulated)
if (!rb.simulated)
{
flyPos = cond.GetPositionFromBeat(startBeat, flyBeats);
@ -50,25 +59,34 @@ namespace HeavenStudio.Games.Scripts_AirRally
float yMul = flyPos * 2f - 1f;
float yWeight = -(yMul*yMul) + 1f;
transform.position += Vector3.up * yWeight * (flyType ? TargetHeightLong : TargetHeight);
if (isTossed) transform.position += Vector3.up * yWeight * TargetHeightToss;
else transform.position += Vector3.up * yWeight * (flyType ? TargetHeightLong : TargetHeight);
}
// calculates next position
{
float rotation;
if (flyPos > 0.5)
if (isTossed)
{
Vector3 midPos = Vector3.LerpUnclamped(startPos, endPos, 0.5f);
midPos += Vector3.up * (flyType ? TargetHeightLong : TargetHeight);
Vector3 direction = (transform.position - midPos).normalized;
rotation = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
rotation = Mathf.Lerp(90, -90, flyPos);
}
else
{
Vector3 direction = (transform.position - lastPos).normalized;
rotation = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
if (flyPos > 0.5)
{
Vector3 midPos = Vector3.LerpUnclamped(startPos, endPos, 0.5f);
midPos += Vector3.up * (flyType ? TargetHeightLong : TargetHeight);
Vector3 direction = (transform.position - midPos).normalized;
rotation = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
}
else
{
Vector3 direction = (transform.position - lastPos).normalized;
rotation = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
}
}
this.transform.eulerAngles = new Vector3(0, 0, rotation - 90f);
}