Beispiel #1
0
    /*enum MeleeFighterState
     * {
     *  TooFar,
     *  TooNear,
     *  InMeleeDistance
     * }
     *
     * MeleeFighterState state;*/

    protected override void Update()
    {
        if (Time.time > nextDistanceCheckTime)
        {
            nextDistanceCheckTime = Time.time + distanceCheckingInterval;

            myWidth    = entity.width;
            enemyWidth = enemySensing.nearestEnemy.width;

            Vector3 nearestEnemyPosition = enemySensing.nearestEnemy.transform.position;
            Vector3 myPosition           = entity.transform.position;

            float   widthFactor    = myWidth + enemyWidth; //multiply the resulting distanceVectorBythisFactor to also use width
            Vector3 distanceVector = nearestEnemyPosition - myPosition;
            //float distanceToEnemySquared = (distanceVector - distanceVector.normalized * widthFactor).sqrMagnitude;
            float distanceToEnemy = (distanceVector - distanceVector.normalized * widthFactor).magnitude;

            //if the enemy is moving, we move to the position he will be at the time we arrive
            EC_Movement enemyMovement = enemySensing.nearestEnemy.GetComponent <EC_Movement>();


            if (enemyMovement.IsMoving())
            {
                //heuristically calculae future position
                //1. how long will it take for me to reach the enemy?
                float timeToReachEnemy = distanceToEnemy / movement.GetMaxSpeed();
                //2. where will the enemy be after this time
                Vector3 futurePosition = nearestEnemyPosition + enemyMovement.GetCurrentVelocity() * timeToReachEnemy;


                movement.MoveTo(futurePosition);
            }
            else
            {
                movement.MoveTo(nearestEnemyPosition + (myPosition - nearestEnemyPosition).normalized * (perfectMeleeDistance + myWidth + enemyWidth));
            }

            if ((nearestEnemyPosition - myPosition).sqrMagnitude > maxMeleeDistance)
            {
                inRange = false;
                movement.StopLookAt();
            }
            else
            {
                inRange = true;
                movement.LookAt(enemySensing.nearestEnemy.transform);
            }
        }

        if (inRange)
        {
            if (weapon.CanAttack())
            {
                weapon.Attack();
            }
        }
    }
    public override void UpdateComponent()
    {
        if (aiming)
        {
            //tod ofix shaking of wepon when enemy is to near on gravity shot someday
            //use weapon transform for rotation, use spwanpoint position for  distance checks

            if (currentTarget != null)
            {
                Vector3 desiredAimVector = Vector3.zero;


                if (!gravityProjectile)
                {
                    //if the projectile flies straight with no gravity, we just calculate the time in air and aim there


                    if (hasMovement)
                    {
                        float timeInAir = (currentTarget.GetPositionForAiming() - projectileSpawnPoint.position).magnitude / initialLaunchSpeed;

                        //now calculate again, but with speed of the target added
                        timeInAir = ((currentTarget.GetPositionForAiming() + currentEnemyMovement.GetCurrentVelocity() * timeInAir) - projectileSpawnPoint.position).magnitude / initialLaunchSpeed;

                        desiredAimVector = (currentTarget.GetPositionForAiming() + currentEnemyMovement.GetCurrentVelocity() * timeInAir) - transform.position;
                    }
                    else
                    {
                        desiredAimVector = currentTarget.GetPositionForAiming() - transform.position;
                    }
                }
                else
                {
                    Vector3 enemyPosition       = currentTarget.GetPositionForAiming();
                    Vector3 launchPointPosition = projectileSpawnPoint.position;
                    Vector3 weaponPosition      = transform.position;

                    //refactor positions - get the m only once

                    if (hasMovement)
                    {
                        //1. calculate the launch angle

                        Vector3 distDelta   = enemyPosition - launchPointPosition;
                        float   launchAngle = GetLaunchAngle
                                              (
                            initialLaunchSpeed,
                            new Vector3(distDelta.x, 0f, distDelta.z).magnitude,
                            distDelta.y,
                            true
                                              );


                        //2. calculate time in air, and adjust the rotation

                        float timeInAir;
                        float g  = Physics.gravity.magnitude;
                        float vY = initialLaunchSpeed * Mathf.Sin(launchAngle * (Mathf.PI / 180));
                        //vY = 5f;
                        float startH = launchPointPosition.y;
                        float finalH = enemyPosition.y;

                        if (finalH < startH)
                        {
                            timeInAir = (vY + Mathf.Sqrt((float)(Mathf.Pow(vY, 2) - 4 * (0.5 * g) * (-(startH - finalH))))) / g;
                        }
                        else
                        {
                            float vX        = initialLaunchSpeed * Mathf.Cos(launchAngle * (Mathf.PI / 180));
                            float distanceX = Vector3.Distance(enemyPosition, launchPointPosition);
                            timeInAir = distanceX / vX;
                        }

                        desiredAimVector   = (enemyPosition + currentEnemyMovement.GetCurrentVelocity() * timeInAir) - weaponPosition;
                        desiredAimVector.y = 0;
                        desiredAimVector   = Quaternion.AngleAxis(-launchAngle, transform.right) * desiredAimVector;
                        //Debug.Log("has movement: " + launchAngle);
                    }
                    else
                    {
                        Vector3 distDelta = enemyPosition - launchPointPosition;
                        //1. calculate the launch angle
                        float launchAngle = GetLaunchAngle
                                            (
                            initialLaunchSpeed,
                            new Vector3(distDelta.x, 0f, distDelta.z).magnitude,
                            distDelta.y,
                            true
                                            );

                        //desiredAimVector = Quaternion.AngleAxis(-launchAngle, projectileSpawnPoint.right) * desiredAimVector;
                        desiredAimVector   = enemyPosition - weaponPosition;
                        desiredAimVector.y = 0;
                        desiredAimVector   = Quaternion.AngleAxis(-launchAngle, transform.right) * desiredAimVector;
                        //Debug.Log("no movement: " + launchAngle);
                    }
                }

                RotateTowards(desiredAimVector);
            }
        }
        else
        {
            RotateTowards(parent.forward);
        }
    }