I want to make realistic greande simular to real life. It mustn't throw people around it will just hurt, kill or won't do anything to people in 20 meter range. I have no idea about this topic how should I do it? My game is arma 3 + insurgency kinda game and it is multiplayer.
Do a Physics.OverlapSphere and check wich players are inside range. Then do a raycast to each transform holding a hit box. Its not perfect but pretty good
An easier route could be that you have a SphereCollider flagged as Trigger attached to your grenade (as a child). Then when you throw it and it time passes you enable that collider's gameobject, and any thing it overlaps gets damaged (using the OnTriggerEnter message/event).
And follow with the raycast. Note I call this easier from a design perspective. It allows you to have a visualization of the grenade hit area, and allows you to write a reusable 'overlap weapon' for AOE's of any shape by replacing the collider.
In this case its just a radius, but you could make a custom gizmo if you have many explosives to configure. Talking about explosives, @BarbarZahoCan, I would use composition over inheritance here. If you have a base grenade class with explosive behaviour, you cant re use it for a bomb or c4. So create a component that takes care of the explosive parts of the grenade
I make really few weapons but I try to make them perfect instead of filling the game with clunky guns and equipments
How did it went? Here is our code if it can help Code (CSharp): namespace Weapons.Explosives { public class Explosive : MonoBehaviour { public Transform ExplosionCenter; public GameObject ExplosionPrefab; private float ExplosionRadius = 15f; private float InjuryRadius = 13f; private float FatalRadius = 6.5f; private NetworkTrackedObject network; protected void Awake() { if(ExplosionCenter == null) ExplosionCenter = transform; network = GetComponent<NetworkTrackedObject>(); network.RegisterRpc(this); } public void RequestPerformExplosion() { var hits = GetHits(); var avatarIds = hits.Select(x => x.Player.NetworkedId).ToArray(); var damage = hits.Select(x => x.Damage).ToArray(); var diedStatus = hits.Select(x => x.Died).ToArray(); //Order here is important, first send to client then call local, becasue some listeners of ExplodedEvent performs delete (handgrenade) and that will make the networkcode ignore RPC because of deleted local gameobject (maybe candidate for refactor?) network.RPC("PerformExplosion", NetworkReceivers.Others, ExplosionCenter.position, avatarIds, damage, diedStatus); PerformExplosion(ExplosionCenter.position, avatarIds, damage, diedStatus); } [BRPC] public void PerformExplosion(Vector3 explosionCenter, ulong[] avatarIds, float[] damage, bool[] diedStatus) { var avatars = avatarIds .Select(id => AvatarBase.AvatarBases[id]) .ToList(); var grenadeHits = new List<GrenadeHit>(); for(int i = 0; i < avatars.Count; i++) { grenadeHits.Add(new GrenadeHit(avatars[i], damage[i], diedStatus[i])); } PerformLocalExplosion(explosionCenter, grenadeHits); network.interactable.Publish(new ExplodedEvent()); //TODO: We should fix so not only NVRInteractibles can fire scoped events } private IEnumerable<GrenadeHit> GetHits() { var avatars = Physics.OverlapSphere(ExplosionCenter.position, ExplosionRadius, LayerMask.GetMask(Layers.Player)) .Select(x => AvatarBase.GetHitZone(x.transform).Avatar) .Distinct() .ToList(); var validHits = RemoveOccludedHits(avatars).ToList(); return validHits.Select(x => new GrenadeHit(x, GetDamage(x))).ToList(); } private IEnumerable<AvatarBase> RemoveOccludedHits(IEnumerable<AvatarBase> avatarsInRange) { foreach(var avatar in avatarsInRange) { var mask = LayerMask.GetMask(Layers.Ground, Layers.Default, Layers.WorldItems); foreach(var part in avatar.HitZones) { RaycastHit hitInfo; if(Physics.Raycast(new Ray(ExplosionCenter.position, part.transform.position - ExplosionCenter.position), out hitInfo, 30, mask)) { if(Vector3.Distance(ExplosionCenter.position, hitInfo.point) > Vector3.Distance(ExplosionCenter.position, part.transform.position)) { yield return avatar; break; } } else { yield return avatar; break; } } } } private float GetDamage(AvatarBase playerAvatar) { var distance = Vector3.Distance(playerAvatar.transform.position, ExplosionCenter.position); if(distance < FatalRadius) { return 110; } if(distance < InjuryRadius) { var damage = (1 - (distance - FatalRadius) / (InjuryRadius - FatalRadius)) * 95; return damage; } return 0; } private void PerformLocalExplosion(Vector3 explosionCenter, IEnumerable<GrenadeHit> hits) { var explosion = GameObject.Instantiate(ExplosionPrefab); explosion.transform.position = explosionCenter; foreach(var hit in hits) { hit.Player.RegisterExplosionHit(network.OwnerId, 800, InjuryRadius, ExplosionCenter.position, hit.Damage, hit.Died); } } }
I am not on grenade right now but looks like it is easy. I am polishing the animations for now grenade is optional I have kind of a milestone after that I will add the grenade probably becouse it is a really important factor in real life firefights and I want my game to feel really hardcore and realistic. Thank you for all of your help
Btw I think you should have some force effect on the ragdolls, but don't over do it, here is how it looks in our game
lmao I will add some ragdoll effects but it will be so little that it will only be able to move limbs a little