204 lines
6.1 KiB
C#
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;
|
|
}
|
|
} |