|
Post by jrackley on Dec 10, 2016 19:33:13 GMT
So I finally managed to get a pretty decent fall damage script put together, it is a modified version to work with Invector from one that I found online. I figured I would post it on here just in case anyone would like to use it. All you have to do is attach the script to your player, and set the threshold that you would like to have the damage to apply after going above. It then calculates the damage based on the y position above the threshold. I have multiplied the damage in the script for more realistic effect from heights, however you can change that value to whatever you would to suit your needs.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Invector;
using Invector.EventSystems;
namespace Invector.CharacterController
{
public class FallDamage : MonoBehaviour
{
public float startYPos;
public float endYPos;
public float damageThreshold;
public bool damaged = false;
public bool firstCall = true;
public float extraDamageMultiplier = 0f;
// Update is called once per frame
void Update ()
{
if (!transform.GetComponent<vThirdPersonController> ().isGrounded) {
if (transform.position.y > startYPos) {
firstCall = true;
}
if (firstCall) {
startYPos = transform.position.y;
firstCall = false;
damaged = true;
}
}
if (transform.GetComponent<vThirdPersonController> ().isGrounded) {
endYPos = transform.position.y;
if (startYPos - endYPos > damageThreshold) {
if (damaged) {
FallDamaged (startYPos - endYPos - damageThreshold);
damaged = false;
firstCall = true;
}
}
}
}
public void FallDamaged (float damageAmount)
{
/***** Add extra damage for more realism from heights*****/
if (extraDamageMultiplier > 0f) {
var damage = damageAmount * extraDamageMultiplier;
transform.GetComponent<vCharacter> ().currentHealth -= damage;
transform.GetComponent<vCharacter> ().currentHealth = Mathf.Round (transform.GetComponent<vCharacter> ().currentHealth);
} else {
var damage = damageAmount;
transform.GetComponent<vCharacter> ().currentHealth -= damage;
transform.GetComponent<vCharacter> ().currentHealth = Mathf.Round (transform.GetComponent<vCharacter> ().currentHealth);
}
}
}
}
|
|
|
Post by Chronicman on Dec 11, 2016 0:47:35 GMT
Nice work!
|
|
|
Post by jrackley on Dec 11, 2016 1:28:30 GMT
Thanks Chronicman, I see a few areas where I can write it better, but hey it works!, lol!
|
|
arkas
Junior vMember
Posts: 40
|
Post by arkas on Dec 11, 2016 2:28:20 GMT
thanks
|
|
|
Post by sickscore on Dec 19, 2016 22:25:06 GMT
Thanks for this script, saved me a good amount of time Let me post a slightly optimized version with less component calls. *Edit and updated by Invector to work with new versions. using UnityEngine; using Invector.vCharacterController;
public class vFallDamageManager : MonoBehaviour { public float damageThreshold = 3f; public float damageMultiplier = 2.85f;
vThirdPersonController vController;
float startYPos, endYPos; bool firstCall = true; bool damaged = false;
void Awake() { vController = GetComponent<vThirdPersonController>(); }
void Update() { if (!vController.isGrounded) { if (transform.position.y > startYPos) { firstCall = true; } if (firstCall) { firstCall = false; damaged = true; startYPos = transform.position.y; } } else { endYPos = transform.position.y; if (damaged && (startYPos - endYPos) > damageThreshold) { damaged = false; firstCall = true;
float amount = startYPos - endYPos - damageThreshold; float damage = (damageMultiplier == 0f) ? amount : amount * damageMultiplier; vController.ChangeHealth(-Mathf.RoundToInt(damage)); } } } }
|
|
|
Post by jrackley on Dec 20, 2016 1:46:11 GMT
Thanks sickscore, I have been meaning to repost a better version, but have been busy at work, thanks for hooking it up!
|
|
|
Post by kajamaz on Jan 12, 2017 14:48:30 GMT
Does the current controller not have fall dmg?
|
|
|
Post by jrackley on Jan 12, 2017 15:26:24 GMT
Does the current controller not have fall dmg? Not by default, but all you have to do is attach this script to the player and you will have it.
|
|
|
Post by kajamaz on Jan 12, 2017 16:47:16 GMT
Does the current controller not have fall dmg? Not by default, but all you have to do is attach this script to the player and you will have it. Ohh shweet! Thanks a ton guys! Would you advise the more optimised script one of the people replied with?
|
|
|
Post by jrackley on Jan 12, 2017 18:35:50 GMT
Yes I would use the optimized one for sure
|
|
|
Post by snooppy on Sept 29, 2017 9:04:03 GMT
Another variant (add this script to "LandHigh" animator's node):
using System.Collections; using System.Collections.Generic; using UnityEngine; using Invector.CharacterController;
public class FallDamageRule : StateMachineBehaviour {
override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { float landSpeed = animator.GetFloat("VerticalVelocity");
float damage = (landSpeed + 21f) * GlobasConst.FallDamageModifier;
if (damage >= 0) return;
vThirdPersonController vController = animator.GetComponent<vThirdPersonController>();
damage *= vController.maxHealth / 100;
var dam = new vDamage(Mathf.RoundToInt(-damage)); dam.sender = animator.transform; dam.ignoreDefense = true; dam.attackName = "FallDamage"; dam.hitPosition = new Vector3(animator.transform.position.x, animator.transform.position.y + 0.2f, animator.transform.position.z); vController.TakeDamage(dam); } }
|
|
|
Post by Frosted Brain on Apr 15, 2018 14:07:52 GMT
Thanks for this script, saved me a good amount of time Let me post a slightly optimized version with less component calls. using UnityEngine; using System.Collections; using Invector.CharacterController;
public class vFallDamageManager : MonoBehaviour { public float damageThreshold = 3f; public float damageMultiplier = 2.85f;
vThirdPersonController vController;
float startYPos, endYPos; bool firstCall = true; bool damaged = false;
void Awake () { vController = GetComponent<vThirdPersonController> (); }
void Update () { if (!vController.isGrounded) { if (transform.position.y > startYPos) { firstCall = true; } if (firstCall) { firstCall = false; damaged = true; startYPos = transform.position.y; } } else { endYPos = transform.position.y; if (damaged && (startYPos - endYPos) > damageThreshold) { damaged = false; firstCall = true;
float amount = startYPos - endYPos - damageThreshold; float damage = (damageMultiplier == 0f) ? amount : amount * damageMultiplier; vController.currentHealth -= Mathf.Round (damage); } } } }
I get an error after updating the invector namespace
|
|
|
Post by newbie on May 19, 2018 13:34:10 GMT
some one create Wall Run
|
|
azul
Junior vMember
Posts: 38
|
Post by azul on Oct 14, 2019 17:47:57 GMT
Thank you so much for the vFallDamageManager script! It's working great as intended, however, I have a unique case in where it conflicts with another script that I'm using. In my game, I have buildings in where the player can enter through a door and 'teleport' to the roof after a few seconds (to simulate going inside a building, climbing up the stairs, and reaching the roof). The player can also 'teleport' back down to the main floor, however, when I use this along with the fall damage script, it damages the player after teleporting down since it thinks the player fell (which obviously isn't true in this case). How would I handle this situation so that whenever I teleport, it temporarily disables the vFallDamageManager? Also, the vFallDamageManager doesn't seem to work with HUD elements such as the damageImage you see when your taking fire from enemies or with OnRecieveDamage (vDamage) events. I have attached the Teleport script bellow. I'm using Sickscore's version of the script by the way. Thanks in advance!
using UnityEngine; using System.Collections;
public class Teleport : MonoBehaviour { public GameObject ui; public GameObject uiEnter; public GameObject objToTP; public Transform tpLoc; public AudioClip SoundToPlay; AudioSource audio; public float Volume; void Start() { ui.SetActive(false); audio = GetComponent<AudioSource>(); }
void OnTriggerStay(Collider other) { ui.SetActive(true); if ((other.gameObject.tag == "Player") && Input.GetKeyDown(KeyCode.T)) { StartCoroutine(Test(other.gameObject)); uiEnter.SetActive(true); audio.PlayOneShot(SoundToPlay,Volume); } } IEnumerator Test(GameObject go) { yield return new WaitForSeconds(6f); objToTP.transform.position = tpLoc.transform.position;
} void OnTriggerExit() { ui.SetActive(false); } }
|
|
|
Post by Yort_Draeb on Oct 20, 2019 20:26:36 GMT
Thank you so much for the vFallDamageManager script! It's working great as intended, however, I have a unique case in where it conflicts with another script that I'm using. In my game, I have buildings in where the player can enter through a door and 'teleport' to the roof after a few seconds (to simulate going inside a building, climbing up the stairs, and reaching the roof). The player can also 'teleport' back down to the main floor, however, when I use this along with the fall damage script, it damages the player after teleporting down since it thinks the player fell (which obviously isn't true in this case). How would I handle this situation so that whenever I teleport, it temporarily disables the vFallDamageManager? Also, the vFallDamageManager doesn't seem to work with HUD elements such as the damageImage you see when your taking fire from enemies or with OnRecieveDamage (vDamage) events. I have attached the Teleport script bellow. I'm using Sickscore's version of the script by the way. Thanks in advance! using UnityEngine; using System.Collections;
public class Teleport : MonoBehaviour { public GameObject ui; public GameObject uiEnter; public GameObject objToTP; public Transform tpLoc; public AudioClip SoundToPlay; AudioSource audio; public float Volume; void Start() { ui.SetActive(false); audio = GetComponent<AudioSource>(); }
void OnTriggerStay(Collider other) { ui.SetActive(true); if ((other.gameObject.tag == "Player") && Input.GetKeyDown(KeyCode.T)) { StartCoroutine(Test(other.gameObject)); uiEnter.SetActive(true); audio.PlayOneShot(SoundToPlay,Volume); } } IEnumerator Test(GameObject go) { yield return new WaitForSeconds(6f); objToTP.transform.position = tpLoc.transform.position;
} void OnTriggerExit() { ui.SetActive(false); } } Could create another book or adjust your code to use one already created Bool canBeDamaged =true; Then whenever your teleport is called make it false. Then adjust your fall code to If(canBeDamaged) {**insert fall damage code**} Else return;
|
|