Example #1
0
    void GetNearBoid()
    {
        float m = Mathf.Infinity;

        nearBoid = null;
        foreach (Boid b in boidGroup.boids)
        {
            float sm = (b.position - position).sqrMagnitude;
            if (sm != 0 && sm < m)
            {
                m        = sm;
                nearBoid = b;
            }
        }

        m      = Mathf.Infinity;
        target = null;
        foreach (BoidTarget bt in boidGroup.targets)
        {
            float sm = (bt.transform.position - position).sqrMagnitude / bt.strength;
            if (sm < m)
            {
                m      = sm;
                target = bt;
            }
        }
    }
Example #2
0
	// Use this for initialization
	void Start () {
        firstTarget = CreateTarget(0);
        BoidTarget prevTarget = firstTarget;

        for (int i = 1; i < count; i++) {
            BoidTarget t = CreateTarget(i);
            t.nextTarget = prevTarget;
            prevTarget = t;
        }

        firstTarget.nextTarget = prevTarget;
	}
Example #3
0
    public void CreateBoid(Vector3 position, Vector3 launchDirection, BoidTarget target = null) {
        BoidBehaviour boid = (BoidBehaviour)Instantiate(boidPrefab, position, Quaternion.identity);
        boid.transform.parent = transform;
        boid.SoundManager = soundManager;
        boid.Launch(launchDirection);

        boid.target = target;

        activeBoids.Add(boid);
    }
Example #4
0
    private BoidTarget SelectGroupTarget(ref Dictionary<BoidTarget, int> counts, BoidTarget curTarget, BoidTarget newTarget) {
        int curTargetCount;
        if (curTarget != null && counts.ContainsKey(curTarget)) {
            curTargetCount = counts[curTarget];
        } else {
            curTargetCount = 0;
        }

        int newTargetCount;
        if (counts.ContainsKey(newTarget)) {
            newTargetCount = counts[newTarget] + 1;
            counts[newTarget] = newTargetCount;
        } else {
            newTargetCount = 1;
            counts.Add(newTarget, newTargetCount);
        }

        if (newTargetCount > curTargetCount) {
            return newTarget;
        } else {
            return curTarget;
        }
    }
Example #5
0
    private void FlyUpdate(Vector3 playerPosition, Vector3 playerVelocity) {
        Vector3 toPlayer = playerPosition - transform.position;
        float toPlayerDist = toPlayer.magnitude;
        
        // modifications based on proximity to player
        float noise = Mathf.PerlinNoise(Time.time, noiseOffset) * 2f - 1f;
        float frameSpeed = maxSpeed * (1f + noise * speedVariance);
        bool targetPlayer = false;

        // find flock
        Collider[] colliders = Physics.OverlapSphere(transform.position, sensorRadius, sensorLayerMask, QueryTriggerInteraction.Ignore);

        // get flock center and velocity
        Vector3 flockCenter = Vector3.zero;
        Vector3 flockVelocity = Vector3.zero;
        Vector3 avoidance = Vector3.zero;
        int count = 0;

        scratch.Clear();
        if (target != null) {
            target = SelectGroupTarget(ref scratch, target, target);
        }

        for (int i = 0; i < colliders.Length; i++) {
            BoidBehaviour boid = GetComponentCache.Instance.GetComponent<BoidBehaviour>(colliders[i]);
            if (boid != null && boid != this && boid.type == type) {
                flockCenter += boid.transform.position;
                flockVelocity += boid.velocity;
                count++;

                Vector3 toBoid = boid.transform.position - transform.position;
                float toBoidDist = toBoid.magnitude;
                if (toBoidDist < avoidanceDist) {
                    avoidance -= (toBoid / toBoidDist) * (avoidanceDist - toBoidDist);
                }

                if (boid.target != null) {
                    target = SelectGroupTarget(ref scratch, target, boid.target);
                }

                // also avoid segments
                if (type == BoidType.Giant) {
                    SegmentBehaviour[] boidSegments = boid.Segments;
                    for (int j = 0; j < boidSegments.Length; j++) {
                        Vector3 toSegment = boidSegments[j].transform.position - transform.position;
                        float toSegmentDist = toSegment.magnitude;
                        if (toSegmentDist < avoidanceDist) {
                            avoidance -= (toSegment / toSegmentDist) * (avoidanceDist - toSegmentDist);
                        }
                    }
                }

                continue;
            }
        }

        // special case: consider player a boid
        if (flockWithPlayer && toPlayerDist < playerSensorRadius) {
            if (!flockedWithPlayerLastFrame) {
                PlaySound(true);
                flockedWithPlayerLastFrame = true;
            }

            flockCenter += playerPosition;
            flockVelocity += playerVelocity;
            count++;

            if (toPlayerDist < avoidanceDist) {
                avoidance -= (toPlayer /  toPlayerDist) * (avoidanceDist - toPlayerDist);
            }

            // new max speed
            float playerSpeed = playerVelocity.magnitude * (1f + noise * speedVariance);
            frameSpeed = Mathf.Max(frameSpeed, Mathf.Lerp(playerSpeed, playerSpeed * playerSpeedMult,
                Mathf.Clamp01(Mathf.InverseLerp(playerSensorRadius, avoidanceDist, toPlayerDist))));

            targetPlayer = targetPlayerWhenClose;
        } else {
            flockedWithPlayerLastFrame = false;
        }

        // avoid phys collisions
        RaycastHit hit;
        if (Physics.SphereCast(transform.position, boidRadius, transform.forward, out hit, rayCastDist, collisionLayerMask)) {
            Vector3 avoidDir = Vector3.ProjectOnPlane(hit.normal, transform.forward).normalized;
            Vector3 avoidForce =  Mathf.InverseLerp(rayCastDist, 0f, hit.distance) * avoidDir * physAvoidanceMultiplier;
            avoidance += avoidForce;

            Debug.DrawLine(hit.point, hit.point + avoidForce, Color.magenta);
        }

        // calc new velocity
        Vector3 newVelocity = Vector3.zero;

        // avoid other boids and obstacles
        newVelocity += avoidance * avoidanceWeight;

        if (count > 0) {
            flockCenter /= count;
            flockVelocity /= count;

            // move toward center of flock
            newVelocity += (flockCenter - transform.position) * centeringWeight;

            // match velocity
            newVelocity += flockVelocity * steeringWeight;
        }

        if (targetPlayer) {
            newVelocity += (playerPosition - transform.position) * targettingWeight;
        } else if (target != null) {
            if (target.InRange(transform.position)) {
                target = target.nextTarget;
            }
            newVelocity += (target.transform.position - transform.position) * targettingWeight;
        }

        // rotate towards new direction
        newVelocity = newVelocity.normalized * frameSpeed;
        float maxAngle = rotSpeed * Time.deltaTime;

        float goalAngle = Vector3.Angle(velocity, newVelocity);
        Quaternion newRotation;
        if (goalAngle > maxAngle) {
            newRotation = Quaternion.RotateTowards(Quaternion.LookRotation(velocity), Quaternion.LookRotation(newVelocity), maxAngle);
        } else {
            newRotation = Quaternion.LookRotation(newVelocity);
        }

        // find y rotation for roll calc
        float yRot = transform.rotation.eulerAngles.y - newRotation.eulerAngles.y;
        if (yRot < -180f) {
            yRot += 360f;
        } else if (yRot > 180f) {
            yRot -= 360f;
        }
        float rollGoal = Mathf.Clamp((yRot / Time.deltaTime) * rollCoef, -maxRoll, maxRoll);
        roll = Mathf.SmoothDampAngle(roll, rollGoal, ref rollVelocity, rollTime, rotSpeed);

        transform.rotation = newRotation;
        velocity = transform.forward * frameSpeed;
        transform.position += velocity * Time.deltaTime;

        // add roll
        Debug.DrawLine(transform.position, transform.position + transform.up * 2f, Color.green);
        transform.Rotate(0f, 0f, roll, Space.Self);
        Debug.DrawLine(transform.position, transform.position + transform.up * 2f, Color.green);
    }
Example #6
0
    void GetNearBoid()
    {
        float m = Mathf.Infinity;
        nearBoid = null;
        foreach(Boid b in boidGroup.boids){
            float sm = (b.position - position).sqrMagnitude;
            if(sm != 0 && sm < m){
                m = sm;
                nearBoid = b;
            }
        }

        m = Mathf.Infinity;
        target = null;
        foreach(BoidTarget bt in boidGroup.targets){
            float sm = (bt.transform.position - position).sqrMagnitude/bt.strength;
            if(sm < m){
                m = sm;
                target = bt;
            }
        }
    }