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 } }
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(); }