public void AttackTarget(Collider2D attackTarget, Animator animator)
    {
        pathfindingGridSetupScript = GameObject.Find("PathfindingGridSetup").GetComponent <PathfindingGridSetup>();
        cellSize = pathfindingGridSetupScript.pathfindingGrid.GetCellSize();

        daAnimator = animator;
        Entity        entity        = convertedEntityHolder.GetEntity();
        EntityManager entityManager = convertedEntityHolder.GetEntityManager();


        PathFollowComp pathFollowComp = entityManager.GetComponentData <PathFollowComp>(entity);
        DynamicBuffer <PathPositionBuffer> pathPositionBuffer = entityManager.GetBuffer <PathPositionBuffer>(entity);

        if (DidColliderChange(attackTarget))
        {
            lastAttackTarget            = attackTarget;
            attackTargetCurrentPosition = attackTarget.transform.position;
            playerGOScript = attackTarget.GetComponent <PlayerGO>();
            // Add pathfinding params
            pathfindingGridSetupScript.pathfindingGrid.GetXY(attackTargetCurrentPosition + new Vector3(1, 1) * cellSize * 0.5f, out int endX, out int endY);
            ValidateGridPosition(ref endX, ref endY);
            pathfindingGridSetupScript.pathfindingGrid.GetXY(transform.position + new Vector3(1, 1) * cellSize * 0.5f, out int startX, out int startY);
            ValidateGridPosition(ref startX, ref startY);

            entityManager.AddComponentData(entity, new PathfindingParams
            {
                startPosition = new int2(startX, startY),
                endPosition   = new int2(endX, endY)
            });
            return;
        }

        if (currentAttackCooldown > 0)
        {
            currentAttackCooldown -= Time.deltaTime;
        }
        if (attackTarget.gameObject.activeSelf)
        {
            //attackTargetCurrentPosition = attackTarget.transform.position;

            // if target hasn't moved 0.25f length away from last pathfinding target position then run
            //      attack code, else, set new pathfinding params
            if (Vector3.Distance(attackTarget.transform.position, attackTargetCurrentPosition) < 1f)
            {
                // if player is within attack range then attack, else move towards target
                // later on need to factor in size of target in this check
                if (Vector3.Distance(transform.position, attackTarget.transform.position) < hostileAttackRange)
                {
                    if (currentAttackCooldown <= 0)
                    {
                        //animator.SetBool("isWalking", false);
                        currentAttackCooldown = hostileAttackCooldown;
                        // attack
                        StartCoroutine(HostileAttack());
                    }
                }
                else // move towards target
                {
                    if (pathFollowComp.pathIndex >= 0)
                    {
                        int2 pathPosition = pathPositionBuffer[pathFollowComp.pathIndex].position;

                        float3 targetPosition = new float3(pathPosition.x, pathPosition.y, 0);
                        float3 moveDir        = math.normalizesafe(targetPosition - (float3)transform.position);

                        animator.SetFloat("moveX", moveDir.x);
                        animator.SetFloat("moveY", moveDir.y);

                        transform.position += (Vector3)(moveDir * hostileSpeed * Time.deltaTime);

                        if (math.distance(transform.position, targetPosition) < 0.1f)
                        {
                            // next waypoint
                            pathFollowComp.pathIndex--;
                            entityManager.SetComponentData(entity, pathFollowComp);
                        }
                    }
                    else
                    {
                        Vector3 moveDir = (attackTarget.transform.position - transform.position).normalized;
                        transform.position += moveDir * hostileSpeed * Time.deltaTime;
                    }
                }
            }
            else
            {
                attackTargetCurrentPosition = attackTarget.transform.position;
                // Add pathfinding params
                pathfindingGridSetupScript.pathfindingGrid.GetXY(attackTargetCurrentPosition + new Vector3(1, 1) * cellSize * 0.5f, out int endX, out int endY);
                ValidateGridPosition(ref endX, ref endY);
                pathfindingGridSetupScript.pathfindingGrid.GetXY(transform.position + new Vector3(1, 1) * cellSize * 0.5f, out int startX, out int startY);
                ValidateGridPosition(ref startX, ref startY);

                entityManager.AddComponentData(entity, new PathfindingParams
                {
                    startPosition = new int2(startX, startY),
                    endPosition   = new int2(endX, endY)
                });
            }
        }
        else // if target was destroyed
        {
            // for now do nothing, later find new target
        }
    }
Exemplo n.º 2
0
    private void Update()
    {
        if (currentAttackCooldown > 0)
        {
            currentAttackCooldown -= Time.deltaTime;
        }
        if (basicSpellCurrentCooldown > 0)
        {
            basicSpellCurrentCooldown  -= Time.deltaTime;
            spellOneCDVisual.fillAmount = basicSpellCurrentCooldown / basicSpellCooldown;
        }

        //// goes up 0.5 per second
        //if (playerHealth < 100)
        //{
        //    playerHealth = Mathf.Clamp(playerHealth + 0.5f *Time.deltaTime, 0, 100);
        //}
        // goes up one per second
        if (playerEnergy < 100)
        {
            playerEnergy = Mathf.Clamp(playerEnergy + Time.deltaTime, 0, 100);
        }


        playerHealthBar.fillAmount = playerHealth / maxPlayerHealth;
        playerEnergyBar.fillAmount = playerEnergy / maxPlayerEnergy;



        Entity        entity        = convertedEntityHolder.GetEntity();
        EntityManager entityManager = convertedEntityHolder.GetEntityManager();


        PathFollowComp pathFollowComp = entityManager.GetComponentData <PathFollowComp>(entity);
        DynamicBuffer <PathPositionBuffer> pathPositionBuffer = entityManager.GetBuffer <PathPositionBuffer>(entity);

        switch (playerState)
        {
        case PlayerState.Idle:

            break;

        case PlayerState.Walking:     // if still have a path then make GO walk, else change state to idle
            if (pathFollowComp.pathIndex >= 0)
            {
                int2 pathPosition = pathPositionBuffer[pathFollowComp.pathIndex].position;

                float3 targetPosition = new float3(pathPosition.x, pathPosition.y, 0);
                float3 moveDir        = math.normalizesafe(targetPosition - (float3)transform.position);
                float  moveSpeed      = 3f;

                animator.SetFloat("moveX", moveDir.x);
                animator.SetFloat("moveY", moveDir.y);

                transform.position += (Vector3)(moveDir * moveSpeed * Time.deltaTime);

                if (math.distance(transform.position, targetPosition) < 0.1f)
                {
                    // next waypoint
                    pathFollowComp.pathIndex--;
                    entityManager.SetComponentData(entity, pathFollowComp);
                }
            }
            else
            {
                playerState = PlayerState.Idle;
                animator.SetBool("isWalking", false);
            }
            break;

        case PlayerState.Attacking:
            // if target has not been destroyed yet, run attack code
            if (attackTarget.gameObject.activeSelf)
            {
                // if target hasn't moved a cell length away from last pathfinding target position then run
                //      attack code, else, set new pathfinding params
                if (Vector3.Distance(attackTarget.transform.position, attackTargetCurrentPosition) < 1f)
                {
                    // if player is within attack range then attack, else move towards target
                    // later on need to factor in size of target in this check
                    if (Vector3.Distance(transform.position, attackTarget.transform.position) < playerAttackRange)
                    {
                        if (currentAttackCooldown <= 0)
                        {
                            Vector3 targetDirection = (attackTarget.transform.position - transform.position).normalized;
                            animator.SetBool("isWalking", false);
                            animator.SetFloat("moveX", targetDirection.x);
                            animator.SetFloat("moveY", targetDirection.y);
                            currentAttackCooldown = playerAttackCooldown;
                            // attack
                            StartCoroutine(PlayerAttack());
                        }
                    }
                    else     // move towards target
                    {
                        if (pathFollowComp.pathIndex >= 0)
                        {
                            int2 pathPosition = pathPositionBuffer[pathFollowComp.pathIndex].position;

                            float3 targetPosition = new float3(pathPosition.x, pathPosition.y, 0);
                            float3 moveDir        = math.normalizesafe(targetPosition - (float3)transform.position);
                            float  moveSpeed      = 3f;

                            animator.SetFloat("moveX", moveDir.x);
                            animator.SetFloat("moveY", moveDir.y);

                            transform.position += (Vector3)(moveDir * moveSpeed * Time.deltaTime);

                            if (math.distance(transform.position, targetPosition) < 0.1f)
                            {
                                // next waypoint
                                pathFollowComp.pathIndex--;
                                entityManager.SetComponentData(entity, pathFollowComp);
                            }
                        }
                        else
                        {
                        }
                    }
                }
                else
                {
                    attackTargetCurrentPosition = attackTarget.transform.position;
                    // Add pathfinding params
                    pathfindingGridSetupScript.pathfindingGrid.GetXY(attackTargetCurrentPosition + new Vector3(1, 1) * cellSize * 0.5f, out int endX, out int endY);
                    ValidateGridPosition(ref endX, ref endY);
                    pathfindingGridSetupScript.pathfindingGrid.GetXY(transform.position + new Vector3(1, 1) * cellSize * 0.5f, out int startX, out int startY);
                    ValidateGridPosition(ref startX, ref startY);

                    entityManager.AddComponentData(entity, new PathfindingParams
                    {
                        startPosition = new int2(startX, startY),
                        endPosition   = new int2(endX, endY)
                    });
                }
            }
            else     // if target was destroyed
            {
                // for now do nothing, later find new target
                Collider2D nearbyEnemyCollider = Physics2D.OverlapCircle(transform.position, 5f, hostileMask);
                if (nearbyEnemyCollider != null)
                {
                    attackTarget = nearbyEnemyCollider;
                    attackTargetCurrentPosition = attackTarget.transform.position;

                    // all of this to add initial pathfinding params
                    pathfindingGridSetupScript.pathfindingGrid.GetXY(attackTargetCurrentPosition + new Vector3(1, 1) * cellSize * 0.5f, out int endX, out int endY);
                    ValidateGridPosition(ref endX, ref endY);
                    pathfindingGridSetupScript.pathfindingGrid.GetXY(transform.position + new Vector3(1, 1) * cellSize * 0.5f, out int startX, out int startY);
                    ValidateGridPosition(ref startX, ref startY);
                    // Add pathfinding params
                    entityManager.AddComponentData(entity, new PathfindingParams
                    {
                        startPosition = new int2(startX, startY),
                        endPosition   = new int2(endX, endY)
                    });
                }
            }


            break;

        case PlayerState.Dead:

            break;
        }


        if (Input.GetMouseButtonDown(1))
        {
            Vector3      mousePosition = RAHUtility.GetMouseWorldPosition(true);
            RaycastHit2D rayCastHit    = Physics2D.Raycast(mousePosition, Vector2.zero);

            // if clicked collider then attack, if didn't click anything then walk. Will add more options later
            if (rayCastHit)
            {
                playerState  = PlayerState.Attacking;
                attackTarget = rayCastHit.collider;
                attackTargetCurrentPosition = attackTarget.transform.position;

                // all of this to add initial pathfinding params
                pathfindingGridSetupScript.pathfindingGrid.GetXY(attackTargetCurrentPosition + new Vector3(1, 1) * cellSize * 0.5f, out int endX, out int endY);
                ValidateGridPosition(ref endX, ref endY);
                pathfindingGridSetupScript.pathfindingGrid.GetXY(transform.position + new Vector3(1, 1) * cellSize * 0.5f, out int startX, out int startY);
                ValidateGridPosition(ref startX, ref startY);
                // Add pathfinding params
                entityManager.AddComponentData(entity, new PathfindingParams
                {
                    startPosition = new int2(startX, startY),
                    endPosition   = new int2(endX, endY)
                });
            }
            else
            {
                pathfindingGridSetupScript.pathfindingGrid.GetXY(mousePosition + new Vector3(1, 1) * cellSize * 0.5f, out int endX, out int endY);
                ValidateGridPosition(ref endX, ref endY);


                pathfindingGridSetupScript.pathfindingGrid.GetXY(transform.position + new Vector3(1, 1) * cellSize * 0.5f, out int startX, out int startY);
                ValidateGridPosition(ref startX, ref startY);

                // Add pathfinding params
                entityManager.AddComponentData(entity, new PathfindingParams
                {
                    startPosition = new int2(startX, startY),
                    endPosition   = new int2(endX, endY)
                });

                playerState = PlayerState.Walking;
                animator.SetBool("isWalking", true);
            }
        }

        if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            if (basicSpellCurrentCooldown <= 0 &&
                playerEnergy >= spellOneEnergyCost)
            {
                StartCoroutine(CastBasicSpell(RAHUtility.GetMouseWorldPosition(true)));
                basicSpellCurrentCooldown = basicSpellCooldown;
            }
        }
    }
        public void Execute()
        {
            for (int i = 0; i < pathNodeArray.Length; i++)
            {
                PathNode pathNode = pathNodeArray[i];
                pathNode.hCost             = CalculateHCost(new int2(pathNode.x, pathNode.y), endPosition);
                pathNode.cameFromNodeIndex = -1;
            }

            NativeArray <int2> neighborOffsetArray = new NativeArray <int2>(8, Allocator.Temp);

            neighborOffsetArray[0] = new int2(-1, 0);  // left
            neighborOffsetArray[1] = new int2(1, 0);   //right
            neighborOffsetArray[2] = new int2(0, 1);   // up
            neighborOffsetArray[3] = new int2(0, -1);  //down
            neighborOffsetArray[4] = new int2(-1, 1);  // left up
            neighborOffsetArray[5] = new int2(-1, -1); // left down
            neighborOffsetArray[6] = new int2(1, 1);   // right up
            neighborOffsetArray[7] = new int2(1, -1);  // right down

            NativeArray <bool> areStraightNeighborsWalkableArray = new NativeArray <bool>(4, Allocator.Temp);



            int endNodeIndex = CalculateIndex(endPosition.x, endPosition.y, gridSize.x);

            PathNode startNode = pathNodeArray[CalculateIndex(startPosition.x, startPosition.y, gridSize.x)];

            startNode.gCost = 0;
            startNode.CalculateFCost();
            pathNodeArray[startNode.index] = startNode;


            NativeList <int> openList = new NativeList <int>(Allocator.Temp);
            //NativeList<int> closedList = new NativeList<int>(Allocator.Temp);
            // 4 instances of closed list including this one ^
            NativeArray <bool> checkedArray = new NativeArray <bool>(gridSize.x * gridSize.y, Allocator.Temp);

            openList.Add(startNode.index);

            while (openList.Length > 0)
            {
                int      currentNodeIndex = GetLowestFCostNodeIndex(openList, pathNodeArray);
                PathNode currentNode      = pathNodeArray[currentNodeIndex];

                if (currentNode.index == endNodeIndex)
                {
                    // YIPEE we reached our destination
                    break;
                }

                // remove current node from open list
                for (int i = 0; i < openList.Length; i++)
                {
                    if (openList[i] == currentNodeIndex)
                    {
                        openList.RemoveAtSwapBack(i);
                        break;
                    }
                }

                //closedList.Add(currentNodeIndex);
                checkedArray[currentNodeIndex] = true;

                for (int i = 0; i < neighborOffsetArray.Length; i++)
                {
                    int2 neighborOffset   = neighborOffsetArray[i];
                    int2 neighborPosition = new int2(currentNode.x + neighborOffset.x, currentNode.y + neighborOffset.y);

                    // if neighbor is a diagonal, check to make sure appropriate straight cells are walkable
                    if (i >= 4)
                    {
                        if (neighborOffset.x == -1)
                        {
                            if (areStraightNeighborsWalkableArray[0] == false)
                            {
                                continue;
                            }
                        }
                        else
                        {
                            if (areStraightNeighborsWalkableArray[1] == false)
                            {
                                continue;
                            }
                        }
                        if (neighborOffset.y == -1)
                        {
                            if (areStraightNeighborsWalkableArray[3] == false)
                            {
                                continue;
                            }
                        }
                        else
                        {
                            if (areStraightNeighborsWalkableArray[2] == false)
                            {
                                continue;
                            }
                        }
                    }


                    if (IsPositionInsideGrid(neighborPosition, gridSize) == false)
                    {
                        // neighbor not valid position
                        continue;
                    }

                    int neighborNodeIndex = CalculateIndex(neighborPosition.x, neighborPosition.y, gridSize.x);

                    //if (closedList.Contains(neighborNodeIndex))
                    //{
                    //    // already searched this node
                    //    continue;
                    //}

                    if (checkedArray[neighborNodeIndex] == true)
                    {
                        // already searched this node
                        continue;
                    }

                    PathNode neighborNode = pathNodeArray[neighborNodeIndex];
                    if (neighborNode.isWalkable == false)
                    {
                        // not walkable
                        if (i < 4)
                        {
                            areStraightNeighborsWalkableArray[i] = false;
                        }

                        continue;
                    }
                    else
                    {
                        // cache the fact that this straight neighbor is walkable
                        if (i < 4)
                        {
                            areStraightNeighborsWalkableArray[i] = true;
                        }
                    }

                    int2 currentNodePosition = new int2(currentNode.x, currentNode.y);

                    // tentativeG is current g plus distance cost to get to neighbor node
                    int tentativeGCost = currentNode.gCost + CalculateHCost(currentNodePosition, neighborPosition);
                    if (tentativeGCost < neighborNode.gCost)
                    {
                        neighborNode.cameFromNodeIndex = currentNodeIndex;
                        neighborNode.gCost             = tentativeGCost;
                        neighborNode.CalculateFCost();
                        pathNodeArray[neighborNodeIndex] = neighborNode;

                        if (openList.Contains(neighborNode.index) == false)
                        {
                            openList.Add(neighborNode.index);
                        }
                    }
                }
            }

            pathPositionBufferFromEntity[entity].Clear();

            PathNode endNode = pathNodeArray[endNodeIndex];

            if (endNode.cameFromNodeIndex == -1)
            {
                // Did not find path
                Debug.Log("Failed to find path");
                pathFollowComponentDataFromEntity[entity] = new PathFollowComp {
                    pathIndex = -1
                };
            }
            else
            {
                // Found path! Set pathIndex to buffer length - 1 because we read path from end to start
                CalculatePathVoid(pathNodeArray, endNode, pathPositionBufferFromEntity[entity]);
                pathFollowComponentDataFromEntity[entity] = new PathFollowComp {
                    pathIndex = pathPositionBufferFromEntity[entity].Length - 1
                };
            }



            areStraightNeighborsWalkableArray.Dispose();
            neighborOffsetArray.Dispose();
            openList.Dispose();
            //closedList.Dispose();
            checkedArray.Dispose();
        }