コード例 #1
0
    private void Update()
    {
        // internal variables
        float   speed        = velocity.magnitude;
        Vector3 avgVeclocity = Vector3.zero;
        Vector3 avgPosition  = Vector3.zero;
        float   count        = 0;
        float   f            = 0.0f;
        float   d            = 0.0f;
        Vector3 myPosition   = transformComponent.position;
        Vector3 forceV;
        Vector3 toAvg;
        Vector3 wantedVel;

        for (int i = 0; i < objects.Length; i++)
        {
            Transform transform = objects[i];
            if (transform != transformComponent)
            {
                Vector3 otherPosition = transform.position;

                //Average position to calculate cohesion
                avgPosition += transform.position;
                count++;

                //Directional vector from other flock to this flock
                forceV = myPosition - otherPosition;

                //Magnitude of that directional vector (Length)
                d = forceV.magnitude;

                //Add the push value if the magnitude, the length of the vector,
                // is less than the followRadius to the leader
                if (d < followRadius)
                {
                    //calculate the velocity, the speed of the object, based on
                    // the avoidance distance between flocks if the current magnitude is less
                    // than the specified avoidance radius
                    if (d < avoidanceRadius)
                    {
                        f = 1.0f - (d / avoidanceRadius);
                        if (d > 0)
                        {
                            avgVeclocity += (forceV / d) * f * avoidanceForce;
                        }
                    }

                    // just keep the current distance with the leader
                    f = d / followRadius;
                    UnityFlock otherSeagull = otherFlocks[i];
                    // we normalize the otherSeagull velocity vector to get
                    // the direction of movement, then we set a new velocity
                    avgVeclocity += otherSeagull.normalizedVelocity * f * followVelocity;
                }
            }
        }
    }
コード例 #2
0
 // Use this for initialization
 void Start()
 {
     for (int i = 0; i < flockSize; i++)
     {
         UnityFlock flock = Instantiate(prefab, transform.position, transform.rotation) as UnityFlock;
         flock.transform.parent = transform;
         flock.controller       = this;
         flockList.Add(flock);
     }
 }
コード例 #3
0
    public void ReturnFlockInSwarmToHive(SwarmTravelController swarmCtrl)
    {
        UnityFlock flock = swarmCtrl.UnregisterRandomFlock();

        if (flock == null)
        {
            return;
        }

        originSwarm.RegisterFlock(flock);
        //foreach(UnityFlock flock in swarm)
    }
コード例 #4
0
    public UnityFlock UnregisterRandomFlock()
    {
        if (flockBehaviors.Count == 0)
        {
            return(null);
        }
        UnityFlock removedFlock = flockBehaviors[0];

        flockTransforms.Remove(removedFlock.GetComponent <Transform>());
        flockBehaviors.RemoveAt(0);

        return(removedFlock);
    }
コード例 #5
0
    public void RegisterFlock(UnityFlock flock)
    {
        if (flockBehaviors.Contains(flock))
        {
            return;
        }

        flockTransforms.Add(flock.GetComponent <Transform>());
        flockBehaviors.Add(flock);

        flock.travelOrigin = this;
        flock.origin       = this.transform;
    }
コード例 #6
0
    //public void SetDestinationSwarm(int indexSwarm)
    //{
    //    if (indexSwarm < swarmControllers.Count)
    //    {
    //        print("SetDestinationSwarm: " + indexSwarm.ToString());
    //        destinationSwarm = swarmControllers[indexSwarm];

    //    }
    //}

    public void SendFlockBetweenSwarms()
    {
        print("swarms count:" + swarmControllers.Count);

        UnityFlock flock = originSwarm.UnregisterRandomFlock();

        if (flock == null)
        {
            return;
        }

        destinationSwarm.RegisterFlock(flock);

        print("flock A:" + originSwarm.flockTransforms.Count.ToString());
        print("flock B:" + destinationSwarm.flockTransforms.Count.ToString());

        OnHomeWorkerCountChange.Invoke(originSwarm.flockBehaviors.Count);
    }
コード例 #7
0
ファイル: UnityFlock.cs プロジェクト: edonhi1/20180212
    void Update()
    {
        float   speed       = velocity.magnitude;
        Vector3 avgVelocity = Vector3.zero;
        Vector3 avgPosition = Vector3.zero;
        float   count       = 0;
        float   f           = 0f;
        float   d           = 0f;
        Vector3 myPosition  = transformComponent.position;
        Vector3 forceV;
        Vector3 toAvg;
        Vector3 wantedVel;

        for (int i = 0; i < objects.Length; i++)
        {
            Transform transform = objects[i];
            if (transform != transformComponent)
            {
                Vector3 otherPosition = transform.position;
                avgPosition += otherPosition;
                count++;
                forceV = myPosition - otherPosition;
                d      = forceV.magnitude;
                if (d < followRadius)
                {
                    f = 1f - (d / avoidanceRadius);
                    if (d > 0)
                    {
                        avgVelocity += (forceV / d) * f * avoidanceForce;
                    }
                }
                f = d / followRadius;
                UnityFlock otherSeaGull = otherFlocks[i];
                avgVelocity += otherSeaGull.normalizedVelocity * f * followVelocity;
            }
        }
    }
コード例 #8
0
    void Update()
    {
        //Internal variables
        float   speed       = velocity.magnitude;
        Vector3 avgVelocity = Vector3.zero;
        Vector3 avgPosition = Vector3.zero;
        float   count       = 0;
        float   f           = 0.0f;
        float   d           = 0.0f;
        Vector3 myPosition  = transformComponent.position;
        Vector3 forceV;
        Vector3 toAvg;
        Vector3 wantedVel;

        for (int i = 0; i < objects.Length; i++)
        {
            Transform transform = objects[i];
            if (transform != transformComponent)
            {
                Vector3 otherPosition = transform.position;

                // Average position to calculate cohesion
                avgPosition += otherPosition;
                count++;

                //Directional vector from other flock to this flock
                forceV = myPosition - otherPosition;

                //Magnitude of that directional vector(Length)
                d = forceV.magnitude;

                //Add push value if the magnitude is less than follow radius to the leader
                if (d < followRadius)
                {
                    //calculate the velocity based on the avoidance distance between flocks
                    //if the current magnitude is less than the specified avoidance radius
                    if (d < avoidanceRadius)
                    {
                        f = 1.0f - (d / avoidanceRadius);

                        if (d > 0)
                        {
                            avgVelocity += (forceV / d) * f * avoidanceForce;
                        }
                    }

                    //just keep the current distance with the leader
                    f = d / followRadius;
                    UnityFlock tempOtherFlock = otherFlocks[i];
                    avgVelocity += tempOtherFlock.normalizedVelocity * f * followVelocity;
                }
            }
        }

        if (count > 0)
        {
            //Calculate the average flock velocity(Alignment)
            avgVelocity /= count;

            //Calculate Center value of the flock(Cohesion)
            toAvg = (avgPosition / count) - myPosition;
        }
        else
        {
            toAvg = Vector3.zero;
        }

        //Directional Vector to the leader
        forceV = origin.position - myPosition;
        d      = forceV.magnitude;
        f      = d / toOriginRange;

        //Calculate the velocity of the flock to the leader
        if (d > 0)
        {
            originPush = (forceV / d) * f * toOriginForce;
        }

        if (speed < minSpeed && speed > 0)
        {
            velocity = (velocity / speed) * minSpeed;
        }

        wantedVel = velocity;

        //Calculate final velocity
        wantedVel -= wantedVel * Time.deltaTime;
        wantedVel += randomPush * Time.deltaTime;
        wantedVel += originPush * Time.deltaTime;
        wantedVel += avgVelocity * Time.deltaTime;
        wantedVel += toAvg.normalized * gravity * Time.deltaTime;

        //Final Velocity to rotate the flock into
        velocity = Vector3.RotateTowards(velocity, wantedVel, turnSpeed * Time.deltaTime, 100.00f);
        transformComponent.rotation = Quaternion.LookRotation(velocity);

        //Move the flock based on the calculated velocity
        transformComponent.Translate(velocity * Time.deltaTime, Space.World);

        //normalise the velocity
        normalizedVelocity = velocity.normalized;
    }
コード例 #9
0
    void Update()
    {
        //speed的标量
        float speed = velocity.magnitude;
        //初始化平均速度
        Vector3 avgVelocity = Vector3.zero;
        //初始化平均位置
        Vector3 avgPosition = Vector3.zero;
        //集群内其余对象的数量
        float count = 0;

        float   f          = 0.0f;
        float   d          = 0.0f;
        Vector3 myPosition = transform.position;
        Vector3 forceV;
        //该对象到平均对象的向量
        Vector3 toAvg;
        //最终的速度方向
        Vector3 wantedVel;

        for (int i = 0; i < objects.Length; i++)
        {
            Transform trans = objects[i];
            if (trans != this.transform)
            {
                Vector3 otherPosition = trans.position;

                //通过平均位置来计算合力
                avgPosition += otherPosition;
                count++;

                //其它对象移动到本对象的向量
                forceV = myPosition - otherPosition;

                //当前对象与数组内其他对象的距离
                d = forceV.magnitude;

                //Add push value if the magnitude is less than follow radius to the leader
                if (d < followRadius)
                {
                    //calculate the velocity based on the avoidance distance between flocks
                    //if the current magnitude is less than the specified avoidance radius
                    if (d < avoidanceRadius)
                    {
                        f = 1.0f - (d / avoidanceRadius);

                        if (d > 0)
                        {
                            avgVelocity += (forceV / d) * f * avoidanceForce;
                        }
                    }

                    //保持和leader的距离
                    f = d / followRadius;
                    UnityFlock tempOtherFlock = otherFlocks[i];
                    avgVelocity += tempOtherFlock.normalizedVelocity * f * followVelocity;
                }
            }
        }

        if (count > 0)
        {
            //计算队列力
            avgVelocity /= count;

            //计算聚合的方向
            toAvg = (avgPosition / count) - myPosition;
        }
        else
        {
            toAvg = Vector3.zero;
        }

        //Directional Vector to the leader
        forceV = origin.position - myPosition;
        d      = forceV.magnitude;
        f      = d / toOriginRange;

        //Calculate the velocity of the flock to the leader
        if (d > 0)
        {
            originPush = (forceV / d) * f * toOriginForce;
        }

        if (speed < minSpeed && speed > 0)
        {
            velocity = (velocity / speed) * minSpeed;
        }

        wantedVel = velocity;

        //想要移动的方向
        wantedVel -= wantedVel * Time.deltaTime;
        //随机力的方向
        wantedVel += randomPush * Time.deltaTime;
        //推向领头鱼的方向
        wantedVel += originPush * Time.deltaTime;
        //范围内的所有群集平均方向
        wantedVel += avgVelocity * Time.deltaTime;
        //聚合速度的方向
        wantedVel += toAvg.normalized * gravity * Time.deltaTime;

        //最终鱼的旋转方向和速度方向
        velocity = Vector3.RotateTowards(velocity, wantedVel, turnSpeed * Time.deltaTime, 100.00f);

        //旋转向当前的速度方向
        transform.rotation = Quaternion.LookRotation(velocity);

        //向合力的方向移动
        transform.Translate(velocity * Time.deltaTime, Space.World);

        //更新标准化速度
        normalizedVelocity = velocity.normalized;
    }
コード例 #10
0
    // Update is called once per frame
    void Update()
    {
        float   speed       = velocity.magnitude;
        Vector3 avgVelocity = Vector3.zero;
        Vector3 avgPosition = Vector3.zero;
        float   count       = 0;
        float   f           = 0.0f;
        float   d           = 0.0f;
        Vector3 myPosition  = transformCompont.position;
        Vector3 forceV;
        Vector3 toAvg;
        Vector3 wantedVel;

        //for (int i = 0; i < objects.Length; i++)
        foreach (Transform transform in travelOrigin.flockTransforms)
        {
            //Transform transform = objects[i];
            if (transform != transformCompont)
            {
                Vector3 otherPositon = transform.position;

                //平均位置来计算聚合
                avgPosition += otherPositon;
                count++;

                //从其他群体到这个的向量
                forceV = myPosition - otherPositon;

                //上面向量的长度
                d = forceV.magnitude;

                //如果向量长度比规避半径小的话,则加大推力
                if (d < followRadius)
                {
                    //如果当前的向量长度小于规定的逃离半径的话,则基于 逃离半径计算对象的速度
                    if (d > 0)
                    {
                        f            = 1.0f - (d / avoidanceRadius);
                        avgVelocity += (forceV / d) * f * avoidanceForce;
                        //向量除以它的模得到自己的单位向量
                    }
                }

                //保持与头儿的距离
                f = d / followRadius;
                //UnityFlock otherSealgull = otherFlocks[i];
                UnityFlock otherSealgull = transform.GetComponent <UnityFlock>();

                //标准化otherSealgul的速度来获取移动的方向,接下来设置一个新的速度
                avgVelocity += otherSealgull.normalizedVelicity * f * followVelocity;
            }
        }

        if (count > 0)
        {
            //得到平均速度
            avgVelocity /= count;
            //获得平均位置与对象间的向量
            toAvg = (avgPosition / count) - myPosition;
        }
        else
        {
            toAvg = Vector3.zero;
        }

        //
        forceV = origin.position - myPosition;
        d      = forceV.magnitude;
        f      = d / toOriginRange;
        //
        if (d > 0)
        {
            originPush = (forceV / d) * f * toOriginForce;
        }
        if (speed < minSpeed && speed > 0)
        {
            velocity = (velocity / speed) * minSpeed;
        }

        wantedVel = velocity;

        //最终速度
        wantedVel -= wantedVel * Time.deltaTime;
        wantedVel += randomPush * Time.deltaTime;
        wantedVel += originPush * Time.deltaTime;
        wantedVel += avgVelocity * Time.deltaTime;
        wantedVel += toAvg.normalized * gravity * Time.deltaTime;

        //调整速度使之转向最终速度
        velocity = Vector3.RotateTowards(velocity, wantedVel, turnSpeed * Time.deltaTime, 100.00f);

        transformCompont.rotation = Quaternion.LookRotation(velocity);

        //移动对象
        transformCompont.Translate(velocity * Time.deltaTime, Space.World);

        //跟新标准化向量的引用
        normalizedVelicity = velocity.normalized;
    }
コード例 #11
0
    void Update()
    {
        //1.首先检查当前boid与其他boid之间的距离,并相应地更新速度
        float   tSpeed       = velocity.magnitude;  //速度的大小
        Vector3 tAvgVelocity = Vector3.zero;
        Vector3 tAvgPosition = Vector3.zero;
        float   tCount       = 0;
        float   tF           = 0f;
        float   tDistance    = 0f;
        Vector3 tMyPosition  = transformComponent.position;
        Vector3 tForceV;
        Vector3 tToArg;
        Vector3 tWantedVel;

        #region 此处代码用于实现"分离"规则。首先,检查当前boid与其他boid之间的距离,并相应的更新速度,接下来,用当前速度除以群组中的boid的数目,计算出群组的平均速度
        for (int i = 0; i < objects.Length; i++)
        {
            Transform tTransform = objects[i];  //除我之外的成员的位置
            if (tTransform != transformComponent)
            {
                Vector3 tOtherPosition = tTransform.position;
                //平均速度 计算聚合
                tAvgPosition += tOtherPosition;
                tCount++;
                //其他群体到这个的向量
                tForceV = tMyPosition - tOtherPosition;
                //求向量长度(方向)
                tDistance = tForceV.magnitude;
                //向量长度小于追随半径,跟上
                if (tDistance < followRadius)
                {
                    //当前向量长度小于规避半径,基于逃离半径计算对象的速度
                    //如果两物体的当前距离已经小于最小距离,根据物体间的最小距离计算物体的速度
                    if (tDistance < avoidanceRadius)
                    {
                        tF = 1 - (tDistance / avoidanceRadius);
                        if (tDistance > 0)
                        {
                            tAvgVelocity += (tForceV / tDistance) * tF * avoidanceForce;    //求得自己的单位向量
                        }
                    }
                    //保持与头的距离
                    tF = tDistance / followRadius;
                    UnityFlock tOtherSealgull = otherFlocks[i];
                    //自己的速度与朝向取决于其他个体的速度与朝向 计算出后设置给自己
                    tAvgVelocity += tOtherSealgull.normalizedVelocity * tF * followVelocity;
                }
            }
        }
        #endregion
        //2.用当前速度除以群组中的boid的数目,计算出群组的平均速度。
        if (tCount > 0)
        {
            //获得平均速度(队列)
            tAvgVelocity /= tCount;
            //获得平均位置与对象间的向量(凝聚)
            tToArg = (tAvgPosition / tCount) - tMyPosition;
        }
        else
        {
            tToArg = Vector3.zero;
        }

        //朝向领队
        tForceV   = origin.position - tMyPosition;              //计算领队与我的位置的距离
        tDistance = tForceV.magnitude;                          //距离的大小
        tF        = tDistance / toOriginRange;                  //计算大小是半径的多少
        //Calculate the velocity of the Flocks to the leader
        if (tDistance > 0)                                      //if this Boid is not at the center of the Flock    //不在群组中间的时候
        {
            originPush = (tForceV / tDistance) * toOriginForce; //给一个初始的速度
        }

        if (tSpeed < minSpeed && tSpeed > 0)            //速度的值小于最小速度
        {
            velocity = (velocity / tSpeed) * minSpeed;  //速度就是最小速度  给最小速度改下方向
        }

        tWantedVel = velocity;
        //计算最终速度
        tWantedVel -= tWantedVel * Time.deltaTime;
        tWantedVel += randomPush * Time.deltaTime;                  //随机的推力
        tWantedVel += originPush * Time.deltaTime;                  //初始的推力
        tWantedVel += tAvgVelocity * Time.deltaTime;                //其他成员的速度
        tWantedVel += tToArg.normalized * gravity * Time.deltaTime; //根据吸引力调节速度快慢
        //调整速度并使其转向最终速度
        velocity = Vector3.RotateTowards(velocity, tWantedVel, turnSpeed * Time.deltaTime, 100f);
        transformComponent.rotation = Quaternion.LookRotation(velocity);


        //根据计算后的速度移动对象
        transformComponent.Translate(velocity * Time.deltaTime, Space.World);
        //更新标准向量的引用
        normalizedVelocity = velocity.normalized;
    }
コード例 #12
0
    // Update is called once per frame
    void Update()
    {
        float   speed       = velocity.magnitude;
        Vector3 avgVelocity = Vector3.zero;
        Vector3 avgPosition = Vector3.zero;
        float   count       = 0;
        float   f           = 0.0f;
        float   d           = 0.0f;
        Vector3 myPosition  = transformComponent.position;
        Vector3 forceV;
        Vector3 toAvg;
        Vector3 wantedVel;

        for (int i = 0; i < objects.Length; i++)
        {
            Transform transform = objects[i];
            if (transform != transformComponent)
            {
                Vector3 otherPosition = transform.position;
                avgPosition += otherPosition;
                count++;
                forceV = myPosition - otherPosition;
                d      = forceV.magnitude;
                if (d < followRadius)
                {
                    if (d < avoidanceRadius)
                    {
                        f = 1.0f - (d / avoidanceRadius);
                        if (d > 0)
                        {
                            avgVelocity += (forceV / d) * f * avoidanceForce;
                        }
                    }
                    f = d / followRadius;
                    UnityFlock otherSealgull = otherFlocks[i];
                    avgVelocity += otherSealgull.normalizedVelocity * f * followVelociy;
                }
            }
        }
        if (count > 0)
        {
            avgVelocity /= count;
            toAvg        = (avgPosition / count) - myPosition;
        }
        else
        {
            toAvg = Vector3.zero;
        }
        forceV = origin.position - myPosition;
        d      = forceV.magnitude;
        f      = d / toOriginRange;
        if (d > 0)
        {
            originPush = (forceV / d) * f * toOriginForce;
        }
        if (speed < minSpeed && speed > 0)
        {
            velocity = (velocity / speed) * minSpeed;
        }
        wantedVel  = velocity;
        wantedVel -= wantedVel * Time.deltaTime;
        wantedVel += randomPush * Time.deltaTime;
        wantedVel += originPush * Time.deltaTime;
        wantedVel += avgVelocity * Time.deltaTime;
        wantedVel += toAvg.normalized * gravity * Time.deltaTime;
        velocity   = Vector3.RotateTowards(velocity, wantedVel, turnSpeed * Time.deltaTime, 100.00f);
        transformComponent.rotation = Quaternion.LookRotation(velocity);
        transformComponent.Translate(velocity * Time.deltaTime, Space.World);
        normalizedVelocity = velocity.normalized;
    }