void OnTriggerEnter(Collider col) { //cache corresponding gameobject that was hit GameObject obj = col.gameObject; //try to get a player component out of the collided gameobject Player player = obj.GetComponent <Player>(); // PlayerBot bot = obj.GetComponent<PlayerBot>(); //we actually hit a player //do further checks if (player != null && col.tag == "Bot") { //ignore ourselves & disable friendly fire (same team index) // if (player.gameObject == owner) // return; // else if (obj.tag == owner.tag) // return; // else if (player.GetView().GetTeam() == owner.GetComponent<Player>().GetView().GetTeam()) return; // else if (null != bot && bot == owner.GetComponent<PlayerBot>()) return; //create clips and particles on hit if (hitFX && stateWepon == 0) { PoolManager.Spawn(hitFX, transform.position, Quaternion.identity); } else if (hitFX && stateWepon == 1) { PoolManager.Spawn(TextBonfire, transform.position, Quaternion.identity); PoolManager.Spawn(Bonfire, transform.position, Quaternion.identity); GameObject damagebonfire = PoolManager.Spawn(Bonfire, transform.position, Quaternion.identity); damagebonfire.GetComponent <BonFire>().damage = TakedamageBullet(); } else if (hitFX && stateWepon == 2) { PoolManager.Spawn(TextFlost, transform.position, Quaternion.identity); PoolManager.Spawn(Flost, transform.position, Quaternion.identity); } if (TextLandmind) { PoolManager.Spawn(TextLandmind, transform.position, Quaternion.identity); } if (zoneTakedamage) { PoolManager.Spawn(zoneTakedamage, transform.position, Quaternion.identity); GameObject Spawndamage = PoolManager.Spawn(zoneTakedamage, transform.position, Quaternion.identity); if (stateWepon == 1) { Spawndamage.GetComponent <ZoneTakedamage>().damage = (int)(TakedamageBullet() + (TakedamageBullet() * 0.5)); } else { Spawndamage.GetComponent <ZoneTakedamage>().damage = TakedamageBullet(); } } if (hitClip) { AudioManager.Play3D(hitClip, transform.position); } //on the player that was hit, set the killing player to the owner of this bullet //maybe this owner really killed the player, but that check is done in the Player script player.killedBy = owner; gameObject.SetActive(false); } //despawn gameobject //the previous code is not synced to clients at all, because all that clients need is the //initial position and direction of the bullet to calculate the exact same behavior on their end. //at this point, continue with the critical game aspects only on the server if (!PhotonNetwork.isMasterClient) { return; } //apply bullet damage to the collided player }
///check what was hit on collisions. Only do non-critical client work here, //not even accessing player variables or anything like that. The server side is separate below void OnTriggerEnter(Collider col) { //cache corresponding gameobject that was hit GameObject obj = col.gameObject; //try to get a player component out of the collided gameobject Player player = obj.GetComponent <Player>(); //we actually hit a player //do further checks if (player != null) { //ignore ourselves & disable friendly fire (same team index) if (IsFriendlyFire(owner.GetComponent <Player>(), player)) { return; } //create clips and particles on hit if (hitFX) { PoolManager.Spawn(hitFX, transform.position, Quaternion.identity); } if (hitClip) { AudioManager.Play3D(hitClip, transform.position); } } else if (bounce > 0) { //a player was not hit but something else, and we still have some bounces left //create a ray that points in the direction this bullet is currently flying to Ray ray = new Ray(lastBouncePos - transform.forward * 0.5f, transform.forward); RaycastHit hit; //perform spherecast in the flying direction, on the default layer if (Physics.SphereCast(ray, sphereCol.radius, out hit, Mathf.Infinity, 1 << 0)) { //ignore multiple collisions i.e. inside colliders if (Vector3.Distance(transform.position, lastBouncePos) < 0.05f) { return; } //cache latest collision point lastBouncePos = hit.point; //substract bouncing count by one bounce--; //something was hit in the direction this projectile is flying to //get new reflected (bounced off) direction of the colliding object Vector3 dir = Vector3.Reflect(ray.direction, hit.normal); //rotate bullet to face the new direction transform.rotation = Quaternion.LookRotation(dir); //reassign velocity with the new direction in mind OnSpawn(); //play clip at the collided position if (hitClip) { AudioManager.Play3D(hitClip, transform.position); } //exit execution until next collision return; } } //despawn gameobject PoolManager.Despawn(gameObject); //the previous code is not synced to clients at all, because all that clients need is the //initial position and direction of the bullet to calculate the exact same behavior on their end. //at this point, continue with the critical game aspects only on the server if (!PhotonNetwork.IsMasterClient) { return; } //create list for affected players by this bullet and add the collided player immediately, //we have done validation & friendly fire checks above already List <Player> targets = new List <Player>(); if (player != null) { targets.Add(player); } //in case this bullet can hit more than 1 target, perform the additional physics area check if (maxTargets > 1) { //find all colliders in the specified range around this bullet, on the Player layer Collider[] others = Physics.OverlapSphere(transform.position, explosionRange, 1 << 8); Player ownerPlayer = owner.GetComponent <Player>(); //loop over all player collisions found for (int i = 0; i < others.Length; i++) { //get Player component from that collision Player other = others[i].GetComponent <Player>(); if (other == null || targets.Contains(other)) { continue; } //again, ignore own bullets and also friendly fire, now done exclusively on server side if (IsFriendlyFire(ownerPlayer, other)) { continue; } //add this Player component to the list //cancel in case we do reach the maximum count now targets.Add(other); if (targets.Count == maxTargets) { break; } } } //apply bullet damage to the collided players for (int i = 0; i < targets.Count; i++) { targets[i].TakeDamage(this); } }
IEnumerator OnProjectileShootRoutine() { while (true) { UIJoystick Uijoy = FindObjectOfType <UIJoystick>(); //shoot bullet on left mouse click if (projectile == false && landmine == false) { Uijoy.UIBullet(); if (Input.GetButton("Fire1")) { Shoot(); } } else if (projectile == true && landmine == false) { Uijoy.UIProjectile(); if (Input.GetButton("Fire1")) { m_BulletSpeed += Time.deltaTime * 5f; DrawLineProjectile(); } else if (Input.GetButtonUp("Fire1")) { ShootProjectile(); projectile = false; m_BulletSpeed = defaultBulletSpeed; renderLine.positionCount = 0; lastProjectilePosition.gameObject.SetActive(false); yield return(new WaitForSeconds(fireRate)); } } else if (landmine == true && projectile == false) { Uijoy.UILandmine(); if (Input.GetButton("Fire1")) { // PoolManager.Spawn(landMine, transform.position, Quaternion.identity); GameObject obj = PoolManager.Spawn(bullets[2], transform.position, Quaternion.identity); obj.GetComponent <Landmine>().stateWepon = StateWepon; landmine = false; } } else { landmine = false; projectile = false; } yield return(null); } }
/// <summary> /// On Host, add automatic despawn coroutine /// </summary> public override void OnStartServer() { PoolManager.Despawn(gameObject, despawnDelay); }