Пример #1
0
        public override void Invoke(CollisionInfo collision)
        {
            var position = spawnAtAvatarBone && AvatarController.TryGetBone(contextBone, out var bone)
                ? bone.position
                : collision.point;

            Invoke(position, AngleUtil.DirectionalRotation(collision.normal));
        }
Пример #2
0
        void Dispatch(ContactPoint2D contact)
        {
            if (contact.normalImpulse < impulseThreshold)
            {
                return;
            }
            var tempObject = new GameObject();

            tempObject.transform.SetPositionAndRotation(contact.point, AngleUtil.DirectionalRotation(contact.normal));
            onColliderEnter.Invoke(tempObject);
            Destroy(tempObject, 0);
        }
Пример #3
0
        IEnumerable <GameObject> CreateContactObjects(Collision2D collision)
        {
            var contacts = collision.contacts;

            for (int i = 0; i < contacts.Length; i++)
            {
                if (contacts[i].normalImpulse >= onCollisionImpulseThreshold)
                {
                    var tempObject = new GameObject();
                    tempObject.transform.SetPositionAndRotation(contacts[i].point, AngleUtil.DirectionalRotation(contacts[i].normal));
                    Destroy(tempObject, 0);
                    yield return(tempObject);
                }
            }
        }
Пример #4
0
        public override MovementCalculator CreateMovementCalculator(AvatarController avatar)
        {
            float angularVelocity               = 0;
            var   acceleration                  = Vector2.zero;
            float boostGatheringDuration        = 0;
            float boostExecutionDuration        = 0;
            float maximumBoostExecutionDuration = 0;

            return(deltaTime => {
                float currentAngle = avatar.physics.rotationAngle;

                var targetDirection = avatar.intentions.intendedFlight == Vector2.zero
                    ? avatar.physics.rotatedForward
                    : avatar.intentions.intendedFlight;

                float targetAngle = Vector2.SignedAngle(avatar.physics.forward, targetDirection);

                if (directionsNormalized)
                {
                    targetAngle = AngleUtil.RoundAngle(targetAngle, directionRange);
                }

                var currentVelocity = avatar.physics.velocity;

                (Vector2, float, int) boost()
                {
                    avatar.physics.drag = boostDrag;

                    boostExecutionDuration++;
                    if (boostExecutionDuration >= maximumBoostExecutionDuration)
                    {
                        boostExecutionDuration = 0;
                        avatar.broom.isBoosting = false;
                        angularVelocity = 0;
                        return glide();
                    }

                    float angle = Mathf.SmoothDampAngle(currentAngle, targetAngle, ref angularVelocity, boostRotationDuration, maximumRotationSpeed, deltaTime);
                    var rotation = Quaternion.Euler(0, 0, angle);
                    var targetVelocity = (Vector2)(rotation * Vector2.right * currentVelocity.magnitude);

                    var velocity = targetVelocity;

                    return (velocity, angle, avatar.physics.facing);
                }

                (Vector2, float, int) glide()
                {
                    float angle = Mathf.SmoothDampAngle(currentAngle, targetAngle, ref angularVelocity, rotationDuration, maximumRotationSpeed, deltaTime);
                    var rotation = Quaternion.Euler(0, 0, angle);

                    var velocityRotation = AngleUtil.DirectionalRotation(currentVelocity);

                    float alignment = AngleUtil.Alignment(rotation, velocityRotation);

                    float alignDuration = GetAlignDuration(alignment);
                    var targetVelocity = rotation * Vector2.right * currentVelocity.magnitude;

                    avatar.physics.drag = GetDrag(alignment);

                    avatar.broom.isAligned = alignment > requiredAlignment;
                    avatar.broom.isDiving = currentVelocity.y < requiredYSpeed;
                    bool intendsBoost = targetAngle <= 180;

                    if (intendsBoost)
                    {
                        if (avatar.broom.canBoost)
                        {
                            avatar.broom.canBoost = false;
                            avatar.broom.isBoosting = true;
                            maximumBoostExecutionDuration = Mathf.Abs(currentVelocity.y) * boostExecutionDurationMultiplier;
                            onBoost.Invoke(avatar.gameObject);
                            currentVelocity += currentVelocity.normalized * boostExecutionSpeed;
                            angularVelocity = 0;
                            return boost();
                        }
                    }
                    else
                    {
                        if (avatar.broom.isAligned && avatar.broom.isDiving)
                        {
                            if (!avatar.broom.canBoost && boostGatheringDuration < minimumBoostGatheringDuration)
                            {
                                boostGatheringDuration += deltaTime;
                                if (boostGatheringDuration >= minimumBoostGatheringDuration)
                                {
                                    boostGatheringDuration = 0;
                                    avatar.broom.canBoost = true;
                                }
                            }
                        }
                    }

                    var velocity = Vector2.SmoothDamp(currentVelocity, targetVelocity, ref acceleration, alignDuration, maximumGlideAcceleration, deltaTime);
                    velocity += GetAcceleration(alignment) * Time.deltaTime * (Vector2)(rotation * Vector3.right);
                    velocity += avatar.physics.gravityStep;

                    return (velocity, angle, avatar.physics.facing);
                }

                return avatar.broom.isBoosting
                    ? boost()
                    : glide();
            });
        }
Пример #5
0
 public void TestDirectionalRotation(float x, float y, float angleX, float angleY, float angleZ)
 {
     Assert.AreEqual(Quaternion.Euler(angleX, angleY, angleZ), AngleUtil.DirectionalRotation(new Vector2(x, y)));
 }