void HHUlt() { anim.SetTrigger("ult"); FPSCamPerHero.FPSCamAct(E_ControlParam.Ultimate); Ray ray = Camera.main.ScreenPointToRay(screenCenterPoint); Vector3 ultStartPos = ray.origin + ray.direction * ultStartPosFactor; Quaternion ultStartRot = Quaternion.LookRotation(ray.direction); photonView.RPC("HHHUltActivate", RpcTarget.All, ultStartPos, ultStartRot); state = E_HeroHookState.Hooking; //정지 용도 nowUltAmount = 0f; StartCoroutine(ultActionDone()); }
void Reloading() { /* * if (isUltOn) return; * if (currBullet == maxBullet) return; */ reloading = true; //리로드 애니메이션 후 풀어주기. //리로드 애니메이션 해주기. FPSCamPerHero.FPSCamAct(E_ControlParam.Reload); StartCoroutine(ReloadingCheck()); currBullet = maxBullet; for (int i = 0; i < maxBullet; i++) { HSMagazineUICurrBulletImageParent.transform.GetChild(i).gameObject.SetActive(true); } currBulletUIText.text = currBullet.ToString(); }
void NormalAttack() { anim.SetTrigger("normalAttack"); FPSCamPerHero.FPSCamAct(E_ControlParam.NormalAttack); List <Hero> enemyHeroes = TeamInfo.GetInstance().EnemyHeroes; Ray ray = Camera.main.ScreenPointToRay(screenCenterPoint); Vector3 normalAttackVector = ray.direction * normalAttackLength; for (int i = 0; i < enemyHeroes.Count; i++) { Hero enemy = enemyHeroes[i]; Vector3 enemyPosition = enemy.CenterPos - ray.origin; Debug.DrawLine(ray.origin, ray.origin + normalAttackVector, Color.blue, 3f ); Debug.DrawLine(ray.origin, ray.origin + enemyPosition, Color.red, 3f ); float dot = Vector3.Dot(enemyPosition, normalAttackVector); if (dot < Mathf.Epsilon) { Debug.Log(enemy.photonView.ViewID + "HH NA enemy Behind, no attack"); continue; } float projectedDis = dot * normalAttackLengthDiv; Debug.DrawLine( ray.origin + Vector3.right * 0.1f, ray.origin + Vector3.right * 0.1f + ray.direction * projectedDis, Color.white, 3f ); Debug.DrawLine( ray.origin + Vector3.left * 0.1f, ray.origin + Vector3.left * 0.1f + ray.direction * normalAttackLength, Color.green, 3f ); if (projectedDis > normalAttackLength) { Debug.Log(enemy.photonView.ViewID + "HH NA enemy too far, no attack"); continue; } float projectedDisSqr = projectedDis * projectedDis; float orthogonalDisSqr = enemyPosition.sqrMagnitude - projectedDisSqr; Debug.DrawLine( ray.origin + ray.direction * projectedDis, ray.origin + ray.direction * projectedDis + (enemy.CenterPos - (ray.origin + ray.direction * projectedDis)) .normalized * Mathf.Sqrt(orthogonalDisSqr), Color.magenta, 3f ); Debug.DrawLine( ray.origin + ray.direction * projectedDis + ray.direction * 0.1f, ray.origin + ray.direction * projectedDis + ray.direction * 0.1f + (enemy.CenterPos + ray.direction * 0.1f - (ray.origin + ray.direction * projectedDis + ray.direction * 0.1f)) .normalized * Mathf.Sqrt(correctionRangeSqr), Color.green, 3f ); if (orthogonalDisSqr > correctionRangeSqr) { Debug.Log(enemy.photonView.ViewID + "HH NA enemy orthogonalDis too far, no attack"); continue; } enemy.photonView.RPC("GetDamaged", Photon.Pun.RpcTarget.All, normalAttackDamage, photonView.ViewID); } }
void NormalAttack() { currBullet--; for (int i = 0; i < maxBullet - currBullet; i++) { HSMagazineUICurrBulletImageParent.transform.GetChild(i).gameObject.SetActive(false); } currBulletUIText.text = currBullet.ToString(); photonView.RPC("normalMuzzleFlashPlay", RpcTarget.Others); FPSCamPerHero.FPSCamAct(E_ControlParam.NormalAttack); // 나자신의 시각효과만 담당. // normalMuzzleFlash.Play(); //fps 카메라라서 다른 곳의 파티클을 뿜어줘야함. anim.SetTrigger("shot"); Camera camera = Camera.main; Ray screenCenterRay = camera.ScreenPointToRay(screenCenterPoint); RaycastHit hitInfo; bool rayMapHit = false; float rayHitDisSqr = 0f; Vector3 hitCorrectionEnemyPos = Vector3.zero; #region 일반 공격 직접 레이 if (Physics.Raycast(screenCenterRay, out hitInfo, maxShotLength, TeamInfo.GetInstance().MapAndEnemyMaskedLayer)) { Debug.DrawLine(screenCenterRay.origin, screenCenterRay.direction * maxShotLength + screenCenterRay.origin, Color.blue, 1f); Debug.DrawRay(screenCenterRay.origin, screenCenterRay.direction, Color.magenta, 1f); Constants.DebugLayerMask(TeamInfo.GetInstance().MapAndEnemyMaskedLayer); GameObject hit = hitInfo.collider.gameObject; //레이캐스트 쏴서 뭐 맞았음. 벽이나, 적팀이나 이런 것을 검출. Vector3 hitPos = hitInfo.point; if (TeamInfo.GetInstance().IsThisLayerEnemy(hit.layer)) { Debug.Log("솔져 직접 레이 쏴서 적이 맞았음." + hitInfo + "레이 당첨 위치 = " + hitPos); photonView.RPC("normalHitParticle", RpcTarget.All, hitPos); //맞는 효과. Hero hitEnemyHero = hit.GetComponent <Hero>(); if (hitEnemyHero == null) { Debug.Log("HS-NormalAttack 히어로 컴포넌트가 없음"); return; } float damage = normalFireDamage; if (hitEnemyHero.IsHeadShot(hitPos)) { Debug.Log("HS-NormalAttack 헤드샷."); damage *= 2f; } hitEnemyHero.photonView.RPC("GetDamaged", RpcTarget.All, damage, photonView.ViewID); return; } if (hit.layer.Equals(Constants.mapLayerMask)) { rayMapHit = true; rayHitDisSqr = (hitPos - screenCenterRay.origin).sqrMagnitude; hitCorrectionEnemyPos = hitPos; } else { //맵에 맞은것도 아니고 적에 맞은 것도 아니고. 있을 수 없는 일임. return; } } #endregion #region 일반 공격 보정 (직접 레이에서 맵에 피격된 경우) Debug.Log("솔져 노멀어택이 맵에 피격, 보정 연산 진입."); Vector3 shotVector = screenCenterRay.direction * maxShotLength; Hero hitEnemy = null; float minHitLength = 0f; List <Hero> enemyHeroes = TeamInfo.GetInstance().EnemyHeroes; for (int i = 0; i < enemyHeroes.Count; i++) { Vector3 enemyPosition = enemyHeroes[i].CenterPos - screenCenterRay.origin; Debug.Log(enemyHeroes[i].photonView.ViewID + "의 센터 포스, " + enemyHeroes[i].CenterPos + "샷 원점에서 부터 포지션" + enemyPosition); Debug.DrawLine(screenCenterRay.origin, screenCenterRay.origin + enemyPosition, Color.red, 4f); float enemyScreenCenterDot = Vector3.Dot(enemyPosition, shotVector); if (enemyScreenCenterDot < Mathf.Epsilon) //벡터가 마이너스 , 뒤에 있음 { Debug.Log("뒤에 있으므로 보정 연산제외"); continue; } float projectedEnemyDis = enemyScreenCenterDot * maxShotLengthDiv; //카메라에서 적 까지의 샷벡터에 투영된 길이. if (projectedEnemyDis > correctionMaxLength) { //보점 최대 길이 보다 못하면 연산 제외. Debug.Log("보정 최대 길이에 도달하지 못하므로 보정연산제외. 샷벡터 투영길이 = " + projectedEnemyDis + "직선 보정 최대 길이 = " + correctionMaxLength); continue; } float projectedEnemyDisSqr = projectedEnemyDis * projectedEnemyDis; if (rayMapHit && rayHitDisSqr < projectedEnemyDisSqr) //처음 레이를 쏜게 벽이었는데. 그 벽 까지의 거리 보다도 먼 적이니까. //연산의 대상이 아님. { Debug.Log("앞에 벽이 있으므로 연산 제외. 샷벡터 투영길이 제곱 = " + projectedEnemyDisSqr + "직접레이가 벽에 맞았던 길이 제곱 = " + rayHitDisSqr); continue; } Debug.DrawLine(screenCenterRay.origin, screenCenterRay.origin + screenCenterRay.direction * projectedEnemyDis, Color.white, 4f); float farFromShotVectorSqr = enemyPosition.sqrMagnitude - projectedEnemyDisSqr;//샷벡터 투영 점에서 적까지의 수직 거리. Debug.DrawLine(screenCenterRay.origin + screenCenterRay.direction * projectedEnemyDis , (screenCenterRay.origin + screenCenterRay.direction * projectedEnemyDis) + (enemyHeroes[i].CenterPos - (screenCenterRay.origin + screenCenterRay.direction * projectedEnemyDis)).normalized * Mathf.Sqrt(farFromShotVectorSqr) , Color.magenta, 4f); Debug.DrawLine( screenCenterRay.origin + screenCenterRay.direction * projectedEnemyDis , (screenCenterRay.origin + screenCenterRay.direction * projectedEnemyDis) + (enemyHeroes[i].CenterPos - (screenCenterRay.origin + screenCenterRay.direction * projectedEnemyDis)).normalized * correctionRange , Color.green, 4f); if (farFromShotVectorSqr > correctionRangeSqr) //보정 범위 밖 { Debug.Log("보정 길이 벗어남으로 인해 보정 연산 제외. 보정에 쓰인 적 위치 길이 제곱 = " + farFromShotVectorSqr + "최대 보정 넓이 반지름 제곱 = " + correctionRangeSqr); continue; } //보정으로 히트 된 적임. //벽 등에 가려졌는지 레이를 한번 더쏴야하나...???? if (Physics.Raycast(screenCenterRay.origin, enemyPosition, enemyPosition.magnitude, 1 << Constants.mapLayerMask)) { Debug.Log(enemyHeroes[i].photonView.ViewID + "가 솔져의 보정 노멀 공격 판정 받았으나 중간에 벽이 있어서 취소."); continue; } Debug.Log(enemyHeroes[i].photonView.ViewID + "가 보정으로 인해 솔져의 노멀 공격 어택으로 판정이 일단 됨."); //적에 피격된 경우. Hero hitHero = enemyHeroes[i]; if (hitEnemy == null) { hitEnemy = hitHero; minHitLength = enemyPosition.sqrMagnitude; hitCorrectionEnemyPos = hitHero.CenterPos; } else if (minHitLength > enemyPosition.sqrMagnitude) { hitEnemy = hitHero; minHitLength = enemyPosition.sqrMagnitude; hitCorrectionEnemyPos = hitHero.CenterPos; } } photonView.RPC("normalHitParticle", RpcTarget.All, hitCorrectionEnemyPos); //벽에 맞았든 어쨌든 결국 이 포인트가 최종적으로 맞은 포인트임. if (hitEnemy == null) { //보정에서도 피격된 놈이 없음. return; } hitEnemy.photonView.RPC("GetDamaged", RpcTarget.All, normalFireDamage, photonView.ViewID); #endregion }