Don't destroy the gameobject - using again Instantiate you unnecessarily workload memory. Create hit gameobject on Awake or Start function end hide it using gameObject.SetActive(false); When hit object will be need just send SetActive(true) and will be show. Hide object after collision is simple so I don't explained. To active object again I wouldn't use WaitForSeconds(); only something related with animation. Maybe when animation is ended?! Code (csharp): if ( !animation.IsPlaying("hitobject")) // when anim with collider will finish { hit.SetActive(true); }
I not browsed your script, I only answered the question. What you don't understand? Let's start form load scene: Your character have sword with cube collider right?! And the cube should be hide yes?
yes there is a cube on my players sword, i have animated it with the sword in maya when it hits the player i want it only hit once then disable itself and go back on after a moment or two
Yeah I get what @rchmiel is saying. What he's saying is just to make a reference to the collider and turn it off, then turn it on again. He was also saying that you don't need to do the Instantiate(), and the Destroy(), as you can just do gameObject.SetActive(false), and gameObject.SetActive(true). But there's an easier way here Code (CSharp): private void CharacterHit() { StartCoroutine(TemporaryDisableHit(0.2f)); } private IEnumerator TemporaryDisableHit(float duration) { Collider objectsCollider = GetComponent<Collider>(); objectsCollider.enabled = false; yield return new WaitForSeconds(duration); objectsCollider.enabled = true; } Just call this Coroutine whenever you want to turn off the collider, and choose the amount of time.. The only thing you may want to change is the Collider in the Coroutine.. So maybe someobject.GetComponent<Collider>().. and change the duration, but asides that. All good .
how would i add what you said to this script or do i make new scirpt? what exactly am i puting in the script and where? lol so basicly everything i do not understand i did not make this script
So just reference the collider to whatever you want to, like I have with this Cube: Code (CSharp): public GameObject cube; private void CharacterHit() { StartCoroutine(TemporaryDisableHit(0.2f)); } private IEnumerator TemporaryDisableHit(float duration) { Collider objectsCollider = cube.GetComponent<Collider>(); objectsCollider.enabled = false; yield return new WaitForSeconds(duration); objectsCollider.enabled = true; }
so i put this on the cube itself? how does it now what its hitting like this is for my player that attacks enemy
Literally just like this: Code (CSharp): using UnityEngine; using System.Collections; public class BulletStatusC : MonoBehaviour { public int damage = 10; public int damageMax = 20; private int playerAttack = 5; public int totalDamage = 0; public int variance = 15; public string shooterTag = "Player"; [HideInInspector] public GameObject shooter; public Transform Popup; public GameObject hitEffect; public bool flinch = false; public bool penetrate = false; private int popDamage = 0; public enum AtkType { Physic = 0, Magic = 1, } public AtkType AttackType = AtkType.Physic; public enum Elementala { Normal = 0, Fire = 1, Ice = 2, Earth = 3, Lightning = 4, } public Elementala element = Elementala.Normal; void Start() { if (variance >= 100) { variance = 100; } if (variance <= 1) { variance = 1; } } public void Setting(int str, int mag, string tag, GameObject owner) { if (AttackType == AtkType.Physic) { playerAttack = str; } else { playerAttack = mag; } shooterTag = tag; shooter = owner; int varMin = 100 - variance; int varMax = 100 + variance; int randomDmg = Random.Range(damage, damageMax); totalDamage = (randomDmg + playerAttack) * Random.Range(varMin, varMax) / 100; } void OnTriggerEnter(Collider other) { StartCoroutine(TemporaryDisableHit(0.2f)); Transform dmgPop; Vector3 dir; //When Player Shoot at Enemy if (shooterTag == "Player" && other.tag == "Enemy") { dmgPop = (Transform)Instantiate(Popup, other.transform.position, transform.rotation); if (AttackType == AtkType.Physic) { popDamage = other.GetComponent<StatusC>().OnDamage(totalDamage, (int)element); } else { popDamage = other.GetComponent<StatusC>().OnMagicDamage(totalDamage, (int)element); } if (popDamage < 1) { popDamage = 1; } if (shooter && shooter.GetComponent<ShowEnemyHealthC>()) { shooter.GetComponent<ShowEnemyHealthC>().GetHP(other.GetComponent<StatusC>().maxHealth, other.gameObject, other.name); } dmgPop.GetComponent<DamagePopupC>().damage = popDamage; if (hitEffect) { Instantiate(hitEffect, transform.position, transform.rotation); } if (flinch) { dir = (other.transform.position - transform.position).normalized; other.GetComponent<StatusC>().Flinch(dir); } if (!penetrate) { Destroy(gameObject); } //When Enemy Shoot at Player } else if (shooterTag == "Enemy" && other.tag == "Player" || shooterTag == "Enemy" && other.tag == "Ally") { //dmgPop = (Transform)Instantiate(Popup, other.transform.position , transform.rotation); if (AttackType == AtkType.Physic) { popDamage = other.GetComponent<StatusC>().OnDamage(totalDamage, (int)element); } else { popDamage = other.GetComponent<StatusC>().OnMagicDamage(totalDamage, (int)element); } dmgPop = (Transform)Instantiate(Popup, transform.position, transform.rotation); if (popDamage < 1) { popDamage = 1; } dmgPop.GetComponent<DamagePopupC>().damage = popDamage; if (hitEffect) { Instantiate(hitEffect, transform.position, transform.rotation); } if (flinch) { dir = (other.transform.position - transform.position).normalized; other.GetComponent<StatusC>().Flinch(dir); } if (!penetrate) { Destroy(gameObject); } } } private IEnumerator TemporaryDisableHit(float duration) { Collider objectsCollider = GetComponent<Collider>(); objectsCollider.enabled = false; yield return new WaitForSeconds(duration); objectsCollider.enabled = true; } } Simples
Okay well actually that depends keepthachange. If you wanna disable the collider on the cube. Make a new script with a new 'OnTriggerEnter', put the script on the Cube, and then call the Coroutine like you've seen me do from in the OnTriggerEnter. If you want the player's Collider to turn off for that amount of time, add it to the player's script like I did above. So you'd just need to add this to a script new script and put it on the cube: Code (CSharp): using UnityEngine; using System.Collections; public class DisableCubeCollider : MonoBehaviour { [SerializeField] private float disableDuration; void OnTriggerEnter(Collider other) { StartCoroutine(TemporaryDisableHit(disableDuration)); } private IEnumerator TemporaryDisableHit(float duration) { Collider objectsCollider = GetComponent<Collider>(); objectsCollider.enabled = false; yield return new WaitForSeconds(duration); objectsCollider.enabled = true; } }
You don't made this script... so yes this is a problem I don't proposed WakeForSeconds() because if you change animation for longer/shorter you also must change "duration". If SetActive will be turn when animation is finished problem would not be.
i dont want player collider to turn off i just want the cubs collider to turn off after the sript has delt its damage and what ever it needed to do on collide and i also do not want it to deal damage to player or ally. atm it does not do anything to player or ally just enemy but it just does not turn off on collide and then back on.. idk if im saying this right or if im just not getting it right from you guys lol.
so what does this do, what you have added to script. cause i think this is what i might be looking for if im reading this right the Literally just like this: script lol
That totally depends on which object's collider you want to turn off. Does the thing you want to turn off have a tag? Is it the 'Enemy' tag? You need to point out which object's collider you want to turn off.
i want the cubes collider to turn( the cube i have my script on ) then back on after a moment or two so as soon as it hits the enemy(the enmeyis taged enemy) it turn off then turns back on after moment.
I think it's best for each attack to have an ID and only call the appropriate methods if the next attack ID is different.