IEnumerator PenetrateVision() { if (state != E_PenetrateState.Settle) { yield break; } if (TeamInfo.GetInstance().IsThisLayerEnemy(attachingHero.gameObject.layer)) { yield break; //적의 것이면 투시 안되게 하기. } float time = 0f; List <Hero> enemyHeroes = TeamInfo.GetInstance().EnemyHeroes; do { for (int i = 0; i < enemyHeroes.Count; i++) { if (enemyHeroes[i] == null) { continue; } if ((transform.position - enemyHeroes[i].CenterPos).sqrMagnitude < searchRangeSqr) //범위 내에 들어옴. { enemyHeroes[i].SetPenetrateVision(penetrateMaintainTime); } } time += penetrateMaintainTime; yield return(penetrateMaintainTimeWFS); } while (time <= amount); if (attachingHero.photonView.IsMine) { attachingHero.photonView.RPC("PenetrateVisionDeActivate", Photon.Pun.RpcTarget.All); } }
public void GameJudgeReceived(E_Team winTeam) { if (PhotonNetwork.IsMasterClient) { payload.StopPayload(); } if (judgeDone) { Debug.Log("이미 저지던이 켜져있으므로 기각"); return; } judgeDone = true; int winTeamLayer = Constants.GetLayerByE_Team(winTeam); int myLayer = TeamInfo.GetInstance().MyTeamLayer; if (winTeamLayer == myLayer) { //나 이겼음. StartCoroutine(GameEndShow(true)); } else { StartCoroutine(GameEndShow(false)); //나 쟜음. } }
IEnumerator StartingHealingProtocol() { activateTime = Time.time; Debug.Log("힐드론 액티베이트 시간 =" + activateTime); while (true) { List <Hero> sameSideHeroes = TeamInfo.GetInstance().MyTeamHeroes; for (int i = 0; i < sameSideHeroes.Count; i++) { if (SqrHealRange >= (sameSideHeroes[i].transform.position - transform.position).sqrMagnitude) //힐 범위에 아군이 있으면 { attachingHero.DroneHeal(sameSideHeroes[i], healAmount); } } if (activateTime + activeMaxTime < Time.time) { break; } yield return(ws); } Debug.Log("힐드론 액티베이트 종료 시간 =" + Time.time + "총 가동시간=" + (Time.time - activateTime)); attachingHero.photonView.RPC("DroneDisAppear", RpcTarget.All); }
IEnumerator Start() { TeamInfo.GetInstance().AddListenerOnCLCD(OnClientLefted); progressPosStart = progressStart.position.x; progressPosEnd = progressEnd.position.x; SetWholePath(); wayPointcloseEnoughSqr = wayPointcloseEnough * wayPointcloseEnough; distanceSqr = distance * distance; payLoadArrive += PayloadArrive; while (!TeamInfo.GetInstance().isTeamSettingDone) { yield return(new WaitForSeconds(1f)); } GetABHeroes(); if (TeamInfo.GetInstance().EnemyTeamLayers.Count != 1) { MyDebug.Log("Payload - 이 게임은 2 팀 대결이 아님."); } }
IEnumerator Start() { TeamInfo.GetInstance().AddListenerOnCLCD(OnClientLefted); progressPosStart = progressStart.position.x; progressPosEnd = progressEnd.position.x; /* * if (!PhotonNetwork.IsMasterClient) * yield break; */ SetWholePath(); wayPointcloseEnoughSqr = wayPointcloseEnough * wayPointcloseEnough; distanceSqr = distance * distance; payLoadArrive += PayloadArrive; cws = new WaitForSeconds(checkTime); while (!TeamInfo.GetInstance().isTeamSettingDone) { yield return(cws); } Debug.Log("팀 세팅 끝남 확인."); GetABHeroes(); if (TeamInfo.GetInstance().EnemyTeamLayer.Count != 1) { Debug.LogError("이 게임은 2 팀 대결이 아님."); } }
private void Awake() { if (_instance == null) { _instance = this; } }
public static RaycastHit GetFirstHitAsMapOrEnemy(Hero shooter, Ray ray, float shotLength) { RaycastHit[] hits = Physics.RaycastAll(ray, shotLength, TeamInfo.GetInstance().MapAndEnemyMaskedLayer); MyDebug.Log("ShotCtrl GetFirstHitAsMapOrEnemy: " + hits.Length + "개가 검출됨"); RaycastHit hit = new RaycastHit(); float minDis = Mathf.Infinity; for (int i = 0; i < hits.Length; i++) { MyDebug.Log("ShotCtrl GetFirstHitAsMapOrEnemy: " + hits[i].collider.name + "검사중"); if ( hits[i].distance < minDis && (hits[i].collider.gameObject.layer != Constants.mapLayerMask || ObstacleToShooter(hits[i], shooter)) ) { MyDebug.Log("ShotCtrl GetFirstHitAsMapOrEnemy: " + hits[i].collider.name + "검사 통과"); hit = hits[i]; minDis = hits[i].distance; } } MyDebug.Log("ShotCtrl GetFirstHitAsMapOrEnemy: 최종 선택된 가장 가까운 장애물 or 적 RaycastHit " + hit.collider.name); return(hit); }
void ShieldActivate(Vector3 pos) { GameObject shieldGO = Instantiate <GameObject>(hookShield); HHShield shield = shieldGO.GetComponent <HHShield>(); shield.SetTeam(LayerMask.LayerToName(gameObject.layer), !TeamInfo.GetInstance().IsThisLayerEnemy(gameObject.layer)); shield.Activate(pos); }
void Start() { TeamInfo.GetInstance().AddListenerOnCLCD(OnClientLefted); geScreenDissolveMat = new Material(gameEndScreen.material); gameEndScreen.material = geScreenDissolveMat; gameEndScreen.gameObject.SetActive(false); payload.AddListenerPayloadArrive(PayloadArrive); }
void Start() {/* * Vector2 myVector = new Vector2(Screen.width, Screen.height); * gameEndScreen.GetComponent<RectTransform>().sizeDelta = myVector; */ TeamInfo.GetInstance().AddListenerOnCLCD(OnClientLefted); geScreenDissolveMat = new Material(gameEndScreen.material); gameEndScreen.material = geScreenDissolveMat; gameEndScreen.gameObject.SetActive(false); payload.AddListenerPayloadArrive(PayloadArrive); }
void DoHook() { anim.SetTrigger("hook"); state = E_HeroHookState.Hooking; //자가 정지 시키기. Ray ray = Camera.main.ScreenPointToRay(screenCenterPoint); Vector3 hookDestPos = ray.origin + ray.direction * maxShotLength; RaycastHit hit; if (Physics.Raycast(ray, out hit, maxShotLength, TeamInfo.GetInstance().MapAndEnemyMaskedLayer)) { hookDestPos = hit.point; } hookOriginPos.transform.LookAt(hookDestPos); photonView.RPC("ActivateHook", RpcTarget.All, hookOriginPos.transform.rotation); }
void HitEnemy() { if (!attachingHero.photonView.IsMine) { return; } List <Hero> enemyHeroes = TeamInfo.GetInstance().EnemyHeroes; for (int i = 0; i < enemyHeroes.Count; i++) { Vector3 enemyPosition = enemyHeroes[i].CenterPos - transform.position; if (enemyPosition.sqrMagnitude < distanceSqr) { enemyHeroes[i].photonView.RPC("GetDamaged", Photon.Pun.RpcTarget.All, amount, attachingHero.photonView.ViewID); } } }
private void OnTriggerEnter(Collider other) { if (!attachingHero.photonView.IsMine) { return; } if (!( (other.gameObject.layer == Constants.mapLayerMask && !other.gameObject.CompareTag(LayerMask.LayerToName(attachingHero.gameObject.layer))) || TeamInfo.GetInstance().IsThisLayerEnemy(other.gameObject.layer))) { return; } Vector3 collCenter = coll.bounds.center; //콜라이더의 센터를 폭발 지점으로. attachingHero.photonView.RPC("BoomUltMissile", Photon.Pun.RpcTarget.All, attachedNumber, transform.position); //효과만. List <Hero> enemyHeroes = TeamInfo.GetInstance().EnemyHeroes; for (int i = 0; i < enemyHeroes.Count; i++) { Vector3 enemyPosition = enemyHeroes[i].CenterPos - collCenter; if (enemyPosition.sqrMagnitude < explosionRangeSqr) { float dis = enemyPosition.magnitude; if (ShotCtrl.MapIntersectedCheck(attachingHero, collCenter, enemyHeroes[i].CenterPos)) { MyDebug.Log("HSUltMissile::OnTriggerEnter- " + enemyHeroes[i].photonView.ViewID + "는 솔져 미사일 폭발 속에서, 중간에 벽이 있어서 피해를 받지 않음"); continue; } Vector3 dir = enemyPosition.normalized; dir *= ((explosionRange - dis) * knockBackPowerInterValue); //폭발 지점과 거리 계산해서 알맞게 넉백 파워를 조절해줌. MyDebug.Log("HSUltMissile::OnTriggerEnter- " + enemyHeroes[i].photonView.ViewID + "솔져 미사일 피격. 넉백 = " + dir + "피해량=" + amount * (explosionRange - dis) * explosionRangeDiv); enemyHeroes[i].photonView.RPC("Knock", Photon.Pun.RpcTarget.All, dir); enemyHeroes[i].photonView.RPC("GetDamaged", Photon.Pun.RpcTarget.All, amount * (explosionRange - dis) * explosionRangeDiv, attachingHero.photonView.ViewID); } } }
private void OnTriggerEnter(Collider other) { if (!attachingHero.photonView.IsMine) { return; } if (!(other.gameObject.layer == Constants.mapLayerMask || TeamInfo.GetInstance().IsThisLayerEnemy(other.gameObject.layer))) { return; } //적이나 맵에 트리거 시 폭발. Vector3 collCenter = coll.bounds.center; //콜라이더의 센터를 폭발 지점으로. attachingHero.photonView.RPC("BoomUltMissile", Photon.Pun.RpcTarget.All, attachedNumber, transform.position); //효과만. List <Hero> enemyHeroes = TeamInfo.GetInstance().EnemyHeroes; //나중에 적 히어로 받아오기로. for (int i = 0; i < enemyHeroes.Count; i++) { Vector3 enemyPosition = enemyHeroes[i].CenterPos - collCenter; if (enemyPosition.sqrMagnitude < explosionRangeSqr) { float dis = enemyPosition.magnitude; if (Physics.Raycast(collCenter, enemyPosition, dis, 1 << Constants.mapLayerMask)) { Debug.Log(enemyHeroes[i].photonView.ViewID + "는 솔져 궁 폭발 속에서, 중간에 벽이 있어서 피해를 받지 않음"); continue; //중간에 벽 있으므로 패스. } Vector3 dir = enemyPosition.normalized; dir *= ((explosionRange - dis) * knockBackPowerInterValue); //폭발 지점과 거리 계산해서 알맞게 넉백 파워를 조절해줌. Debug.Log(enemyHeroes[i].photonView.ViewID + "는 솔져 궁 영향 입음. 넉백 = " + dir + "피해량=" + amount * (explosionRange - dis) * explosionRangeDiv); enemyHeroes[i].photonView.RPC("Knock", Photon.Pun.RpcTarget.All, dir); enemyHeroes[i].photonView.RPC("GetDamaged", Photon.Pun.RpcTarget.All, amount * (explosionRange - dis) * explosionRangeDiv, attachingHero.photonView.ViewID); } } }
public void HookSuccess(int hookedEnemyPhotonViewID, float hookReturnTime) { velocity = retrieveVelocity; state = HookState.HookSuccess; if (false == TeamInfo.GetInstance().HeroPhotonIDDic.ContainsKey(hookedEnemyPhotonViewID)) { Retrieve(); return; } hookedEnemy = TeamInfo.GetInstance().HeroPhotonIDDic[hookedEnemyPhotonViewID]; if (hookedEnemy == null) { Retrieve(); return; } hookSuccessTime = 0f; hookSuccessReturnTime = hookReturnTime; MyDebug.Log("HHHook - HookSuccess : 훅 성공. 대상 photonID= " + hookedEnemyPhotonViewID + ", Hook Return Time = " + hookReturnTime); }
private void OnTriggerEnter(Collider other) { if (!attachingHero.photonView.IsMine) { return; } if (state != HookState.Activate) { return; } int layer = other.gameObject.layer; if (layer == Constants.mapLayerMask) { state = HookState.Retrieve; velocity = 0f; attachingHero.photonView.RPC("HookRetrieve", Photon.Pun.RpcTarget.All); return; } if (TeamInfo.GetInstance().IsThisLayerEnemy(layer)) { state = HookState.Retrieve; velocity = 0f; Hero enemy = other.gameObject.GetComponent <Hero>(); if (enemy == null) { Debug.Log("갈고리로 끌었으나 적이 히어로가 아님"); attachingHero.photonView.RPC("HookRetrieve", Photon.Pun.RpcTarget.All); return; } Vector3 enemyPos = enemy.transform.position; Vector3 destPos = attachingHero.transform.position + attachingHero.transform.TransformDirection(Vector3.forward) * hookedDestDis; enemy.photonView.RPC("Hooked", Photon.Pun.RpcTarget.All, enemyPos, destPos, transform.localPosition.z * retrieveVelocityDiv //후크가 원래 자리로 돌아오는데 걸리는 시간이 곧 사람이 끌리는 총 시간임. ); attachingHero.photonView.RPC("HookRetrieve", Photon.Pun.RpcTarget.All); } }
private void OnTriggerEnter(Collider other) { if (!attachingHero.photonView.IsMine) { return; } if (state != HookState.Activate) { return; } int layer = other.gameObject.layer; //장애물에 부딪힌 경우 if (layer == Constants.mapLayerMask && !other.gameObject.CompareTag(LayerMask.LayerToName(attachingHero.gameObject.layer))) { attachingHero.photonView.RPC("HookRetrieve", Photon.Pun.RpcTarget.All); return; } if (TeamInfo.GetInstance().IsThisLayerEnemy(layer)) { Hero enemy = other.gameObject.GetComponent <Hero>(); if (enemy == null) { MyDebug.Log("HHHook - OnTriggerEnter : 적으로 판정한 훅 대상에 Hero 컴포넌트가 없음"); attachingHero.photonView.RPC("HookRetrieve", Photon.Pun.RpcTarget.All); return; } //적 Hook 성공 Vector3 enemyPos = enemy.transform.position; Vector3 destPos = attachingHero.transform.position + attachingHero.transform.TransformDirection(Vector3.forward) * hookedDestDis; float hookReturnTime = (enemyPos - destPos).magnitude * retrieveVelocityDiv; enemy.photonView.RPC("GetBadState", Photon.Pun.RpcTarget.All, E_BadState.Stun, transform.localPosition.z * retrieveVelocityDiv);//대상 스턴 enemy.photonView.RPC("Hooked", Photon.Pun.RpcTarget.All, enemyPos, destPos, hookReturnTime); attachingHero.photonView.RPC("HookSuccess", Photon.Pun.RpcTarget.All, enemy.photonView.ViewID, hookReturnTime); } }
public void SetAsTeamSetting() { if (TeamInfo.GetInstance().IsThisLayerEnemy(attachingHero.gameObject.layer)) { playerNameTextMesh.color = Color.red; hpBar.color = Color.red; } else { playerNameTextMesh.color = Color.blue; hpBar.color = Color.white; } if (attachingHero != null) { playerNameTextMesh.text = attachingHero.PlayerName; attachingHeroMaxHPDiv = 1 / attachingHero.MaxHP; } teamSettingDone = true; }
void Update() { if (!TeamInfo.GetInstance().isTeamSettingDone) { return; } if (!PhotonNetwork.IsMasterClient) { return; } if (arrive) { return; } Vector3 dir; if (MoveSideCheck(out dir) == false) { if (ATeamCount > 0 || BTeamCount > 0) { heroClose = true; } else if (ATeamCount == 0 && BTeamCount == 0) { heroClose = false; } return; } if (ATeamCount > 0 || BTeamCount > 0) { heroClose = true; } else if (ATeamCount == 0 && BTeamCount == 0) { heroClose = false; } transform.Translate(dir * Time.deltaTime * moveSpeed, Space.World); }
void OnClientLefted() { if (!PhotonNetwork.IsMasterClient || judgeDone) { return; } List <Hero> enemies = TeamInfo.GetInstance().EnemyHeroes; int cnt = 0; for (int i = 0; i < enemies.Count; i++) { if (enemies[i] != null) { cnt++; } } if (cnt == 0) { photonView.RPC("GameJudgeReceived", RpcTarget.All, Constants.GetE_TeamByLayer(TeamInfo.GetInstance().MyTeamLayer)); } }
public virtual void GetDamaged(float damage, int attackerPhotonViewID) { if (IsDie) { return; } currHP -= damage; Debug.Log(photonView.ViewID + "겟 데미지드" + damage); if (currHP <= 0) { Debug.Log(photonView.ViewID + "겟데미지드 - 데미지 받아 사망."); Hero attacker = TeamInfo.GetInstance().HeroPhotonIDDic[attackerPhotonViewID]; if (attacker == null) { Debug.Log(photonView.ViewID + "겟 데미지드" + damage + "어태커가 존재하지 않음." + attackerPhotonViewID); } else { if (attackerPhotonViewID == photonView.ViewID) //내가 나를 공격자로 두고 겟 데미지를 부름 - 낙사한 경우임. { ShowKillLog(null, HeroType); } else { ShowKillLog(attacker.PlayerName, attacker.HeroType); } } dieAction(); } else if (TeamInfo.GetInstance().HeroPhotonIDDic[attackerPhotonViewID].gameObject.layer == TeamInfo.GetInstance().MyTeamLayer // ((int)attackerPhotonViewID/1000) == TeamInfo.GetInstance().MyPhotonViewIDKey) ) { Debug.Log("오클루드 실행"); SetOcclude(3f); } }
void HitEnemy(Vector3 activatePos, Vector3 cutPlaneNormal) { if (!attachingHero.photonView.IsMine) { return; } List <Hero> enemyHeroes = TeamInfo.GetInstance().EnemyHeroes; for (int i = 0; i < enemyHeroes.Count; i++) { if (Vector3.Dot((enemyHeroes[i].CenterPos - activatePos), cutPlaneNormal) < Mathf.Epsilon) { continue; } Vector3 enemyPosition = enemyHeroes[i].CenterPos - transform.position; if (enemyPosition.sqrMagnitude < distanceSqr) { enemyHeroes[i].photonView.RPC("GetDamaged", Photon.Pun.RpcTarget.All, amount, attachingHero.photonView.ViewID); } } }
private void OnTriggerEnter(Collider other) { if (!attachingHero.photonView.IsMine) { return; } if (state != E_PenetrateState.Shot) { return; } GameObject hit = other.gameObject; MyDebug.Log("HSPenetrateVision:: OnTriggerEnter - 충돌" + hit.name + " , 충돌 물체 레이어 = " + LayerMask.LayerToName(hit.layer) + ", 태그 = " + hit.tag); if ((hit.layer == Constants.mapLayerMask && !hit.CompareTag(LayerMask.LayerToName(attachingHero.gameObject.layer))) //벽에 부딪힌 경우. || TeamInfo.GetInstance().IsThisLayerEnemy(hit.layer) //적에 부딪힌 경우 ) { attachingHero.photonView.RPC("PenetrateVisionSettle", Photon.Pun.RpcTarget.All, transform.position); return; } }
public virtual void GetDamaged(float damage, int attackerPhotonViewID) { if (IsDie) { return; } currHP -= damage; MyDebug.Log("Hero::GetDamaged - " + photonView.ViewID + "GetDamaged RPC Called . " + damage); if (currHP <= 0) { MyDebug.Log("Hero::GetDamaged - " + photonView.ViewID + " 사망."); Hero attacker = TeamInfo.GetInstance().HeroPhotonIDDic[attackerPhotonViewID]; if (attacker == null) { MyDebug.Log("Hero::GetDamaged - " + photonView.ViewID + "RPC Called dmg = " + damage + " , but 공격자가 존재하지 않음." + attackerPhotonViewID); } else { if (attackerPhotonViewID == photonView.ViewID) //내가 나를 공격자로 두고 겟 데미지를 부름 - 낙사한 경우임. { ShowKillLog(null, HeroType); } else { ShowKillLog(attacker.PlayerName, attacker.HeroType); } } dieAction(); } else if (TeamInfo.GetInstance().HeroPhotonIDDic[attackerPhotonViewID].gameObject.layer == TeamInfo.GetInstance().MyTeamLayer //어태커의 팀이 "이" 클라이언트와 같은 팀이라면 피격당한 이 히어로의 피격 효과를 줌. ) { SetBeAttackedEffect(3f); } }
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 }
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); } }