using Unity.Mathematics; using UnityEngine; public class HaseBewegung : MonoBehaviour { const float MAX_HINTERLAUF_ANGLE = 20; const float HINTERLAUF_TIME = .7f; public float jumpVelocityX; public float maxJumpVelocityY; public float waitingTimeBetweenJumps; public float earRigidity; public float maxEarAngularVelocity; public GameObject hinterlauf; public GameObject loeffel; public GameObject kopf; private float xTarget; private uint collisions; private float nextJumpTime; private bool lookingRight; private float jumpStartTime; private float lastEarAngle; private Rigidbody2D rigidBody; public void GoToXPosition(float x){ xTarget = x; rigidBody.constraints = RigidbodyConstraints2D.FreezeRotation; } public void Turn(){ GetComponent().flipX = lookingRight; loeffel.GetComponent().flipX = lookingRight; hinterlauf.GetComponent().flipX = lookingRight; kopf.GetComponent().flipX = lookingRight; lookingRight = !lookingRight; Vector3 v = loeffel.transform.localPosition; v.x = -v.x; loeffel.transform.localPosition = v; v = hinterlauf.transform.localPosition; v.x = -v.x; hinterlauf.transform.localPosition = v; v = kopf.transform.localPosition; v.x = -v.x; kopf.transform.localPosition = v; loeffel.transform.localRotation = Quaternion.Inverse(loeffel.transform.localRotation); hinterlauf.transform.localRotation = Quaternion.Inverse(hinterlauf.transform.localRotation); kopf.transform.localRotation = Quaternion.Inverse(kopf.transform.localRotation); transform.rotation = Quaternion.Inverse(transform.rotation); } // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { rigidBody = GetComponent(); collisions = 0; lookingRight = true; nextJumpTime = 0f; jumpStartTime = 0; lastEarAngle = 0; } // Update is called once per frame void Update() { if (!targetReached()) { if (collisions > 0){ if (Time.time > nextJumpTime){ StartJump(); nextJumpTime = 0; } else if (nextJumpTime == 0){ nextJumpTime = Time.time + waitingTimeBetweenJumps; rigidBody.linearVelocityX = 0; } } } else { rigidBody.linearVelocityX = 0; rigidBody.linearVelocityY = math.min(rigidBody.linearVelocityY, 0f); rigidBody.constraints = RigidbodyConstraints2D.FreezePositionX | RigidbodyConstraints2D.FreezeRotation; } float earAngle; if (rigidBody.linearVelocityX != 0){ earAngle = math.acos(earRigidity / math.abs(rigidBody.linearVelocityX)) / math.PIHALF * 50; if (!lookingRight){ earAngle *= -1; } } else { earAngle = 0; } if (math.abs(earAngle - lastEarAngle) / Time.deltaTime > maxEarAngularVelocity) { if (earAngle > lastEarAngle){ earAngle = lastEarAngle + Time.deltaTime * maxEarAngularVelocity; } else { earAngle = lastEarAngle - Time.deltaTime * maxEarAngularVelocity; } } lastEarAngle = earAngle; loeffel.transform.localRotation = Quaternion.AngleAxis(earAngle, Vector3.forward); float timeFactor = (Time.time - jumpStartTime) / HINTERLAUF_TIME; Vector3 rotationAxis; if (lookingRight) { rotationAxis = Vector3.back; } else { rotationAxis = Vector3.forward; } if (timeFactor < .5f){ hinterlauf.transform.localRotation = Quaternion.AngleAxis(MAX_HINTERLAUF_ANGLE * timeFactor * 2, rotationAxis); } else if (timeFactor < 1.0f){ hinterlauf.transform.localRotation = Quaternion.AngleAxis(MAX_HINTERLAUF_ANGLE * (1 - timeFactor) * 2, rotationAxis); } else { hinterlauf.transform.localRotation = Quaternion.identity; } } void OnCollisionEnter2D(Collision2D collision){ if (collision.gameObject.layer == 7){ //That layer is the ground. if (collisions == 0){ rigidBody.linearVelocityX = 0; } collisions++; } } void OnCollisionExit2D(Collision2D collision){ if (collision.gameObject.layer == 7){ //That layer is the ground. collisions--; } } private void StartJump(){ if (lookingRight) { rigidBody.linearVelocityX = jumpVelocityX; } else { rigidBody.linearVelocityX = -jumpVelocityX; } rigidBody.linearVelocityY = maxJumpVelocityY; jumpStartTime = Time.time; } private bool targetReached(){ return (lookingRight && transform.position.x >= xTarget) || (!lookingRight && transform.position.x <= xTarget); } }