Esempio n. 1
0
        protected override Vector3 GetShootDirection()
        {
            var camera         = Camera.main;
            var shootingOrigin = Refs.shootingOrigin.position;
            var direction      = shootingOrigin - camera.transform.position;

            direction = Vector3.Project(direction, camera.transform.forward);

            var mousePosition = Input.mousePosition;

            mousePosition.z = direction.magnitude;
            var mousePos = camera.ScreenToWorldPoint(mousePosition);

            direction = mousePos - shootingOrigin;
            direction = Vector3.ProjectOnPlane(direction, Vector3.up).normalized;

            return(direction);
        }
Esempio n. 2
0
    void FixedUpdate()
    {
        Vector3 pos    = transform.position;
        float   module = (m_heavy_body_pos - pos).magnitude;

        if (module > 1000)
        {
            Destroy(transform.gameObject);
        }

        if (module < 1)
        {
            m_v -= 2 * m_v.Project(m_heavy_body_pos - pos);
        }
        float   denom = module * module * module;
        Vector3 a     = m_G * m_M / denom * (m_heavy_body_pos - pos);

        float dt = Time.deltaTime;

        transform.Translate(dt * (m_v + a * dt / 2));
        m_v += a * dt;
    }
Esempio n. 3
0
        private void CalculateFriction()
        {
            var isGrounded = _wheelCollisionDetector.TryGetCollision(out var point, out var normal, out var collider, out var rb, out var t);

            if (!isGrounded)
            {
                return;
            }

            var forceOffset = transform.up * _applyForcesOffset;

            var right   = transform.right;
            var forward = transform.forward;

            var direction = Vector3.Cross(normal, right);

            if (motorTorque < 0)
            {
                direction *= -1;
            }

            var lateralVelocity = Vector3.Project(velocity, right);
            var forwardVelocity = Vector3.Project(velocity, forward);
            var slip            = (forwardVelocity + lateralVelocity) / 2;

            var lateralFriction = Vector3.Project(right, slip).magnitude *lateralVelocity.magnitude *lateralFrictionMultiplier / Time.fixedDeltaTime;

            _rb.AddForceAtPosition(-Vector3.Project(slip, lateralVelocity).normalized *lateralFriction, point + forceOffset);

            var motorForce             = Mathf.Abs(motorTorque / _wheel.GetRadius());
            var maxForwardFriction     = motorForce * forwardFrictionCoeff;
            var appliedForwardFriction = Mathf.Clamp(motorForce, 0, maxForwardFriction);

            var forwardForce = direction.normalized * appliedForwardFriction * engineShaftToWheelRatio;

            _rb.AddForceAtPosition(forwardForce, point + forceOffset);
        }
Esempio n. 4
0
 /// <summary>
 /// Calculate the distance between two point's projections on a plane.
 /// </summary>
 /// <param name="v"></param>
 /// <param name="u"></param>
 /// <param name="planePos">An arbitrary point inside the plane.</param>
 /// <param name="planeRot">The plane's rotation.</param>
 /// <returns>The distance of both points' projection in the plane.</returns>
 public static float distance(this Vector3 v, Vector3 u, Vector3 planePos, Quaternion planeRot)
 {
     var localv = v.Project( planePos, planeRot );
     var localu = u.Project( planePos, planeRot );
     return localv.distance( localu );
 }
Esempio n. 5
0
 /// <summary>
 /// Calculate the squared distance between two points' projections on an arbitrary plane.
 /// </summary>
 /// <param name="v"></param>
 /// <param name="normal">Normal defining the plane to project on.</param>
 /// <returns>The squared distance between the two points on the plane.</returns>
 public static float sqrDistance(this Vector3 v, Vector3 u, Vector3 normal)
 {
     var localv = v.Project( normal );
     var localu = u.Project( normal );
     return localv.distance( localu );
 }
Esempio n. 6
0
 public static Vector3 ProjectOnPlane(Vector3 vector, Vector3 planeNormal)
 {
     return(vector - Vector3.Project(vector, planeNormal));
 }
Esempio n. 7
0
 public static Vector3 Exclude(Vector3 excludeThis, Vector3 fromThat)
 {
     return(fromThat - Vector3.Project(fromThat, excludeThis));
 }
Esempio n. 8
0
 public static Vector3 Project(this Vector3 u, Vector3 v)
 {
     return(Vector3.Project(u, v));
 }
Esempio n. 9
0
    /// <summary>
    /// Returns the angle which points towards the provided mouse point
    /// </summary>
    /// <param name="mousePoint">the point to aim at</param>
    /// <returns>angle that points towars mousepoint</returns>
    public Vector3 GetAngle(Vector3 mousePoint)
    {
        Vector3 v_RP_MP          = mousePoint - RotationPoint.transform.position;
        Vector3 norm_GP_prj_RPMP = Vector3.Project(v_RP_MP, FirePoint.transform.right);
        Vector3 CheckV2          = RotationPoint.position + norm_GP_prj_RPMP - new Vector3(mousePoint.x, mousePoint.y);

        Vector2 newCheckV = RotationPoint.transform.position - FirePoint.transform.position;

        if (Mathf.Floor(CheckV.magnitude * 10) != Mathf.Floor(newCheckV.magnitude * 10))
        {
            this.CheckV = newCheckV;
            CreateHelperObjects();
        }

        if (CheckV2.magnitude > 0.35)
        {
            CreateHelperObjects();
        }

        // rotates the helper gun point towards the mouse
        v_RP_MP = mousePoint - RotationPoint.transform.position;
        float   z_angle   = this.RadianToDegree(Math.Atan2(v_RP_MP.y, v_RP_MP.x));
        bool    isFlipped = (z_angle <90 && z_angle> -90) ? false : true;
        Vector3 angle     = (isFlipped) ? new Vector3(180, 0, -z_angle) : new Vector3(0, 0, z_angle);

        helperRotPoint.transform.rotation = Quaternion.Euler(angle);

        // finds the vector projected from the shooting direction on the vector from the helper GP to the MP
        Vector3 v_GP_MP          = mousePoint - helperAimPoint.transform.position;
        Vector3 norm_GP          = helperAimPoint.transform.right;
        Vector3 norm_GP_Prj_GPMP = Vector3.Project(v_GP_MP, norm_GP);

        // finds the point where a line from the helper GP to the point found in the block above
        // wold intersect a circle centered at the RP with a radius of the distance between the RP and MP
        Vector3 v_RP_GP = helperAimPoint.transform.position - helperRotPoint.transform.position;
        Vector3 V2      = (norm_GP_Prj_GPMP + v_RP_GP);

        float r = new Vector2(v_RP_MP.x, v_RP_MP.y).magnitude;

        float x1 = v_RP_GP.x;
        float y1 = v_RP_GP.y;

        float x2 = V2.x;
        float y2 = V2.y;

        float dx = x2 - x1;
        float dy = y2 - y1;
        float dr = Mathf.Sqrt(Mathf.Pow(dx, 2) + Mathf.Pow(dy, 2));

        float D = x1 * y2 - x2 * y1;

        float xCord = 0;
        float yCord = 0;

        float toSqr = Mathf.Pow(r, 2) * Mathf.Pow(dr, 2) - Mathf.Pow(D, 2);

        // to avoid sqrt(-num) only use the "correct" coordinates for x,y when the squared block is
        // bigger then 0
        if (toSqr > 0)
        {
            float sgnX   = (dy < 0) ? -1 : 1;
            float xCord1 = (D * dy + sgnX * dx * Mathf.Sqrt(toSqr)) / Mathf.Pow(dr, 2);
            float xCord2 = (D * dy - sgnX * dx * Mathf.Sqrt(toSqr)) / Mathf.Pow(dr, 2);

            float yCord1 = (-D * dx + Mathf.Abs(dy) * Mathf.Sqrt(toSqr)) / Mathf.Pow(dr, 2);
            float yCord2 = (-D * dx - Mathf.Abs(dy) * Mathf.Sqrt(toSqr)) / Mathf.Pow(dr, 2);

            Vector2 helper1 = new Vector2(helperAimPoint.transform.right.x, helperAimPoint.transform.right.y) - new Vector2(xCord1, yCord1);
            Vector2 helper2 = new Vector2(helperAimPoint.transform.right.x, helperAimPoint.transform.right.y) - new Vector2(xCord2, yCord2);

            if (debug)
            {
                Debug.DrawLine(Vector3.zero, new Vector3(xCord1, yCord1), Color.red);
                Debug.DrawLine(Vector3.zero, new Vector3(xCord2, yCord2), Color.black);
            }

            // if checks which one of the two fond points is closest and uses that one
            // the other point wold be on the other intersection point for the ray on the circle
            if (helper1.magnitude > helper2.magnitude)
            {
                xCord = xCord2;
                yCord = yCord2;
            }
            else
            {
                xCord = xCord1;
                yCord = yCord1;
            }

            float ang2     = this.RadianToDegree(Math.Atan2(yCord, xCord));
            float deltaAng = ang2 - z_angle;
            z_angle -= deltaAng;
        }
        else
        {
            // use the v2 as the gun angle, technically not correct but it works
            float ang2     = this.RadianToDegree(Math.Atan2(V2.y, V2.x));
            float deltaAng = ang2 - z_angle;
            z_angle -= deltaAng;
        }

        if (debug)
        {
            Debug.Log(CheckV2.magnitude);

            Debug.DrawLine(Vector3.zero, CheckV2, Color.green);

            Debug.DrawLine(RotationPoint.position, Camera.main.ScreenToWorldPoint(Input.mousePosition), Color.magenta);

            Debug.DrawRay(Vector3.zero, RotationPoint.position + norm_GP_prj_RPMP, Color.gray);
            Debug.DrawRay(FirePoint.transform.position, FirePoint.transform.right * 100, Color.cyan);
            Debug.DrawRay(Vector3.zero, helperAimPoint.transform.right * 100, Color.white);
        }

        return((isFlipped) ? new Vector3(180, 0, -z_angle) : new Vector3(0, 0, z_angle));
    }
Esempio n. 10
0
    protected override void OnUpdate()
    {
        if (startCountdownServerSystem.raceHasStarted)
        {
            var tick = ghostPredictionSystemGroup.PredictingTick;

            Entities.ForEach((Entity carEntity, DynamicBuffer <PlayerInput> inputBuffer, ref SynchronizedCarComponent carComponent, ref HealthComponent healthComponent, ref CarComponent serverCarComponent, ref PhysicsVelocity velocity, ref Rotation rotation) =>
            {
                PlayerInput input;
                inputBuffer.GetDataAtTick(tick, out input);

                bool playerCanControl = healthComponent.Health > 0 && EntityManager.GetComponentData <ProgressionComponent>(carEntity).CrossedCheckpoints < checkpointInitializationSystem.numberOfCheckpoints * GameSession.serverSession.laps;

                bool keyForwardPressed   = Convert.ToBoolean(input.keyForwardPressed) && playerCanControl;
                bool keyBackwardPressed  = Convert.ToBoolean(input.keyBackwardPressed) && playerCanControl;
                bool keyTurnRightPressed = Convert.ToBoolean(input.keyTurnRightPressed) && playerCanControl;
                bool keyTurnLeftPressed  = Convert.ToBoolean(input.keyTurnLeftPressed) && playerCanControl;

                if (keyTurnRightPressed && !keyTurnLeftPressed)
                {
                    if (carComponent.SteerAngle < 0)
                    {
                        carComponent.SteerAngle = 0;
                    }
                    if (carComponent.SteerAngle < SerializedFields.singleton.maxSteerAngle)
                    {
                        carComponent.SteerAngle += SerializedFields.singleton.wheelSteeringAngularSpeed * simulationDeltaTime;
                        if (carComponent.SteerAngle > SerializedFields.singleton.maxSteerAngle)
                        {
                            carComponent.SteerAngle = SerializedFields.singleton.maxSteerAngle;
                        }
                    }
                }
                else if (keyTurnLeftPressed && !keyTurnRightPressed)
                {
                    if (carComponent.SteerAngle > 0)
                    {
                        carComponent.SteerAngle = 0;
                    }
                    if (carComponent.SteerAngle > -SerializedFields.singleton.maxSteerAngle)
                    {
                        carComponent.SteerAngle -= SerializedFields.singleton.wheelSteeringAngularSpeed * simulationDeltaTime;
                        if (carComponent.SteerAngle < -SerializedFields.singleton.maxSteerAngle)
                        {
                            carComponent.SteerAngle = -SerializedFields.singleton.maxSteerAngle;
                        }
                    }
                }
                else if (!keyTurnRightPressed && !keyTurnLeftPressed)
                {
                    if (carComponent.SteerAngle > 0)
                    {
                        carComponent.SteerAngle -= SerializedFields.singleton.idleWheelSteeringAngularSpeed * simulationDeltaTime;
                        if (carComponent.SteerAngle < 0)
                        {
                            carComponent.SteerAngle = 0;
                        }
                    }
                    else if (carComponent.SteerAngle < 0)
                    {
                        carComponent.SteerAngle += SerializedFields.singleton.idleWheelSteeringAngularSpeed * simulationDeltaTime;
                        if (carComponent.SteerAngle > 0)
                        {
                            carComponent.SteerAngle = 0;
                        }
                    }
                }

                float turningRadiusInverse = CalculateTurningRadiusInverse(carComponent.SteerAngle);

                Vector3 localVelocity = math.mul(math.inverse(rotation.Value), velocity.Linear);
                if (localVelocity.magnitude > 0)
                {
                    Vector3 resistance = -localVelocity.normalized * localVelocity.sqrMagnitude * SerializedFields.singleton.forwardAcceleration / math.pow(SerializedFields.singleton.maxCarSpeed, 2) * simulationDeltaTime;
                    localVelocity     += resistance;
                }

                if (localVelocity.x > 0)
                {
                    localVelocity -= new Vector3(SerializedFields.singleton.friction * 9.81f * simulationDeltaTime, 0, 0);
                    if (localVelocity.x < 0)
                    {
                        localVelocity = new Vector3(0, localVelocity.y, localVelocity.z);
                    }
                }
                else if (localVelocity.x < 0)
                {
                    localVelocity += new Vector3(SerializedFields.singleton.friction * 9.81f * simulationDeltaTime, 0, 0);
                    if (localVelocity.x > 0)
                    {
                        localVelocity = new Vector3(0, localVelocity.y, localVelocity.z);
                    }
                }

                if (!serverCarComponent.GoingBackward)
                {
                    if (keyForwardPressed && !keyBackwardPressed)
                    {
                        if (localVelocity.z < 0)
                        {
                            localVelocity += new Vector3(0, 0, SerializedFields.singleton.friction * 9.81f * simulationDeltaTime);
                        }
                        else
                        {
                            localVelocity += new Vector3(0, 0, SerializedFields.singleton.forwardAcceleration * simulationDeltaTime);
                        }
                    }
                    else if (keyBackwardPressed && !keyForwardPressed)
                    {
                        if (localVelocity.z > 0)
                        {
                            localVelocity -= new Vector3(0, 0, SerializedFields.singleton.brakeAcceleration * simulationDeltaTime);
                            if (localVelocity.z < 0)
                            {
                                localVelocity = new Vector3(localVelocity.x, localVelocity.y, 0);
                            }
                        }
                        else if (localVelocity.z < 0)
                        {
                            localVelocity += new Vector3(0, 0, SerializedFields.singleton.brakeAcceleration * simulationDeltaTime);
                            if (localVelocity.z > 0)
                            {
                                localVelocity = new Vector3(localVelocity.x, localVelocity.y, 0);
                            }
                        }

                        if (Vector3.ProjectOnPlane(localVelocity, Vector3.up).magnitude < 0.1f)
                        {
                            serverCarComponent.GoingBackward = true;
                        }
                    }
                    else
                    {
                        if (localVelocity.z > 0)
                        {
                            localVelocity -= new Vector3(0, 0, SerializedFields.singleton.idleDeacceleration * simulationDeltaTime);
                            if (localVelocity.z < 0)
                            {
                                localVelocity = new Vector3(localVelocity.x, localVelocity.y, 0);
                            }
                        }
                        else if (localVelocity.z < 0)
                        {
                            localVelocity += new Vector3(0, 0, SerializedFields.singleton.friction * 9.81f * simulationDeltaTime);
                            if (localVelocity.z > 0)
                            {
                                localVelocity = new Vector3(localVelocity.x, localVelocity.y, 0);
                            }
                        }
                    }
                }
                else
                {
                    if (keyForwardPressed && !keyBackwardPressed)
                    {
                        if (localVelocity.z > 0)
                        {
                            localVelocity -= new Vector3(0, 0, SerializedFields.singleton.brakeAcceleration * simulationDeltaTime);
                            if (localVelocity.z < 0)
                            {
                                localVelocity = new Vector3(localVelocity.x, localVelocity.y, 0);
                            }
                        }
                        else if (localVelocity.z < 0)
                        {
                            localVelocity += new Vector3(0, 0, SerializedFields.singleton.brakeAcceleration * simulationDeltaTime);
                            if (localVelocity.z > 0)
                            {
                                localVelocity = new Vector3(localVelocity.x, localVelocity.y, 0);
                            }
                        }

                        if (Vector3.ProjectOnPlane(localVelocity, Vector3.up).magnitude < 0.1f)
                        {
                            serverCarComponent.GoingBackward = false;
                        }
                    }
                    else if (keyBackwardPressed && !keyForwardPressed)
                    {
                        if (localVelocity.z > -SerializedFields.singleton.backwardTopSpeed)
                        {
                            localVelocity -= new Vector3(0, 0, SerializedFields.singleton.backwardAcceleration * simulationDeltaTime);
                            if (localVelocity.z < -SerializedFields.singleton.backwardTopSpeed)
                            {
                                localVelocity = new Vector3(localVelocity.x, localVelocity.y, -SerializedFields.singleton.backwardTopSpeed);
                            }
                        }
                        else if (localVelocity.z < -SerializedFields.singleton.backwardTopSpeed)
                        {
                            localVelocity += new Vector3(0, 0, SerializedFields.singleton.brakeAcceleration * simulationDeltaTime);
                            if (localVelocity.z > -SerializedFields.singleton.backwardTopSpeed)
                            {
                                localVelocity = new Vector3(localVelocity.x, localVelocity.y, -SerializedFields.singleton.backwardTopSpeed);
                            }
                        }
                    }
                    else
                    {
                        if (localVelocity.z > 0)
                        {
                            localVelocity -= new Vector3(0, 0, SerializedFields.singleton.friction * 9.81f * simulationDeltaTime);
                            if (localVelocity.z < 0)
                            {
                                localVelocity = new Vector3(localVelocity.x, localVelocity.y, 0);
                            }
                        }
                        else if (localVelocity.z < 0)
                        {
                            if (localVelocity.z < -SerializedFields.singleton.backwardTopSpeed)
                            {
                                localVelocity += new Vector3(0, 0, SerializedFields.singleton.friction * 9.81f * simulationDeltaTime);
                            }
                            else
                            {
                                localVelocity += new Vector3(0, 0, SerializedFields.singleton.idleDeacceleration * simulationDeltaTime);
                                if (localVelocity.z > 0)
                                {
                                    localVelocity = new Vector3(localVelocity.x, localVelocity.y, 0);
                                }
                            }
                        }
                    }
                }

                Vector3 localAngularVelocity = velocity.Angular; // no need to inverse transform

                if (localAngularVelocity.y > SerializedFields.singleton.maxAngularVelocity)
                {
                    localAngularVelocity.y = SerializedFields.singleton.maxAngularVelocity;
                }
                else if (localAngularVelocity.y < -SerializedFields.singleton.maxAngularVelocity)
                {
                    localAngularVelocity.y = -SerializedFields.singleton.maxAngularVelocity;
                }

                Vector3 transformUp = math.mul(rotation.Value, new float3(0, 1, 0));

                float targetAngularVelocityY = Mathf.Min(Vector3.ProjectOnPlane(velocity.Linear, transformUp).magnitude / SerializedFields.singleton.minSpeedForFullRotation, 1) * carComponent.SteerAngle / SerializedFields.singleton.maxSteerAngle * SerializedFields.singleton.maxTurningAngularVelocity * (serverCarComponent.GoingBackward ? -1 : 1);

                if (targetAngularVelocityY > localAngularVelocity.y)
                {
                    localAngularVelocity += new Vector3(0, SerializedFields.singleton.angularAcceleration * simulationDeltaTime, 0);
                    if (localAngularVelocity.y > targetAngularVelocityY)
                    {
                        localAngularVelocity = new Vector3(localAngularVelocity.x, targetAngularVelocityY, localAngularVelocity.z);
                    }
                }
                else if (targetAngularVelocityY < localAngularVelocity.y)
                {
                    localAngularVelocity -= new Vector3(0, SerializedFields.singleton.angularAcceleration * simulationDeltaTime, 0);
                    if (localAngularVelocity.y < targetAngularVelocityY)
                    {
                        localAngularVelocity = new Vector3(localAngularVelocity.x, targetAngularVelocityY, localAngularVelocity.z);
                    }
                }

                localVelocity = Vector3.ProjectOnPlane(localVelocity, Vector3.forward) + Quaternion.AngleAxis(localAngularVelocity.y * simulationDeltaTime, Vector3.up) * Vector3.Project(localVelocity, Vector3.forward);

                if (EntityManager.GetComponentData <BoostComponent>(carEntity).RemainingTime > 0)
                {
                    localVelocity += new Vector3(0, 0, SerializedFields.singleton.boostPowerupAcceleration * simulationDeltaTime);
                }

                velocity.Angular = localAngularVelocity; // no need to transform
                velocity.Linear  = math.mul(rotation.Value, localVelocity);
            });
        }
    }