Example #1
0
    // can you move from one map node to another
    bool canMove(MapNodeBS start, MapNodeBS destination)
    {
        bool    result   = false;
        Color   color    = Color.red;
        Vector3 startPos = mapNodeToVector(start);
        Vector3 destPos  = mapNodeToVector(destination);
        float   dist     = Vector3.Distance(startPos, destPos);

        if (MaxMapNodeDist > dist)
        {
            RaycastHit2D hitInfo = Physics2D.Raycast(startPos, destPos - startPos, dist, -1, 5f);

            // is there a collider in the way with hieght at least 5 (walls)
            if (hitInfo.collider == null)
            {
                //color = Color.green;
                //Debug.DrawLine(mapNodeToVector(start), mapNodeToVector(destination), color, 2000f);
                result = true;
            }
            else
            {
                //Debug.DrawLine(mapNodeToVector(start), mapNodeToVector(destination), color, 2000f);
            }
        }

        return(result);
    }
Example #2
0
    // returns the closest map node to the loc that is visible (not through a wall or person)
    public MapNodeBS VectorToMapNode(Vector3 loc)
    {
        MapNodeBS closestNode = null;
        float     closestDist = Mathf.Infinity;

        foreach (MapNodeBS node in mapNodes)
        {
            // can we see the node?
            if (canSeeIgnoreCharacters(loc, node.transform.position))
            {
                // is it the closest?
                float dist = Vector3.Distance(loc, node.transform.position);
                if (dist <= closestDist)
                {
                    closestDist = dist;
                    closestNode = node;
                }
            }
        }

        return(closestNode);
    }
Example #3
0
    // Update is called once per frame
    void Update()
    {
        Vector2 newPos     = transform.position; // default
        bool    is_moving  = false;
        bool    canSeeTarg = false;

        // NOW: lose % of intensity every X seconds
        float TimeMult = 1f;

        // The ratio of delta time into X seconds
        if (Time.deltaTime < forgetNoiseRate)
        {
            TimeMult = (forgetNoiseRate - Time.deltaTime) / forgetNoiseRate;
        }

        // drop intensity by a certain % each frame, drops quickly, stays nonzero for a long time
        if (targetIntensity > 0f)
        {
            targetIntensity = targetIntensity * TimeMult;
        }
        // lose intensity if we reach destination
        if (Vector2.Distance(transform.position, softTarget) < minForgetDistance)
        {
            targetIntensity = 0;
        }

        // only do logic every delayTime seconds
        if (Time.time > nextSyncTime)
        {
            nextSyncTime = Time.time + delayTime;

            // control which target mode we are in
            if (hardTarget != null)
            {
                targetmode = TargetMode.HardTarget;
                canSeeTarg = GAMESTATE.canSee(gameObject, hardTarget);

                // if the hard target gets too far away, switch to soft target
                float dist = Vector2.Distance(hardTarget.transform.position, transform.position);

                // if we cant see the hard target, set soft target and create a path
                if (canSeeTarg == false)
                {
                    targetmode            = TargetMode.FollowPath;
                    softTarget            = hardTarget.transform.position;
                    pathDestinationTarget = softTarget;
                    hardTarget            = null;
                    if (path == null)
                    {
                        //print("Find path1 at " + Time.time);
                        path = GAMESTATE.findPath(transform.position, pathDestinationTarget);
                        if (null == path)
                        {
                            targetmode = TargetMode.SoftTarget;
                        }
                        else
                        {
                            pathTarget            = path[0];
                            pathDestinationTarget = softTarget;
                        }
                    }
                }
                // if hard target moves out of range, go back to soft
                else if (dist > hardDetectRange)
                {
                    targetmode      = TargetMode.SoftTarget;
                    softTarget      = hardTarget.transform.position; // set the soft target to the old pos
                    targetIntensity = maxIntensity;
                    hardTarget      = null;
                    path            = null;
                }
            }
            // is the intensity great enough to follow? if so, set soft target
            else if (targetIntensity > minIntensity)
            {
                // there already is a soft target
                canSeeTarg = GAMESTATE.canSeeIgnoreCharacters(transform.position, softTarget);

                if (canSeeTarg == false)
                {
                    // follow path if we cant see where the sound came from
                    // if we dont yet have a path, get one, or if this is a new soft target, generate a new path
                    targetmode = TargetMode.FollowPath;

                    if (path == null || (pathDestinationTarget != softTarget))
                    {
                        path = GAMESTATE.findPath(transform.position, pathDestinationTarget);
                        // there is no path
                        if (null == path)
                        {
                            targetmode = TargetMode.SoftTarget;
                        }
                        else
                        {
                            pathTarget            = path[0];
                            pathDestinationTarget = softTarget;
                        }
                    }
                }
                else
                {
                    // otherwise just go towards it
                    targetmode = TargetMode.SoftTarget;
                    path       = null;
                }
            }
            else
            {
                targetmode      = TargetMode.NoTarget;
                softTarget      = transform.position;
                targetIntensity = 0;
                path            = null;
            }
            //print(Vector3.Magnitude(character.rigidbod.velocity) + " " + Time.time);
        }


        // handle behavior based off of the target mode
        switch (targetmode)
        {
        case (TargetMode.NoTarget):
        {
            character.State = Character_BS.AnimState.Idle;
            break;
        }

        case (TargetMode.SoftTarget):
        {
            is_moving = true;
            character.SetFacing(softTarget);         // face the soft target VECTOR
            character.State = Character_BS.AnimState.Walk;
            Vector2 dir = new Vector2(softTarget.x, softTarget.y);
            dir -= new Vector2(transform.position.x, transform.position.y);
            dir.Normalize();
            character.rigidbod.velocity = dir * character.walkSpeed;


            break;
        }

        case (TargetMode.HardTarget):
        {
            is_moving = true;
            character.SetFacing(hardTarget);         // face the target game object
            character.State = Character_BS.AnimState.Run;
            Vector2 dir  = hardTarget.transform.position - transform.position;
            float   dist = dir.magnitude;
            dir.Normalize();
            character.rigidbod.velocity = dir * character.runSpeed;

            if (dist < meleeDist)
            {
                // makes melee attack
                if (character.meleeWeapon.canAttack(is_moving) == true)
                {
                    GAMESTATE.MakeAttack(gameObject, dir, character.meleeWeapon);
                }
            }

            break;
        }

        case (TargetMode.FollowPath):
        {
            // If we can see the next pathTarget, also just choose it (instead of walking too far the wrong way)
            float dist = Vector2.Distance(transform.position, pathTarget.transform.position);
            int   i    = path.IndexOf(pathTarget);
            is_moving = true;
            if (i + 1 < path.Count)
            {
                bool skipNode = GAMESTATE.canSeeIgnoreCharacters(transform.position, path[i + 1].transform.position);
                if (dist <= minPathNodeDist || skipNode == true)
                {
                    // get the next path target
                    pathTarget = path[i + 1];
                    //print("going to next node " + Time.time);
                }
            }
            // if too close to last path
            else if (dist <= minPathNodeDist)
            {
                targetIntensity = 0;
                is_moving       = false;
            }

            if (is_moving == true)
            {
                Vector2 pathvector = pathTarget.transform.position;
                character.SetFacing(pathvector);         // face the soft target VECTOR
                character.State = Character_BS.AnimState.Walk;
                Vector2 dir = pathvector;
                dir -= new Vector2(transform.position.x, transform.position.y);
                dir.Normalize();
                character.rigidbod.velocity = Vector2.Lerp(character.rigidbod.velocity, dir * character.walkSpeed, 0.5f);
            }

            break;
        }

        default:
        {
            break;
        }
        }
    }
Example #4
0
    // returns the vector in gamespace that corresponds to this map node
    public Vector3 mapNodeToVector(MapNodeBS node)
    {
        Vector3 result = new Vector3(node.transform.position.x, node.transform.position.y, 10);

        return(result);
    }
Example #5
0
    // finds path between two locations, in squares
    public List <MapNodeBS> findPath(Vector3 start, Vector3 end)
    {
        MapNodeBS startNode = VectorToMapNode(start);
        MapNodeBS endNode   = VectorToMapNode(end);

        Queue <List <MapNodeBS> > pathsQueue = new Queue <List <MapNodeBS> >(); // queue of paths to process
        List <MapNodeBS>          path       = new List <MapNodeBS>();

        path.Add(startNode);
        pathsQueue.Enqueue(path);

        List <List <MapNodeBS> > successPaths = new List <List <MapNodeBS> >();
        int numPaths = 0;
        int i        = 0;

        // iteratively go through all paths
        while ((i < maxIter) && (numPaths < maxPaths))
        {
            i++;
            if (pathsQueue.Count > 0)
            {
                path = pathsQueue.Dequeue();
            }
            else
            {
                // just break out of while and let it continue processing what we have
                break;
            }
            MapNodeBS nd = path[path.Count - 1];

            // does the path contain the destination?
            if (nd == endNode)
            {
                successPaths.Add(path);
                numPaths += 1;
            }
            if (nd != null && nd.adjacentNodes != null)
            {
                foreach (MapNodeBS adj in nd.adjacentNodes)
                {
                    // is this node already in our path? if so, dont use it
                    if (path.Contains(adj) == false)
                    {
                        List <MapNodeBS> newPath = new List <MapNodeBS>();
                        foreach (MapNodeBS mp in path)
                        {
                            newPath.Add(mp);
                        }
                        newPath.Add(adj);
                        pathsQueue.Enqueue(newPath); // enqueue new path
                    }
                }
            }
        }

        // how many good paths did we get? look through and return one
        if (numPaths > 0)
        {
            float            totalLength = 0;
            float            minLength   = Mathf.Infinity;
            List <MapNodeBS> bestPath    = null;
            MapNodeBS        prevP       = null;
            //Dictionary<List<MapNodeBS>, float> pathLengths = new Dictionary<List<MapNodeBS>, float>();
            foreach (List <MapNodeBS> l in successPaths)
            {
                totalLength = 0;
                prevP       = null;
                foreach (MapNodeBS p in l)
                {
                    if (prevP != null)
                    {
                        //Debug.DrawLine(mapNodeToVector(p), mapNodeToVector(prevP), Color.blue, 2000f);
                        totalLength += Vector3.Distance(mapNodeToVector(p), mapNodeToVector(prevP));
                    }
                    prevP = p;
                }
                if (totalLength < minLength)
                {
                    bestPath  = l;
                    minLength = totalLength;
                }
                //print(totalLength);
                //pathLengths[l] = totalLength;
            }

            // TODO: Instead select randomly from a few good paths
            // DRAW BEST PATH
            prevP = null;
            foreach (MapNodeBS p in bestPath)
            {
                if (prevP != null)
                {
                    Debug.DrawLine(mapNodeToVector(p), mapNodeToVector(prevP), Color.yellow, 10f);
                    totalLength += Vector3.Distance(mapNodeToVector(p), mapNodeToVector(prevP));
                }
                prevP = p;
            }

            return(bestPath);
        }
        else
        {
            return(null);
        }
    }
Example #6
0
 public void addAdjacentNode(MapNodeBS node)
 {
     adjacentNodes.Add(node);
 }