예제 #1
0
    public void TagAIAgentWithinViewRange(AIAgent entity, float radius)
    {
        foreach (KeyValuePair <int, AIGroup> ai in m_aiGroup)
        {
            List <AIAgent> entities = ai.Value.Agents();

            for (int i = 0; i < entities.Count; ++i)
            {
                AIAgent curEntity = entities[i];

                //first clear any current tag
                curEntity.UnTagging();

                Vector3 to = curEntity.VPos() - entity.VPos();

                //the bounding radius of the other is taken into account by adding it
                //to the range
                float range = radius + curEntity.BRadius();

                //if entity within range, tag for further consideration. (working in
                //distance-squared space to avoid sqrts)
                if ((curEntity.GetHashCode() != entity.GetHashCode()) &&
                    (to.sqrMagnitude < range * range))
                {
                    curEntity.Tagging();
                }
            }
        }
    }
예제 #2
0
    public void AIUpdate()
    {
        //update the time elapsed

        //keep a record of its old position so we can update its cell later
        //in this method
        Vector3 OldVelocity = aiAgent.Velocity();

        Vector3 SteeringForce = Vector3.zero;

        //calculate the combined force from each steering behavior in the
        //vehicle's list
        SteeringForce = steeringBehaviour.Calculate();

        //Acceleration = Force/Mass
        Vector3 acceleration = SteeringForce / aiAgent.Mass();
        Vector3 gravityaccel = steeringBehaviour.GravityAccel();

        grounded = (gravityaccel.magnitude > 0) ? true : false;

        aiAgent.Update(acceleration, gravityaccel, useWrapAround, Time.deltaTime);

        Vector3 vPos = aiAgent.VPos();

        vPos.y = steeringBehaviour.GravityTruncate(vPos.y);

        aiAgent.SetVPos(vPos);

        //EnforceNonPenetrationConstraint(this, World()->Agents());

        //update the vehicle's current cell if space partitioning is turned on
        if (isSmoothingOn())
        {
            m_vSmoothedHeading = m_pHeadingSmoother.Update(aiAgent.Heading());
        }

        //moveState
        if (steeringBehaviour.IsSteering())
        {
            float epsillon = 0.01f;

            if (MathUtil.Equal(aiAgent.Velocity(), Vector3.zero, epsillon) &&
                OldVelocity.magnitude >= epsillon)
            {
                if (onMoveComplete != null)
                {
                    onMoveComplete(aiAgent, steeringBehaviour, MoveCompleteState.Reached);
                }
            }
            else if (gravityaccel.magnitude <= 0 &&
                     gravityaccel_old.magnitude > 0)
            {
                if (onMoveComplete != null)
                {
                    onMoveComplete(aiAgent, steeringBehaviour, MoveCompleteState.Landed);
                }
            }
        }

        gameObject.transform.position = aiAgent.VPos();

        if (useRotation)
        {
            Vector3 vDir = aiAgent.Heading();

            if (vDir.magnitude > 0)
            {
                gameObject.transform.rotation = Quaternion.LookRotation(vDir);
            }
        }

        Vector3 target = gameObject.transform.position + gameObject.transform.rotation * Vector3.forward * aiAgent.BRadius();

        gravityaccel_old = gravityaccel;

        DebugExtension.DebugCircle(target, 0.5f);
    }
예제 #3
0
    /**
     *  Given a vector of obstacles, this method returns a steering force
     *  that will prevent the agent colliding with the closest obstacle
     */
    private Vector3 ObstacleAvoidance(List <AIObject> obstacles)
    {
        //*
        //the detection box length is proportional to the agent's velocity
        m_fDBoxLength = minDetectionBoxLength
                        + (m_entity.Speed() / m_entity.MaxSpeed())
                        * minDetectionBoxLength;

        //tag all obstacles within range of the box for processing
        m_entity.World().TagObstaclesWithinViewRange(m_entity, m_fDBoxLength);

        //this will keep track of the closest intersecting obstacle (CIB)
        AIObject ClosestIntersectingObstacle = null;

        //this will be used to track the distance to the CIB
        float DistToClosestIP = float.MaxValue;

        //this will record the transformed local coordinates of the CIB
        Vector3 LocalPosOfClosestObstacle = Vector3.zero;

        IEnumerator <AIObject> it = obstacles.GetEnumerator();

        for (int i = 0; i < obstacles.Count; ++i)
        {
            //if the obstacle has been tagged within range proceed
            AIObject curOb = obstacles[i];

            if (curOb.Tag)
            {
                //calculate this obstacle's position in local space
                Vector3 LocalPos = MathUtil.PointToLocalSpace(curOb.VPos(),
                                                              m_entity.Heading(),
                                                              m_entity.Side(),
                                                              m_entity.VPos());


                // entity Heading and LocalPos is
                if (Vector3.Dot(LocalPos, Vector3.forward) > 0)
                {
                    //than its radius + half the width of the detection box then there
                    //is a potential intersection.
                    float ExpandedRadius = curOb.BRadius() + m_entity.BRadius();

                    if (Mathf.Abs(LocalPos.x) < ExpandedRadius)
                    {
                        //test to see if this is the closest so far. If it is keep a
                        //record of the obstacle and its local coordinates
                        if (LocalPos.magnitude < DistToClosestIP)
                        {
                            DistToClosestIP = LocalPos.magnitude;

                            ClosestIntersectingObstacle = curOb;

                            LocalPosOfClosestObstacle = LocalPos;
                        }
                    }
                }
            }
        }

        //if we have found an intersecting obstacle, calculate a steering
        //force away from it
        Vector3 steeringForce = Vector3.zero;

        if (ClosestIntersectingObstacle != null)
        {
            //should be
            //the closer the agent is to an object, the stronger the
            //steering force should be
            float multiplier = 1.0f + (m_fDBoxLength - LocalPosOfClosestObstacle.z)
                               / m_fDBoxLength;

            //calculate the lateral force
            steeringForce.x = (ClosestIntersectingObstacle.BRadius()
                               - LocalPosOfClosestObstacle.x) * multiplier;

            //apply a braking force proportional to the obstacles distance from
            //the vehicle.
            float BrakingWeight = 0.2f;

            steeringForce.z = (ClosestIntersectingObstacle.BRadius()
                               - LocalPosOfClosestObstacle.z)
                              * BrakingWeight;
        }

        //finally, convert the steering vector from local to world space
        return(MathUtil.VectorToWorldSpace(steeringForce,
                                           m_entity.Heading(),
                                           m_entity.Side()));
    }