예제 #1
0
    public override void ModifyMoveForce(KobotoMoveForce moveForce, InputData input, KobotoSensor sensors, KobotoParameters parameters)
    {
        if (burnTimeLeft <= 0)
        {
            return;
        }

        float t = 1f - burnTimeLeft / totalBurnTime; // normalized time

        Func <float, float>        f_sin       = (float s) => Mathf.Sin(s * Mathf.PI);
        Func <float, float>        f_parab     = (float s) => 1 - (s - 1) * (s - 1);
        Func <float, float, float> f_skewedSin = (float s, float skew) => f_sin(Mathf.Lerp(t, f_parab(t), skew));

        t = f_skewedSin(t, 0.5f);


        moveForce.airMove = sensors.upVector * maxThrust * t;

        burnTimeLeft -= Time.fixedDeltaTime;

        moveForce.tiltAngle    = 25f * input.move;
        moveForce.tiltStrength = 0.2f;
        moveForce.airDrag      = 1f;

        moveForce.airMove += sensors.forwardVector * input.move * 120f;

        moveForce.airForcesSet = true;


        if (burnTimeLeft <= 0)
        {
            burnTimeLeft = 0f;
            Debug.Log("Jetpack done");
        }
    }
예제 #2
0
    public override void ModifyMoveForce(KobotoMoveForce moveForce, InputData input, KobotoSensor sensors, KobotoParameters parameters)
    {
        bool belowMagnetic = sensors.localBelowCeiling && sensors.localBelowCeilingCollider.tag == "magnetic";



        const float magnetStrengthMax = 400f;
        const float magnetStrengthMin = 10f;
        const float magnetDist        = 12f;

        if (belowMagnetic)
        {
            lineRenderer.enabled       = true;
            lineRenderer.positionCount = 2;
            lineRenderer.SetPositions(new Vector3[2] {
                transform.position, sensors.localBelowCeilingPoint
            });

            float   t           = Mathf.Clamp01((magnetDist - sensors.localCeilingDist) / magnetDist);
            Vector3 magnetForce = sensors.upVector * Mathf.Lerp(magnetStrengthMin, magnetStrengthMax, t);
            moveForce.airMove += magnetForce;
            Debug.Log("Magnet force: " + magnetForce);
        }
        else
        {
            lineRenderer.positionCount = 0;
            lineRenderer.enabled       = false;
        }

        moveForce.airForcesSet = true;
    }
    public override void UpdateKoboto(Koboto koboto, KobotoSensor sensors)
    {
        float rollVol = 0f;

        if (sensors.onGround)
        {
            rollVol = Mathf.Clamp01(sensors.velocity.magnitude / 10f);
        }
        koboto.soundPlayer.PlayRoll(rollVol);
    }
예제 #4
0
    protected override void UpdateSensor(KobotoSensor kSense, Vector2 pointInZone)
    {
        float strength = (1f - pointInZone.x * pointInZone.x) * windSpeed;
        float velComp  = Mathf.Clamp(Vector3.Dot(kSense.velocity, transform.forward), 0, strength);

        strength = strength - velComp;
        Debug.Log("wind strength " + strength);

        kSense.windSpeed += transform.forward * strength;
    }
예제 #5
0
    public bool AffectKobotoSenses(KobotoSensor kSense, Vector3 testPoint)
    {
        Vector2 pointInZone = Vector2.zero;
        bool    inZone      = Test(testPoint, ref pointInZone);

        if (inZone)
        {
            Debug.Log("In zone: " + pointInZone);
            UpdateSensor(kSense, pointInZone);
        }
        return(inZone);
    }
예제 #6
0
    public override void ModifyMoveForce(KobotoMoveForce moveForce, InputData input, KobotoSensor sensors, KobotoParameters parameters)
    {
        // m/s to degrees/s
        const float degreesPerSecMultiplier = 180f / (Mathf.PI * wheelRadius);

        float targetV = input.move * parameters.groundMoveSpeed;

        float targetWheelSpeed = targetV;

        if (sensors.onGround)
        {
            // moveForce.airDrag = 0f;
            moveForce.dynamicFriction = 0f;
            moveForce.staticFriction  = 0f;

            float groundV = Vector3.Dot(sensors.forwardWheelForward, sensors.velocity);

            float forceMultiplier = 1f;
            if (Mathf.Sign(targetV) == Mathf.Sign(groundV))
            {
                float t = Mathf.Clamp01(Mathf.Abs(groundV) / parameters.groundMoveSpeed);
                forceMultiplier = parameters.groundAccelerationCurve.Evaluate(t);
            }

            Vector3 driveForce = forceMultiplier * input.move * parameters.groundMoveStength * sensors.forwardWheelForward;
            moveForce.groundMove += driveForce;

            moveForce.upRotation = Utils.TiltFromUpVector(sensors.forwardWheelNormal);

            moveForce.tiltAngle    = 0f;
            moveForce.tiltStrength = 1f;

            moveForce.groundForcesSet = true;

            float groundWheelSpeed = Vector3.Dot(sensors.velocity, sensors.forwardWheelForward);

            float spinFactor = Mathf.Abs(targetWheelSpeed) * Mathf.Abs((targetWheelSpeed - groundWheelSpeed));
            float minSpin    = 0.1f;
            float maxSpin    = 8f;

            wheelSpeed = Mathf.Lerp(groundWheelSpeed, targetWheelSpeed, Utils.Smoothstep(minSpin, maxSpin, spinFactor)) * degreesPerSecMultiplier;
        }
        else
        {
            moveForce.airTiltResponse = Mathf.Clamp01(sensors.inAirTime * 2f);
            moveForce.airMoveResponse = 1f;
            moveForce.upRotation      = Quaternion.identity;

            wheelSpeed = targetWheelSpeed * degreesPerSecMultiplier * 1.5f;
        }
    }
예제 #7
0
    public override void UpdateKoboto(Koboto koboto, KobotoSensor sensors)
    {
        float rollVol = 0f;

        if (sensors.onGround)
        {
            rollVol = Mathf.Clamp01(sensors.velocity.magnitude / 10f);
        }

        koboto.soundPlayer.PlayRoll(rollVol);

        foreach (var spoke in spokeTransforms)
        {
            Debug.Log("Rotating wheel: " + wheelSpeed);
            spoke.Rotate(Vector3.right, wheelSpeed * Time.fixedDeltaTime);
        }
    }
예제 #8
0
    public override void ModifyMoveForce(KobotoMoveForce moveForce, InputData input, KobotoSensor sensors, KobotoParameters parameters)
    {
        if (!open)
        {
            return;
        }
        float speedError  = terminalVelocity - sensors.velocity.y;
        float upDragForce = dragControl.Update(speedError, Time.fixedDeltaTime);

        //  float upDragForce = 15f;
        //  Debug.Log("Up force " + upDragForce);

        moveForce.tiltAngle    = 25f * input.move;
        moveForce.tiltStrength = 0.2f;
        moveForce.airDrag      = 1f;


        moveForce.airMove     += Vector3.up * upDragForce + sensors.forwardVector * input.move * 120f;
        moveForce.airMove     += sensors.windSpeed;
        moveForce.airForcesSet = true;
    }
예제 #9
0
    protected override void Init(EGameState gameState)
    {
        parameters  = GetComponent <KobotoParameters>();
        soundPlayer = GetComponent <KobotoSoundPlayer> ();

        rotationController = new PIDController(tiltControllerP, tiltControllerI, tiltControllerD);

        sensors            = new KobotoSensor();
        moveForce          = new KobotoMoveForce();
        colliderBaseCenter = boxCollider.center;
        colliderBaseSize   = boxCollider.size;

        physMat = boxCollider.material;
        capsuleCollider.sharedMaterial = boxCollider.sharedMaterial;

        physMat.name = "KobotoPhysMat";

        upRotation = Quaternion.identity;
        tiltAngle  = 0f;

        defaultCom = rb.centerOfMass;

        attachmentTargetContents = new Dictionary <EAttachmentTarget, AttachmentBase>();
        attachmentTargetLookup   = new Dictionary <EAttachmentTarget, Transform>();
        currentAttachments       = new Dictionary <EAttachmentType, AttachmentBase>();
        var attachPoints = GetComponentsInChildren <KobotoAttachPoint>();

        foreach (var point in attachPoints)
        {
            attachmentTargetLookup.Add(point.targetType, point.transform);
        }

        doFixedUpdate = (gameState == EGameState.Play);
        SetupCollider();
        defaultParent = transform.parent;
        Debug.Log("Koboto init in state: " + gameState);
    }
예제 #10
0
    public override void UpdateKoboto(Koboto koboto, KobotoSensor sensor)
    {
        base.UpdateKoboto(koboto, sensor);
        bool shouldOpen  = false;
        bool shouldClose = false;

        shouldClose |= sensor.onGround;
        shouldClose |= sensor.onCeiling;

        shouldClose |= sensor.velocity.y > 0f;

        shouldOpen = !shouldClose && sensor.velocity.y < downSpeedForOpen;

        //   Debug.Log("speed " + sensor.velocity.y + " should open " + shouldOpen + " should close " + shouldClose);

        if (!open && shouldOpen)
        {
            Open(koboto);
        }
        else if (open && shouldClose)
        {
            Close(koboto);
        }
    }
    public override void ModifyMoveForce(KobotoMoveForce moveForce, InputData input, KobotoSensor sensors, KobotoParameters parameters)
    {
        bool wasOverGround      = overGround;
        bool overGroundLocal    = sensors.localAboveGround && sensors.localGroundDist < maxHeight;
        bool overGroundVertical = sensors.aboveGround && sensors.heightAboveGround < maxHeight;

        overGround = overGroundLocal || overGroundVertical;

        if (overGround)
        {
            Vector3 point;
            if (overGround && overGroundLocal)
            {
                point = (sensors.aboveGroundPoint + sensors.localAboveGroundPoint) * 0.5f;
            }
            else
            {
                point = overGroundLocal ? sensors.localAboveGroundPoint : sensors.aboveGroundPoint;
            }
            if (!wasOverGround)
            {
                groundPoint = point;
            }
            else
            {
                groundPoint = Vector3.Lerp(groundPoint, point, 4f * Time.fixedDeltaTime);
            }

            groundVector = groundPoint - sensors.positionTrail[0];
            float height = groundVector.magnitude;

            dustVFX.transform.position = groundPoint;
            dustVFX.SetActive(true);

            float heightError = targetHeight - height;


            if (resetMotor)
            {
                motorControl.Reset(heightError);
                resetMotor = false;
            }

            motorForce = motorControl.Update(heightError, Time.fixedDeltaTime);

            float propSpeed = Mathf.Clamp01(motorForce / 100f);
            bladeSpeed = Mathf.Lerp(visualBladeSpeedMin, visualBladeSpeedMax, propSpeed);


            moveForce.tiltAngle    = 45f * input.move;
            moveForce.tiltStrength = 0.4f;
        }
        else
        {
            motorForce *= 1f - 0.2f * visualBladeSpeedSlowdown * Time.fixedDeltaTime;
            bladeSpeed *= 1f - visualBladeSpeedSlowdown * Time.fixedDeltaTime;
            dustVFX.SetActive(false);
        }

        moveForce.airMove = motorForce * strength * sensors.upVector;

        float glide = Mathf.Abs(Vector3.Dot(sensors.velocity, sensors.forwardVector));

        glide = Mathf.Clamp(glide, 0, 6f);

        Vector3 liftForce = glide * lift * sensors.upVector;

        moveForce.airMove += liftForce;

        moveForce.airForcesSet = true;

        bladeTransform.Rotate(Vector3.up * bladeSpeed, Space.Self);
    }
예제 #12
0
 protected virtual void ApplyStandardModification(KobotoMoveForce moveForce, InputData input, KobotoSensor sensors, KobotoParameters parameters)
 {
 }
예제 #13
0
 protected virtual void UpdateSensor(KobotoSensor kSense, Vector2 pointInZone)
 {
 }
 protected override void UpdateSensor(KobotoSensor kSense, Vector2 pointInZone)
 {
     kSense.cameraPushOut = camDistance;
 }
예제 #15
0
    public override void ModifyMoveForce(KobotoMoveForce moveForce, InputData input, KobotoSensor sensors, KobotoParameters parameters)
    {
        if (sensors.onGround)
        {
            if (firstBounce)
            {
                charging         = true;
                bounceVelNormal  = preferredBounceSpeed * 0.8f;
                bounceVelTangent = 0f;

                landingRotation = Utils.TiltFromUpVector(sensors.groundNormal);
            }
            else if (!charging && sensors.landedThisFrame)
            {
                charging = true;
                Debug.Log("Land " + sensors.velocity);

                landingRotation = Utils.TiltFromUpVector(sensors.upVector);

                if (sensors.positionTrail.Count < 2)
                {
                    bounceVelNormal  = preferredBounceSpeed * 0.8f;
                    bounceVelTangent = 0f;
                }
                else
                {
                    Vector3 incoming = sensors.velocity;
                    bounceVelNormal  = Vector3.Dot(-incoming, sensors.groundNormal);
                    bounceVelTangent = 0.35f * Vector3.Dot(incoming, sensors.groundForward);

                    float speed = incoming.magnitude;
                    bounceVelNormal = Mathf.Lerp(speed, preferredBounceSpeed, 0.8f);
                }
            }

            moveForce.groundMove = Vector3.zero;
            moveForce.airMove    = Vector3.zero;

            moveForce.upRotation = Utils.TiltFromUpVector(sensors.groundNormal);


            if (charging && sensors.onGroundTime >= onGroundTime)
            {
                // Bounce!
                charging    = false;
                firstBounce = false;

                moveForce.airMove   = sensors.upVector * bounceVelNormal + sensors.groundForward * bounceVelTangent;
                moveForce.forceMode = ForceMode.VelocityChange;
            }
            else
            {
                moveForce.dynamicFriction = 1f;
                moveForce.staticFriction  = 1f;

                moveForce.upRotation   = landingRotation;
                moveForce.tiltStrength = 1f;
            }
        }
        else
        {
            moveForce.airMoveResponse = 1.5f;
            moveForce.airTiltResponse = 0.8f;
        }
    }
    public override void ModifyMoveForce(KobotoMoveForce moveForce, InputData input, KobotoSensor sensors, KobotoParameters parameters)
    {
        if (sensors.onGround)
        {
            // moveForce.airDrag = 0f;
            moveForce.dynamicFriction = 0f;
            moveForce.staticFriction  = 0f;

            float groundV = Vector3.Dot(sensors.forwardWheelForward, sensors.velocity);
            float targetV = input.move * parameters.groundMoveSpeed;

            float forceMultiplier = 1f;
            if (Mathf.Sign(targetV) == Mathf.Sign(groundV))
            {
                float t = Mathf.Clamp01(Mathf.Abs(groundV) / parameters.groundMoveSpeed);
                forceMultiplier = parameters.groundAccelerationCurve.Evaluate(t);
            }

            Vector3 driveForce = forceMultiplier * input.move * parameters.groundMoveStength * sensors.forwardWheelForward;
            moveForce.groundMove += driveForce;

            moveForce.upRotation = Utils.TiltFromUpVector(sensors.forwardWheelNormal);

            moveForce.tiltAngle    = 0f;
            moveForce.tiltStrength = 1f;

            moveForce.groundForcesSet = true;
        }
        else if (sensors.onCeiling)
        {
            // moveForce.airDrag = 0f;
            moveForce.dynamicFriction = 0f;
            moveForce.staticFriction  = 0f;

            float groundV = Vector3.Dot(sensors.topForwardWheelForward, sensors.velocity);
            float targetV = input.move * parameters.groundMoveSpeed;

            float forceMultiplier = 1f;
            if (Mathf.Sign(targetV) == Mathf.Sign(groundV))
            {
                float t = Mathf.Clamp01(Mathf.Abs(groundV) / parameters.groundMoveSpeed);
                forceMultiplier = parameters.groundAccelerationCurve.Evaluate(t);
            }

            Vector3 driveForce = forceMultiplier * input.move * parameters.groundMoveStength * sensors.topForwardWheelForward;
            moveForce.groundMove += driveForce;

            moveForce.upRotation = Utils.TiltFromUpVector(-sensors.topForwardWheelNormal);

            moveForce.tiltAngle    = 0f;
            moveForce.tiltStrength = 1f;

            moveForce.groundForcesSet = true;

            moveForce.airMove      = -sensors.topForwardWheelNormal * maxUpForce;
            moveForce.airForcesSet = true;
            moveForce.useGravity   = false;
        }
        else
        {
            //if (sensors.belowCeiling && sensors.belowCeilingDist < 1.5f)
            //{
            //    Debug.Log("Near ceiling");
            //    moveForce.upRotation = Utils.TiltFromUpVector(-sensors.topForwardWheelNormal);
            //    moveForce.tiltAngle = 0f;
            //    moveForce.tiltStrength = 1f - sensors.belowCeilingDist / 1.5f;
            //    moveForce.useGravity = false;
            //    moveForce.airForcesSet = true;
            //}
            //else
            {
                moveForce.alignToCeiling = true;
            }
            //moveForce.airTiltResponse = 0.5f * Mathf.Clamp01(sensors.inAirTime - 0.5f);
            //moveForce.airMoveResponse = 1f;
        }
    }
예제 #17
0
 public virtual void ModifyMoveForce(KobotoMoveForce moveForce, InputData input, KobotoSensor sensors, KobotoParameters parameters)
 {
 }
예제 #18
0
    public void ProcessMoveForce(KobotoMoveForce moveForce, InputData input, KobotoSensor sensors, KobotoParameters parameters)
    {
        if (sensors.onGround)
        {
            if (!moveForce.groundForcesSet)
            {
                moveForce.upRotation   = Utils.TiltFromUpVector(sensors.groundNormal);
                moveForce.tiltAngle    = 0f;
                moveForce.tiltStrength = 1f;
            }
        }
        else
        {
            if (!moveForce.airForcesSet)
            {
                float       alignToGroundStartDist = Mathf.Min(0.75f + 0.25f * sensors.velocity.magnitude, 3f);
                const float alignToGroundEndDist   = 0.5f;

                Debug.Log("align start " + alignToGroundStartDist);

                const float alignToCeilingStartDist = 5f;
                const float alignToCeilingEndDist   = 2f;

                float speed = sensors.velocity.magnitude;

                // float alignStart = alignToGroundStartDist;
                // float alignEnd = alignToGroundEndDist;

                if (moveForce.alignToCeiling && sensors.inAirTime > 0f && speed > 0.1f &&
                    sensors.closeToCeiling &&
                    sensors.distanceToCeiling < alignToCeilingStartDist &&
                    Vector3.Dot(sensors.velocity.normalized, sensors.closestCeilingNormal) < 0f)
                {
                    Quaternion ceilingAlign = Utils.TiltFromUpVector(-sensors.closestCeilingNormal);
                    Quaternion currentRot   = Utils.TiltFromUpVector(sensors.upVector);
                    if (sensors.distanceToCeiling > alignToCeilingEndDist)
                    {
                        ceilingAlign = Quaternion.Lerp(currentRot, ceilingAlign, 24f * Time.fixedDeltaTime);
                    }
                    float t = Mathf.Clamp01((alignToCeilingStartDist - sensors.distanceToCeiling) / (alignToCeilingStartDist - alignToCeilingEndDist));
                    moveForce.upRotation   = Quaternion.Lerp(sensors.airBaseRotation, ceilingAlign, t);
                    moveForce.tiltStrength = Mathf.Clamp01(1f - 8f * t);
                    moveForce.useGravity   = false;
                    moveForce.airMove     += 20.0f * t * -sensors.closestCeilingNormal;

                    Debug.DrawRay(sensors.closestCeilingPoint, -3.0f * sensors.closestCeilingNormal, Color.yellow);
                }

                //align to ground if headed towards it
                else if (sensors.inAirTime > 0.5f &&
                         speed > 0.1f &&
                         sensors.closeToGround &&
                         sensors.distanceToGround < alignToGroundStartDist &&
                         Vector3.Dot(sensors.velocity.normalized, sensors.closestGroundNormal) < 0.1f)
                {
                    Quaternion groundAlign = Utils.TiltFromUpVector(sensors.closestGroundNormal);
                    Quaternion currentRot  = Utils.TiltFromUpVector(sensors.upVector);
                    if (sensors.distanceToGround > alignToGroundEndDist)
                    {
                        groundAlign = Quaternion.Lerp(currentRot, groundAlign, 8f * Time.fixedDeltaTime);
                    }
                    float t = Mathf.Clamp01((alignToGroundStartDist - sensors.distanceToGround) / (alignToGroundStartDist - alignToGroundEndDist));
                    moveForce.upRotation   = Quaternion.Lerp(sensors.airBaseRotation, groundAlign, t);
                    moveForce.tiltStrength = Mathf.Clamp01(1f - 4f * t);

                    Debug.DrawLine(sensors.closestGroundPoint, sensors.closestGroundPoint + sensors.closestGroundNormal, Color.blue);
                }
                else
                {
                    // apply air move + tilt
                    moveForce.upRotation   = sensors.airBaseRotation;
                    moveForce.tiltStrength = 1f;
                    moveForce.tiltAngle    = moveForce.airTiltResponse * input.move * parameters.maxAirTilt;

                    moveForce.airMove = input.move * Vector3.forward * parameters.airMoveStrength * moveForce.airMoveResponse;
                    //float inputTiltAmount = 45f * Mathf.Clamp01(sensors.inAirTime - 0.5f);
                    // moveForce.tiltAngle = inputTiltAmount * input.move;

                    // moveForce.airMove = input.move * Vector3.forward * parameters.airMoveStrength;
                }
            }
        }
    }
예제 #19
0
 public static void ApplyAirForces(KobotoMoveForce moveForce, InputData input, KobotoSensor sensors, KobotoParameters parameters)
 {
 }
예제 #20
0
 public virtual void UpdateKoboto(Koboto koboto, KobotoSensor sensor)
 {
 }