public static float DistanceFromGround(Rigidbody player, out PillarBehaviour hitPillar) { // Find the highest pillar cllider under the player and return the distance from it hitPillar = null; float highestHit = -1; var hits = Physics.RaycastAll( player.transform.position + player.transform.up, -player.transform.up, 2 * UserDefinedConstants.sphereRadius, 1 << LayerMask.NameToLayer("Environment")); if (hits.Length == 0) { Debug.LogError("Nothing under player!"); return(-1); } foreach (var hit in hits) { var pillar = hit.collider.gameObject.GetComponent <PillarBehaviour>(); if (pillar != null && pillar.currentHeight > highestHit) { hitPillar = pillar; highestHit = pillar.currentHeight; } } if (hitPillar == null) { Debug.LogError(string.Format("Raycast didn't get a pillar / bounding-sphere hit! Hit {0} instead", hits[0].collider.gameObject.name)); return(-1); } float dist = (UserDefinedConstants.sphereRadius - hitPillar.currentHeight) - player.position.magnitude; // Dist of pillar surface from origin minus dist of player from origin return(dist); }
public static PillarBehaviour Create( bool isHexagon, Vector3 location, float edgeLength, float h, float collExpansion, int pillarId = -1) { Object obj = isHexagon ? Resources.Load("Prefabs/Hexagon") : Resources.Load("Prefabs/Pentagon"); GameObject pillarObj = Instantiate(obj, location, Quaternion.identity) as GameObject; PillarBehaviour pillar = pillarObj.GetComponent <PillarBehaviour>(); pillar.isHex = isHexagon; pillar.edge = edgeLength; pillar.targetHeight = h; pillar.currentHeight = h; pillar.maxHeight = maxHeightPercentage * UserDefinedConstants.sphereRadius; pillar.extensionDelta = extensionDeltaPercentage * UserDefinedConstants.sphereRadius; pillar.timeToTarget = 0f; pillar.collisionExpansion = collExpansion; pillar.extending = false; pillar.primedToLaunch = false; pillar.heightLocked = false; pillar.id = pillarId; pillar.mesh = new Mesh(); pillar.collMesh = new Mesh(); pillar.needRedraw = true; pillar.meshVertexMap = new Dictionary <int, int>(); return(pillar); }
private void extensionFX() { // We want to play a sound from the height of the lowest neighbor (lower than us) PillarBehaviour lowestNeighbor = null; foreach (PillarBehaviour neighbor in neighbors) { if (neighbor.currentHeight > currentHeight + 1) { continue; } // We'll play a sound from the height of the lowest-height neighbor (if we're not surrounded by higher neighbors). if (lowestNeighbor == null || lowestNeighbor.currentHeight > neighbor.currentHeight) { lowestNeighbor = neighbor; } } float soundHeight = lowestNeighbor == null ? currentHeight : lowestNeighbor.currentHeight; Vector3 soundLocation = transform.position - (soundHeight * transform.position.normalized); AudioSource.PlayClipAtPoint(extensionSoundSteam, soundLocation); AudioSource.PlayClipAtPoint(extensionSoundScreech[Mathf.FloorToInt(Random.Range(0, extensionSoundScreech.Length - 0.01f))], soundLocation); // We show steam coming out from the center of the pillar Vector3 steamLocation = soundLocation + 15 * transform.position.normalized; // A little lower var steam = Instantiate(steamPrefab, steamLocation, Quaternion.identity); steam.transform.LookAt(Vector3.zero); Destroy(steam, steam.GetComponent <ParticleSystem>().main.duration * 5); }
/** Only the shooter's instance of the projectile has a collider */ void OnCollisionEnter(Collision col) { if (destroyed) { return; // Don' process more than one collision... hope this helps...? } // The first thing a projectile hits should destroy it (unless it's the shooter) GameObject obj = col.gameObject; // Check if it's a player. If it is, filter out the shooter. PlayerMovementController pmc = obj.GetComponent <PlayerMovementController>(); bool hitPlayer = (pmc != null); if (hitPlayer) { // Is this the shooter? if (Tools.NullToEmptyString(obj.GetComponent <PhotonView>().Owner.UserId) == shooterId) { return; } } // Did we hit a pillar? PillarBehaviour pillar = obj.GetComponent <PillarBehaviour>(); bool hitPillar = (pillar != null); if (hitPillar) { // TODO: One day I'll find out why objects are suddenly null... if (pillarCtrl == null) { InitControllers(); } pillarCtrl.BroadcastHitPillar(pillar.id); } // Is this projectile seeking a targetable player? If so we need to tell him we're not seeking him anymore if (lockedOn) { target.BroadcastBecameUntargeted(shooterId); } // Did we hit the sun? SunController sun = obj.GetComponent <SunController>(); if (sun != null) { sun.BroadcastHit(shooterId); } // In any case, all collisions destroy the projectile explosionCtrl.BroadcastExplosion(transform.position, shooterId, false); projectileCtrl.BroadcastDestroyProjectile(projectileId); destroyed = true; }
void ComputeExplosionPositions() { // We're in RPC context here (someone broadcasted a sun hit). We only broadcast an explosion if we're the shooter so otherwise we don't care if (shooterId != Tools.NullToEmptyString(PhotonNetwork.LocalPlayer.UserId)) { return; } // Find all objects in the sunray. Should always hit a pillar, at least. RaycastHit[] hits = Physics.RaycastAll(Vector3.zero, target.position); if (hits.Length == 0) { Debug.LogError("Sunray found nothing to hit with explosion! Exploding in the sun..."); explosionPositions = new List <Vector3> { Vector3.zero }; return; } // Find the highest hit pillar PillarBehaviour hitPillar = null; Vector3 hitPillarPosition = Vector3.zero; foreach (var hit in hits) { // Ignore non-pillar objects PillarBehaviour pillar = hit.collider.GetComponent <PillarBehaviour>(); if (pillar == null) { continue; } // Only take the highest hit pillar (with hitpoint closest to (0,0,0)) if (hitPillar == null || hitPillarPosition.magnitude > hit.point.magnitude) { hitPillar = pillar; hitPillarPosition = hit.point; } } // Add the hit pillar location to the explosion list, and find all hit players above the pillar explosionPositions = new List <Vector3> { hitPillarPosition }; hitPillarId = hitPillar.id; foreach (var hit in hits) { // Ignore the sun itself, and all objects below the height of the hit pillar if (hit.point.magnitude > hitPillarPosition.magnitude || hit.collider.gameObject.name == "Sun") { continue; } // If this is a network character closer to the sun than the top of the pillar, add the hitpoint. // However, if player is grounded, don't trigger an explosion; player should be taking damage from the explosion on the pillar bool isNetChar = hit.collider.GetComponent <NetworkCharacter>() != null; Rigidbody rb = hit.collider.GetComponent <Rigidbody>(); bool grounded = rb != null && GeoPhysics.IsPlayerGrounded(rb); if (isNetChar && !grounded) { explosionPositions.Add(hit.point); } } }
public static bool IsPlayerGrounded(Rigidbody player, out PillarBehaviour hitPillar) { float dist = DistanceFromGround(player, out hitPillar); return(hitPillar == null ? false : dist < 0.1f); }