Skip to content

Instantly share code, notes, and snippets.

@benanil
Created December 29, 2021 15:46
Show Gist options
  • Save benanil/bba3a1afab5e8200aac5ce7398758b2d to your computer and use it in GitHub Desktop.
Save benanil/bba3a1afab5e8200aac5ce7398758b2d to your computer and use it in GitHub Desktop.
using UnityEngine;
using Assets.scripts;
using System.Collections;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class RopeController : MonoBehaviour
{
public float DistanceBetweenLines = 2;
public float swingSpeed = 5;
public float swingAmount = 5;
public Transform lineConnection;
public bool isSwingTest;
[Range(-1, 1)]
public float swingTest;
public static KidIK[] kids;
public static byte kidCount;
public Transform EndPlane;
public GameObject max;
private void OnValidate() {
if (!Application.isPlaying)
{
if (isSwingTest)
{
Swing(swingTest);
}
else
{
// useful for aligning line height
for (int i = 1; i < LineRenderer.positionCount; i++)
{
Vector3 newPos = LineRenderer.GetPosition(0);
newPos.y -= DistanceBetweenLines * i;
LineRenderer.SetPosition(i, newPos);
}
}
}
}
private void Start()
{
Instance = this;
kids = new KidIK[LineRenderer.positionCount * 2];
ended = false;
kidCount = 0;
}
// alignment and climbing for girls
private void Update() {
if (ended) return;
for (byte i = 0, j = 0; i < kidCount; i++) // j is second layer girls
{
KidIK kid = kids[i];
if (kid == null) break;
Vector3 targetLine, footPos;
if (i > 3) {
var animator = kid.animator;
if (!animator.IsInTransition(0) && animator.GetCurrentAnimatorClipInfo(0)[0].clip.name.Equals("Climb Rope", System.StringComparison.OrdinalIgnoreCase))
{
animator.SetTrigger("Wall");
}
targetLine = LineRenderer.GetPosition(j + 1);
footPos = LineRenderer.GetPosition(j + 2);
j++;
}
else
{
targetLine = LineRenderer.GetPosition(i + 1);
footPos = LineRenderer.GetPosition(i + 2);
}
Vector3 girlUp = (targetLine - kid.transform.position).normalized;
Vector3 oldPos = new Vector3(footPos.x, kid.transform.position.y, footPos.z - (i > 3 ? .1f : 0));
oldPos.y = HeliController.state == State.descenting ? footPos.y : Mathf.Lerp(oldPos.y, footPos.y, Time.deltaTime * .5f);
kid.transform.position = oldPos;
kid.transform.eulerAngles = new Vector3(0, 0, Mathf.Atan2(girlUp.x, girlUp.y) * -Mathf.Rad2Deg);
kid.animator.speed = Mathf.Abs(footPos.y - kid.transform.position.y) > 0.1f ? 1 : 0;
}
Swing(-Joystick.Horizontal);
}
public void Bang()
{
for (int i = 0; i < kidCount; i++)
{
kids[i].gameObject.SetActive(false);
}
}
// swing physics for rope
// value must be in range of -1 and 1
public void Swing(float value)
{
if (Mathf.Abs(Joystick.Horizontal) < 0.1 && Application.isPlaying)
{
for (int i = 0; i < LineRenderer.positionCount; i++)
{
Vector3 newPos = lineConnection.position;
float t = i / (float)LineRenderer.positionCount;
value = Mathf.Sin(Time.time * 3);
newPos.y -= DistanceBetweenLines * i;
newPos.x += EaseInQuad(0, value * (swingAmount / 10 ), t);
LineRenderer.SetPosition(i, newPos);
}
}
else
{
for (int i = 0; i < LineRenderer.positionCount; i++)
{
Vector3 newPos = lineConnection.position;
newPos.y -= DistanceBetweenLines * i;
float t = i / (float)LineRenderer.positionCount;
newPos.x += EaseInQuad(0, value * swingAmount, t + Mathf.Sin(Time.time * 5) * (0.05f * t)); // the sin thing is just wiggling
LineRenderer.SetPosition(i, newPos);
}
}
}
internal bool TryAddPeople(GameObject kid)
{
if (kidCount < kids.Length -1)
{
kidCount++;
// find empty slot
for (byte i = 0; i < kids.Length; i++)
{
if (kids[i] == null)
{
kids[i] = kid.GetComponent<KidIK>();
try
{
kids[i].transform.GetChild(2).gameObject.SetActive(false);
} finally { }
return true;
}
}
}
kid.GetComponent<KidIK>().SetRagdoll(true);
kid.tag = "dropped people";
if (maxCoroutine != null) StopCoroutine(maxCoroutine);
maxCoroutine = StartCoroutine(ShowMaxText());
return false;
}
Coroutine maxCoroutine;
IEnumerator ShowMaxText()
{
max.SetActive(true);
yield return new WaitForSecondsRealtime(1.2f);
max.SetActive(false);
}
internal void DropPeople()
{
if (kidCount > 0)
{
KidIK kid = default;
// find last climbed girl
for (int i = kids.Length - 1; i >= 0; i--)
{
if (kids[i] != null)
{
kid = kids[i];
kids[i] = null;
break;
}
}
kid.Drop();
kid.tag = "dropped people";
kid.GetComponent<CapsuleCollider>().enabled = true;
kid.GetComponent<Rigidbody>().isKinematic = false;
kid.GetComponent<Rigidbody>().AddForce(Random.insideUnitSphere * 5);
kidCount--;
}
}
public static void EndLine()
{
Instance.Swing(0); // rope musn't move at the end
// end of the game circale alignment of the girls
for (int i = 0; i < kidCount; i++)
{
kids[i].animator.speed = 1;
kids[i].animator.SetTrigger("Dance");
kids[i].transform.position = Instance.EndPlane.position + (new Vector3(Mathf.Sin(i * 0.6f), 0.6f, Mathf.Cos(i * 0.6f)) * .5f);
kids[i].transform.eulerAngles = new Vector3(0, Mathf.Atan2(-Mathf.Sin(i * 0.6f), -Mathf.Cos(i * 0.6f)) * Mathf.Rad2Deg, 0);
}
ended = true;
}
// https://gist.github.com/cjddmut/d789b9eb78216998e95c
public static float EaseInQuad(float start, float end, float value)
{
end -= start;
return end * value * value + start;
}
private static T GetIfNull<T>(T value) where T : Component {
if (value == null) value = FindObjectOfType<T>();
return value;
}
private static bool ended;
private readonly FloatingJoystick _joystick;
private FloatingJoystick Joystick => GetIfNull(_joystick);
public LineRenderer LineRenderer
{
get => GetComponent<LineRenderer>();
}
public static RopeController Instance;
}
@benanil
Copy link
Author

benanil commented Dec 29, 2021

first

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment