Files
DeviantMobile-Rohan/Assets/New Lowpoly Models/Scripts/CharacterHitboxAutoSetup.cs
2026-06-26 22:41:39 +05:30

204 lines
6.1 KiB
C#

using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
[ExecuteAlways]
public class CharacterHitboxAutoSetup : MonoBehaviour
{
[Header("References")]
[SerializeField] private Animator animator;
[SerializeField] private EnemyCombat enemyCombat;
[Header("Hitbox Settings")]
[SerializeField] private Vector3 handHitboxSize = new Vector3(0.35f, 0.35f, 0.35f);
[SerializeField] private Vector3 footHitboxSize = new Vector3(0.45f, 0.35f, 0.45f);
[SerializeField] private float punchDamage = 10f;
[SerializeField] private float kickDamage = 15f;
[Header("Hurtbox Settings")]
[SerializeField] private Vector3 headHurtboxSize = new Vector3(0.35f, 0.35f, 0.35f);
[SerializeField] private Vector3 bodyHurtboxSize = new Vector3(0.55f, 0.75f, 0.35f);
[SerializeField] private Vector3 legHurtboxSize = new Vector3(0.35f, 0.6f, 0.35f);
[Header("Optional")]
[SerializeField] private GameObject bloodVFXPrefab;
[ContextMenu("Auto Setup Hitboxes And Hurtboxes")]
public void AutoSetup()
{
FindReferences();
if (animator == null)
{
Debug.LogError("Animator not found on " + gameObject.name);
return;
}
if (!animator.isHuman)
{
Debug.LogError("Animator is not Humanoid. Set model Rig Type to Humanoid first: " + gameObject.name);
return;
}
SetupHitboxes();
SetupHurtboxes();
#if UNITY_EDITOR
EditorUtility.SetDirty(gameObject);
if (enemyCombat != null)
EditorUtility.SetDirty(enemyCombat);
#endif
Debug.Log("Hitboxes and hurtboxes setup completed for " + gameObject.name);
}
private void FindReferences()
{
if (animator == null)
animator = GetComponentInChildren<Animator>();
if (enemyCombat == null)
enemyCombat = GetComponent<EnemyCombat>();
if (enemyCombat == null)
enemyCombat = gameObject.AddComponent<EnemyCombat>();
}
private void SetupHitboxes()
{
enemyCombat.rightHandPunchHitbox = CreateHitbox(
"RightHandPunchHitbox",
HumanBodyBones.RightHand,
handHitboxSize,
punchDamage
);
enemyCombat.leftHandPunchHitbox = CreateHitbox(
"LeftHandPunchHitbox",
HumanBodyBones.LeftHand,
handHitboxSize,
punchDamage
);
enemyCombat.rightFootKickHitbox = CreateHitbox(
"RightFootKickHitbox",
HumanBodyBones.RightFoot,
footHitboxSize,
kickDamage
);
enemyCombat.leftFootKickHitbox = CreateHitbox(
"LeftFootKickHitbox",
HumanBodyBones.LeftFoot,
footHitboxSize,
kickDamage
);
//enemyCombat.DisableAll();
}
private GameObject CreateHitbox(string objectName, HumanBodyBones bone, Vector3 size, float damage)
{
Transform boneTransform = animator.GetBoneTransform(bone);
if (boneTransform == null)
{
Debug.LogWarning("Missing bone: " + bone + " on " + gameObject.name);
return null;
}
GameObject hitboxObject = GetOrCreateChild(boneTransform, objectName);
BoxCollider boxCollider = hitboxObject.GetComponent<BoxCollider>();
if (boxCollider == null)
boxCollider = hitboxObject.AddComponent<BoxCollider>();
boxCollider.isTrigger = true;
boxCollider.size = size;
boxCollider.center = Vector3.zero;
Hitbox hitbox = hitboxObject.GetComponent<Hitbox>();
if (hitbox == null)
hitbox = hitboxObject.AddComponent<Hitbox>();
hitbox.damage = damage;
hitbox.bloodVFXPrefab = bloodVFXPrefab;
int hitboxLayer = LayerMask.NameToLayer("Hitbox");
if (hitboxLayer != -1)
hitboxObject.layer = hitboxLayer;
hitboxObject.SetActive(false);
return hitboxObject;
}
private void SetupHurtboxes()
{
CreateHurtbox("HeadHurtbox", HumanBodyBones.Head, headHurtboxSize, "Head");
CreateHurtbox("ChestHurtbox", HumanBodyBones.Chest, bodyHurtboxSize, "Body");
CreateHurtbox("HipsHurtbox", HumanBodyBones.Hips, bodyHurtboxSize, "Body");
CreateHurtbox("LeftUpperLegHurtbox", HumanBodyBones.LeftUpperLeg, legHurtboxSize, "Legs");
CreateHurtbox("RightUpperLegHurtbox", HumanBodyBones.RightUpperLeg, legHurtboxSize, "Legs");
}
private GameObject CreateHurtbox(string objectName, HumanBodyBones bone, Vector3 size, string bodyPart)
{
Transform boneTransform = animator.GetBoneTransform(bone);
if (boneTransform == null)
{
Debug.LogWarning("Missing bone: " + bone + " on " + gameObject.name);
return null;
}
GameObject hurtboxObject = GetOrCreateChild(boneTransform, objectName);
BoxCollider boxCollider = hurtboxObject.GetComponent<BoxCollider>();
if (boxCollider == null)
boxCollider = hurtboxObject.AddComponent<BoxCollider>();
boxCollider.isTrigger = true;
boxCollider.size = size;
boxCollider.center = Vector3.zero;
Hurtbox hurtbox = hurtboxObject.GetComponent<Hurtbox>();
if (hurtbox == null)
hurtbox = hurtboxObject.AddComponent<Hurtbox>();
hurtbox.bodyPart = bodyPart;
int hurtboxLayer = LayerMask.NameToLayer("Hurtbox");
if (hurtboxLayer != -1)
hurtboxObject.layer = hurtboxLayer;
hurtboxObject.SetActive(true);
return hurtboxObject;
}
private GameObject GetOrCreateChild(Transform parent, string objectName)
{
Transform existing = parent.Find(objectName);
if (existing != null)
return existing.gameObject;
GameObject newObject = new GameObject(objectName);
newObject.transform.SetParent(parent);
newObject.transform.localPosition = Vector3.zero;
newObject.transform.localRotation = Quaternion.identity;
newObject.transform.localScale = Vector3.one;
return newObject;
}
}