public void Damage(vp_DamageInfo damageInfo) { if (reciever) { damageInfo.Damage *= DamageMultiply; reciever.Damage(damageInfo); } if (reciever2) { damageInfo.Damage *= DamageMultiply; reciever2.Damage(damageInfo); } }
/// <summary> /// forwards damage in UFPS format to a damagehandler on the target object /// </summary> public virtual void Damage(vp_DamageInfo damageInfo) { if (!enabled) { return; } if (m_TargetDamageHandler != null) { m_TargetDamageHandler.Damage(damageInfo); } else { Damage(damageInfo.Damage); } }
/// <summary> /// /// </summary> void OnTriggerEnter(Collider col) { // return if this is not a relevant object. TIP: this check can be expanded if (col.gameObject.layer == vp_Layer.Debris || col.gameObject.layer == vp_Layer.Pickup) return; // try to find a damagehandler on the target and abort on fail m_TargetDamageHandler = vp_DamageHandler.GetDamageHandlerOfCollider(col); if (m_TargetDamageHandler == null) return; // abort if target is already dead // NOTE: this deals with cases of multiple 'OnTriggerEnter' calls on contact if (m_TargetDamageHandler.CurrentHealth <= 0) return; // try to find a respawner on the target to see if it's currently OK to kill it m_TargetRespawner = vp_Respawner.GetByCollider(col); if (m_TargetRespawner != null) { // abort if target has respawned within one second before this call. // NOTE: this addresses a case where 'OnTriggerEnter' is called when // teleporting (respawning) away from the trigger, resulting in the // object getting insta-killed on respawn. it will only work if the // target gameobject has a vp_Respawner-derived component if (Time.time < m_TargetRespawner.LastRespawnTime + 1.0f) return; } m_TargetDamageHandler.Damage(new vp_DamageInfo(m_TargetDamageHandler.CurrentHealth, m_TargetDamageHandler.Transform, vp_DamageInfo.DamageType.KillZone)); }
/// <summary> /// attempts to do damage using a regular Unity-message, and / or more advanced /// UFPS format damage (whichever is supported by the bullet and target) /// </summary> protected virtual void TryDamage() { // send primitive damage as UnityMessage. this allows support for many third party // systems (simply use a 'void Damage(float)' method in target MonoBehaviours) if ((DamageMode == vp_DamageInfo.DamageMode.UnityMessage) || (DamageMode == vp_DamageInfo.DamageMode.Both)) { m_TargetCollider.gameObject.BroadcastMessage(DamageMessageName, (DistanceModifier * Damage), SendMessageOptions.DontRequireReceiver); #if UNITY_EDITOR if (!m_DidWarnAboutBothMethodName && (DamageMessageName == "Damage") && (vp_DamageHandler.GetDamageHandlerOfCollider(m_TargetCollider) != null)) { Debug.LogWarning("Warning (" + this + ") Target object has a vp_DamageHandler. When damaging it with DamageMode: 'UnityMessage' or 'Both', you probably want to change 'DamageMessageName' to something other than 'Damage', or too much damage might be applied."); m_DidWarnAboutBothMethodName = true; } #endif } // send damage in UFPS format. this allows different damage types, and tracking damage source if ((DamageMode == vp_DamageInfo.DamageMode.DamageHandler) || (DamageMode == vp_DamageInfo.DamageMode.Both)) { m_TargetDHandler = vp_DamageHandler.GetDamageHandlerOfCollider(m_TargetCollider); if (m_TargetDHandler != null) { m_TargetDHandler.Damage(new vp_DamageInfo((DistanceModifier * Damage), Source, OriginalSource, vp_DamageInfo.DamageType.Explosion)); } } }
public void OnTriggerStay(Collider other) { vp_DamageHandler handler = other.GetComponent <vp_DamageHandler>(); if (handler) { handler.Damage(new vp_DamageInfo(DamagePerSecond * Time.deltaTime, transform)); } }
/// <summary> /// sends damage to a target that has a vp_DamageHandler (or derived) /// component /// </summary> protected virtual void DoUFPSDamage(float damage) { // abort if this explosion has already hit this damagehandler if (m_DHandlersHitByThisExplosion.ContainsKey(m_TargetDHandler)) { return; } // remember that we have processed this target m_DHandlersHitByThisExplosion.Add(m_TargetDHandler, null); // this was a known target and we have a damagehandler for it m_TargetDHandler.Damage(new vp_DamageInfo(damage, Source, OriginalSource, vp_DamageInfo.DamageType.Explosion)); // send the damage! }
/// <summary> /// /// </summary> void DoDamage() { m_TargetDHandler = vp_DamageHandler.GetDamageHandlerOfCollider(m_TargetCollider); if (m_TargetDHandler != null) { // target has a known damagehandler -> send damage in UFPS format. // this works with targets that have a vp_DamageHandler (or derived) component m_TargetDHandler.Damage(new vp_DamageInfo((DistanceModifier * Damage), Source, OriginalSource, vp_DamageInfo.DamageType.Explosion)); } else if (!RequireDamageHandler) { // target is known to have no damagehandler -> send damage the 'Unity way'. // this works with targets that have a custom script with the standard // method: "Damage(float damage)" m_TargetCollider.gameObject.BroadcastMessage(DamageMessageName, (DistanceModifier * Damage), SendMessageOptions.DontRequireReceiver); } }
/// <summary> /// /// </summary> void OnTriggerEnter(Collider col) { // return if this is not a relevant object. TIP: this check can be expanded if (col.gameObject.layer == vp_Layer.Debris || col.gameObject.layer == vp_Layer.Pickup) { return; } // try to find a damagehandler on the target and abort on fail m_TargetDamageHandler = vp_DamageHandler.GetDamageHandlerOfCollider(col); if (m_TargetDamageHandler == null) { return; } // abort if target is already dead // NOTE: this deals with cases of multiple 'OnTriggerEnter' calls on contact if (m_TargetDamageHandler.CurrentHealth <= 0) { return; } // try to find a respawner on the target to see if it's currently OK to kill it m_TargetRespawner = vp_Respawner.GetByCollider(col); if (m_TargetRespawner != null) { // abort if target has respawned within one second before this call. // NOTE: this addresses a case where 'OnTriggerEnter' is called when // teleporting (respawning) away from the trigger, resulting in the // object getting insta-killed on respawn. it will only work if the // target gameobject has a vp_Respawner-derived component if (Time.time < m_TargetRespawner.LastRespawnTime + 1.0f) { return; } } m_TargetDamageHandler.Damage(new vp_DamageInfo(m_TargetDamageHandler.CurrentHealth, m_TargetDamageHandler.Transform, vp_DamageInfo.DamageType.KillZone)); }
/// <summary> /// applies damage in the UFPS format, with the amount of damage and its /// source. NOTE: this method is overridden by 'vp_FXBullet' /// </summary> protected virtual void DoUFPSDamage() { m_TargetDHandler.Damage(new vp_DamageInfo(Damage, m_Source)); }
/// <summary> /// everything happens in the DoHit method. the script that /// spawns the bullet is responsible for setting its position /// and angle. after being instantiated, the bullet immediately /// raycasts ahead for its full range, then snaps itself to /// the surface of the first object hit. it then spawns a /// number of particle effects and plays a random impact sound. /// </summary> void DoHit() { Ray ray = new Ray(m_Transform.position, m_Transform.forward); // if this bullet was fired by the local player, don't allow it to hit the local player if ((m_Source != null) && (m_Source.gameObject.layer == vp_Layer.LocalPlayer)) LayerMask = vp_Layer.Mask.BulletBlockers; // raycast against all big, solid objects except the player itself // SNIPPET: using this instead may be useful in cases where bullets // fail to hit colliders (however likely at a performance cost) //if (Physics.Linecast(m_Transform.position, m_Transform.position + (m_Transform.forward * Range), out hit, LayerMask)) if (Physics.Raycast(ray, out m_Hit, Range, LayerMask)) { // NOTE: we can't bail out of this if-statement based on !collider.isTrigger, // because that would make bullets _disappear_ if they hit a trigger. to make a // trigger not interfere with bullets, put it in the layer: 'vp_Layer.Trigger' // (default: 27) // move this gameobject instance to the hit object Vector3 scale = m_Transform.localScale; // save scale to handle scaled parent objects m_Transform.parent = m_Hit.transform; m_Transform.localPosition = m_Hit.transform.InverseTransformPoint(m_Hit.point); m_Transform.rotation = Quaternion.LookRotation(m_Hit.normal); // face away from hit surface if (m_Hit.transform.lossyScale == Vector3.one) // if hit object has normal scale m_Transform.Rotate(Vector3.forward, Random.Range(0, 360), Space.Self); // spin randomly else { // rotated child objects will get skewed if the parent object has been // unevenly scaled in the editor, so on scaled objects we don't support // spin, and we need to unparent, rescale and reparent the decal. m_Transform.parent = null; m_Transform.localScale = scale; m_Transform.parent = m_Hit.transform; } // if hit object has physics, add the bullet force to it Rigidbody body = m_Hit.collider.attachedRigidbody; if (body != null && !body.isKinematic) body.AddForceAtPosition(((ray.direction * Force) / Time.timeScale) / vp_TimeUtility.AdjustedTimeScale, m_Hit.point); // spawn impact effect if (m_ImpactPrefab != null) vp_Utility.Instantiate(m_ImpactPrefab, m_Transform.position, m_Transform.rotation); // spawn dust effect if (m_DustPrefab != null) vp_Utility.Instantiate(m_DustPrefab, m_Transform.position, m_Transform.rotation); // spawn spark effect if (m_SparkPrefab != null) { if (Random.value < m_SparkFactor) vp_Utility.Instantiate(m_SparkPrefab, m_Transform.position, m_Transform.rotation); } // spawn debris particle fx if (m_DebrisPrefab != null) vp_Utility.Instantiate(m_DebrisPrefab, m_Transform.position, m_Transform.rotation); // play impact sound if (m_ImpactSounds.Count > 0) { m_Audio.pitch = Random.Range(SoundImpactPitch.x, SoundImpactPitch.y) * Time.timeScale; m_Audio.clip = m_ImpactSounds[(int)Random.Range(0, (m_ImpactSounds.Count))]; m_Audio.Stop(); m_Audio.Play(); } // do damage if possible m_TargetDHandler = vp_DamageHandler.GetDamageHandlerOfCollider(m_Hit.collider); // try to find a damage handler on the target if ((m_TargetDHandler != null) && (m_Source != null)) { // this was a known damagehandler target and we know the source: send UFPS damage! m_TargetDHandler.Damage(new vp_DamageInfo(Damage, m_Source, vp_DamageInfo.DamageType.Bullet)); } else if (!RequireDamageHandler) { // this target was known to have no damagehandler: send damage using unitymessage (if allowed) m_Hit.collider.SendMessage(DamageMethodName, Damage, SendMessageOptions.DontRequireReceiver); } // prevent adding decals to objects based on layer if ((m_Renderer != null) && NoDecalOnTheseLayers.Length > 0) { foreach (int layer in NoDecalOnTheseLayers) { if (m_Hit.transform.gameObject.layer != layer) continue; m_Renderer.enabled = false; TryDestroy(); return; } } // if bullet is visible (i.e. has a decal), queue it for deletion later if(m_Renderer != null) vp_DecalManager.Add(gameObject); else vp_Timer.In(1, TryDestroy); // we have no renderer, so destroy object in 1 sec } else vp_Utility.Destroy(gameObject); // hit nothing, so self destruct immediately }
/// <summary> /// everything happens in the DoHit method. the script that /// spawns the bullet is responsible for setting its position /// and angle. after being instantiated, the bullet immediately /// raycasts ahead for its full range, then snaps itself to /// the surface of the first object hit. it then spawns a /// number of particle effects and plays a random impact sound. /// </summary> void DoHit() { Ray ray = new Ray(m_Transform.position, m_Transform.forward); // if this bullet was fired by the local player, don't allow it to hit the local player if ((m_Source != null) && (m_Source.gameObject.layer == vp_Layer.LocalPlayer)) { LayerMask = vp_Layer.Mask.BulletBlockers; } // raycast against all big, solid objects except the player itself // SNIPPET: using this instead may be useful in cases where bullets // fail to hit colliders (however likely at a performance cost) //if (Physics.Linecast(m_Transform.position, m_Transform.position + (m_Transform.forward * Range), out hit, LayerMask)) if (Physics.Raycast(ray, out m_Hit, Range, LayerMask)) { // NOTE: we can't bail out of this if-statement based on !collider.isTrigger, // because that would make bullets _disappear_ if they hit a trigger. to make a // trigger not interfere with bullets, put it in the layer: 'vp_Layer.Trigger' // (default: 27) // move this gameobject instance to the hit object Vector3 scale = m_Transform.localScale; // save scale to handle scaled parent objects m_Transform.parent = m_Hit.transform; m_Transform.localPosition = m_Hit.transform.InverseTransformPoint(m_Hit.point); m_Transform.rotation = Quaternion.LookRotation(m_Hit.normal); // face away from hit surface if (m_Hit.transform.lossyScale == Vector3.one) // if hit object has normal scale { m_Transform.Rotate(Vector3.forward, Random.Range(0, 360), Space.Self); // spin randomly } else { // rotated child objects will get skewed if the parent object has been // unevenly scaled in the editor, so on scaled objects we don't support // spin, and we need to unparent, rescale and reparent the decal. m_Transform.parent = null; m_Transform.localScale = scale; m_Transform.parent = m_Hit.transform; } // if hit object has physics, add the bullet force to it Rigidbody body = m_Hit.collider.attachedRigidbody; if (body != null && !body.isKinematic) { body.AddForceAtPosition(((ray.direction * Force) / Time.timeScale) / vp_TimeUtility.AdjustedTimeScale, m_Hit.point); } // spawn impact effect if (m_ImpactPrefab != null) { vp_Utility.Instantiate(m_ImpactPrefab, m_Transform.position, m_Transform.rotation); } // spawn dust effect if (m_DustPrefab != null) { vp_Utility.Instantiate(m_DustPrefab, m_Transform.position, m_Transform.rotation); } // spawn spark effect if (m_SparkPrefab != null) { if (Random.value < m_SparkFactor) { vp_Utility.Instantiate(m_SparkPrefab, m_Transform.position, m_Transform.rotation); } } // spawn debris particle fx if (m_DebrisPrefab != null) { vp_Utility.Instantiate(m_DebrisPrefab, m_Transform.position, m_Transform.rotation); } // play impact sound if (m_ImpactSounds.Count > 0) { m_Audio.pitch = Random.Range(SoundImpactPitch.x, SoundImpactPitch.y) * Time.timeScale; m_Audio.clip = m_ImpactSounds[(int)Random.Range(0, (m_ImpactSounds.Count))]; m_Audio.Stop(); m_Audio.Play(); } // do damage if possible m_TargetDHandler = vp_DamageHandler.GetDamageHandlerOfCollider(m_Hit.collider); // try to find a damage handler on the target if ((m_TargetDHandler != null) && (m_Source != null)) { // this was a known damagehandler target and we know the source: send UFPS damage! m_TargetDHandler.Damage(new vp_DamageInfo(Damage, m_Source, vp_DamageInfo.DamageType.Bullet)); } else if (!RequireDamageHandler) { // this target was known to have no damagehandler: send damage using unitymessage (if allowed) m_Hit.collider.SendMessage(DamageMethodName, Damage, SendMessageOptions.DontRequireReceiver); } // prevent adding decals to objects based on layer if ((m_Renderer != null) && NoDecalOnTheseLayers.Length > 0) { foreach (int layer in NoDecalOnTheseLayers) { if (m_Hit.transform.gameObject.layer != layer) { continue; } m_Renderer.enabled = false; TryDestroy(); return; } } // if bullet is visible (i.e. has a decal), queue it for deletion later if (m_Renderer != null) { vp_DecalManager.Add(gameObject); } else { vp_Timer.In(1, TryDestroy); // we have no renderer, so destroy object in 1 sec } } else { vp_Utility.Destroy(gameObject); // hit nothing, so self destruct immediately } }
void Update() { // spawn fire when near to fireplace // only one boolean variable is required - assumption - player will be near either one or a group of fireplace at the moment if (isNearToFirePlace && Input.GetKeyDown(KeyCode.E)) { isConsumingHeat = true; } //fade in/out frost/heat icon if (isFadingInFrostIcon) { fadeInImage(ref tempFrostColor, ref frostIcon, ref isFadingInFrostIcon); } if (isFadingInHeatIcon) { fadeInImage(ref tempHeatColor, ref heatIcon, ref isFadingInHeatIcon); } if (isFadingOutFrostIcon) { fadeOutImage(ref tempFrostColor, ref frostIcon, ref isFadingOutFrostIcon); } if (isFadingOutHeatIcon) { fadeOutImage(ref tempHeatColor, ref heatIcon, ref isFadingOutHeatIcon); } fwd = transform.TransformDirection(Vector3.forward); //check for raycast hit with fireplace every second if (Time.time >= nextTime) { nextTime += (int)THERMAL_LIMITS.NEXT_UPDATE_INTERVAL; //When near heat source "frost" goes up by FROST_INCREASE_RATE units per second to max THERMAL_LIMITS.MAX_TEMP if (Physics.Raycast(transform.position, fwd, out hit, rayLength) && hit.collider.gameObject.CompareTag(Tags.FIREBOX_TAG)) { //increase frost temp if near fireplace every second Debug.Log("raycast hit "); isNearToFirePlace = true; if (isConsumingHeat) { Debug.Log("consuimg heat"); //span fire GameObject firePlace = hit.collider.gameObject; if (firePlace2FireFlameMap.Contains(firePlace)) { Debug.Log(" already spawing fire for this fireplace "); } else { Debug.Log("spawning fire "); //http://answers.unity3d.com/questions/965909/how-to-spawn-gameobject-exactly-on-top-of-another.html float firePlacePlatformSize = firePlace.GetComponent <Renderer>().bounds.size.y; float fireFlameBlockSize = fireFlame.GetComponent <Renderer>().bounds.size.y; GameObject spawnedFlames = (GameObject)Instantiate(fireFlame, new Vector3(firePlace.transform.position.x, firePlace.transform.position.y + fireFlameBlockSize, firePlace.transform.position.z), Quaternion.identity); firePlace2FireFlameMap.Add(firePlace, spawnedFlames); } // consume heat if (currentFrostTemp < (int)THERMAL_LIMITS.MAX_TEMP) { // i crease frost temp currentFrostTemp += FROST_INCREASE_RATE; // fade out frost icon when temperature goes above FROST_TEMP if (currentFrostTemp > ((int)THERMAL_LIMITS.FROST_TEMP) && isFrostIconVisible) { isFadingOutFrostIcon = true; // fade out frost icon in Update() isFrostIconVisible = false; } } // reset frost temp if greater then THERMAL_LIMITS.MAX_TEMP if (currentFrostTemp > (int)THERMAL_LIMITS.MAX_TEMP) { currentFrostTemp = (int)THERMAL_LIMITS.MAX_TEMP; // set currentFrostTemp to max temperature Debug.Log("heat icon gone"); // heat icon visibility logic //When "frost" increases THERMAL_LIMITS.MAX_TEMP "heat icon" disappears. if (isHeatIconVisible) { isFadingOutHeatIcon = true; isHeatIconVisible = false; } } } } // decrease frost value every second when not near aheat source else if (currentFrostTemp >= (int)THERMAL_LIMITS.TEMP_ZERO) { isNearToFirePlace = false; isConsumingHeat = false; //Frost goes down by FROST_DECREASE_RATE per second when not near heat source currentFrostTemp -= FROST_DECREASE_RATE; // show frost icon when temp is less then FROST_TEMP if (currentFrostTemp == (int)THERMAL_LIMITS.FROST_TEMP) { isFadingInFrostIcon = true; isFrostIconVisible = true; } else if (currentFrostTemp < (int)THERMAL_LIMITS.TEMP_ZERO) { currentFrostTemp = (int)THERMAL_LIMITS.TEMP_ZERO; // reset frost temp to zero //lower health by HEALTH_LOW_HP Debug.Log("damage occurs"); damg.Damage(HEALTH_LOW_HP); // add damage to player } // show heat icon when frost temp is below THERMAL_LIMITS.MAX_TEMP if (!isHeatIconVisible) { isFadingInHeatIcon = true; isHeatIconVisible = true; } } } }