/// <summary> /// Check a raycast hit, and call appropriate event handlers /// </summary> /// <param name="scanbox"></param> /// <param name="dHealth"></param> /// <param name="hit"></param> /// <param name="OnHit"></param> private static void ApplyCastHit(Scanbox scanbox, HitscanType type, DeltaHealth dHealth, CEvent cEvent, RaycastHit hit, Action <Scanbox, RaycastHit> OnHit) { if (scanbox != null) { scanbox.AcceptScan(type, dHealth, cEvent); } OnHit?.Invoke(scanbox, hit); }
public Hitscan(Hitscan copy) { hitscanType = copy.hitscanType; dmgType = copy.dmgType; range = copy.range; damage = copy.damage; lifetime = copy.lifetime; startPosition = copy.startPosition; direction = copy.direction; }
public void AcceptScan(HitscanType type, DeltaHealth dHealth, CEvent cEvent) { if (hasHurtbox && (type & HitscanType.damage) == HitscanType.damage) { hurtbox.ApplyDeltaHealth(dHealth); } if (hasEventbox && (type & HitscanType.eventScan) == HitscanType.eventScan) { eventbox.AcceptEvent(cEvent); } }
/// <summary> /// Cast a hitscan over the scene /// </summary> /// <param name="ray">The ray to cast</param> /// <param name="dHealth">The Delta Health object to use for damage/healing</param> /// <param name="distance">The distance to apply the hitscan over. Default, infinity</param> /// <param name="layerMask">The layers to cast the hitscan over. Default all</param> /// <param name="penetrate">This hitscan penetrates walls. Default false</param> /// <param name="targets">The targets to cast the hitscan over. Default, whole scene</param> /// <param name="OnHit">The function to call on a hit. Default None</param> public static void Cast( Ray ray, HitscanType type, DeltaHealth dHealth = null, CEvent cEvent = null, float distance = Mathf.Infinity, int layerMask = -1, bool penetrate = false, Collider[] targets = null, Action <Scanbox, RaycastHit> OnHit = null ) => Cast(ray.origin, ray.direction, type, dHealth, cEvent, distance, layerMask, penetrate, targets, OnHit);
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { SerializedProperty hitscanType = property.FindPropertyRelative("hitscanType"); HitscanType hittype = (HitscanType)hitscanType.intValue; bool doesntNeedExtraLine = hittype == HitscanType.Raycast || hittype == HitscanType.OverlapSphere; bool needsExtraExtra = hittype == HitscanType.CapsuleCast || hittype == HitscanType.BoxCast; bool isOverlap = hittype.IsOverlap(); return((5 * SPACING + PAD * 2) + (isOverlap ? SPACING : 0) + (doesntNeedExtraLine ? 0 : (needsExtraExtra ? SPACING * 2 : SPACING)) + (hittype.IsCast() ? SPACING : 0)); }
int IndexFromHitscanType(HitscanType hitscanType) { switch (hitscanType) { case HitscanType.Arcannon: return(0); case HitscanType.Superlaser: return(1); default: return(0); } }
/// <summary> /// Cast a hitscan over the scene /// </summary> /// <param name="origin">The point to cast the hitscan from</param> /// <param name="direction">The direction to cast the hitscan</param> /// <param name="dHealth">The Delta Health object to use for damage/healing</param> /// <param name="distance">The distance to apply the hitscan over. Default, infinity</param> /// <param name="layerMask">The layers to cast the hitscan over. Default all</param> /// <param name="penetrate">This hitscan penetrates walls. Default false</param> /// <param name="targets">The targets to cast the hitscan over. Default, whole scene</param> /// <param name="OnHit">The function to call on a hit. Default None</param> public static void Cast(Vector3 origin, Vector3 direction, HitscanType type, DeltaHealth dHealth = null, CEvent cEvent = null, float distance = Mathf.Infinity, int layerMask = -1, bool penetrate = false, Collider[] targets = null, Action <Scanbox, RaycastHit> OnHit = null) { if (penetrate) { if (targets == null) { foreach (var hit in Physics.RaycastAll(origin, direction, distance, layerMask)) { ApplyCastHit(type, dHealth, cEvent, hit, OnHit); } } else { foreach (var coll in targets) { RaycastHit hit; if (coll.Raycast(new Ray(origin, direction), out hit, distance)) { ApplyCastHit(type, dHealth, cEvent, hit, OnHit); } } } } else { if (targets == null) { RaycastHit hit; if (Physics.Raycast(origin, direction, out hit, distance, layerMask)) { ApplyCastHit(type, dHealth, cEvent, hit, OnHit); } } else { foreach (var coll in targets) { RaycastHit hit; if (coll.Raycast(new Ray(origin, direction), out hit, distance)) { ApplyCastHit(type, dHealth, cEvent, hit, OnHit); } break; } } } }
public override void OnGUI(Rect r, SerializedProperty _property, GUIContent _label) { r.yMax -= 6; // Draw leading black separator r.yMin += 2; EditorGUI.DrawRect(new Rect(r) { height = 2 }, new Color(.15f, .15f, .15f)); r.yMin += 4; EditorGUI.BeginProperty(r, GUIContent.none, _property); int startingIndent = EditorGUI.indentLevel; SerializedProperty layerMask = _property.FindPropertyRelative("layerMask"); SerializedProperty useOffset = _property.FindPropertyRelative("useOffset"); SerializedProperty offset1 = _property.FindPropertyRelative("offset1"); SerializedProperty offset2 = _property.FindPropertyRelative("offset2"); SerializedProperty hitscanType = _property.FindPropertyRelative("hitscanType"); SerializedProperty distance = _property.FindPropertyRelative("distance"); SerializedProperty radius = _property.FindPropertyRelative("radius"); SerializedProperty halfExtents = _property.FindPropertyRelative("halfExtents"); SerializedProperty orientation = _property.FindPropertyRelative("orientation"); SerializedProperty nearestOnly = _property.FindPropertyRelative("nearestOnly"); HitscanType hitscantype = (HitscanType)hitscanType.intValue; EditorGUI.LabelField(new Rect(r) { height = FLDHGHT }, _label); r.yMin += SPACING; GUI.Box(r, GUIContent.none, (GUIStyle)"HelpBox"); r.xMin += PAD; r.xMax -= PAD; r.height = FLDHGHT; r.y += PAD; EditorGUI.BeginChangeCheck(); EditorGUI.PropertyField(r, hitscanType); r.y += SPACING; EditorGUI.PropertyField(r, layerMask); // Show dist for any of the casts if (hitscantype.IsCast()) { r.y += SPACING; EditorGUI.PropertyField(r, distance); } r.y += SPACING; EditorGUI.PropertyField(r, nearestOnly); // Radius types if (hitscantype.UsesRadius()) { r.y += SPACING; EditorGUI.PropertyField(r, radius); } // Offset (all but capsule) if (!hitscantype.IsCapsule()) { r.y += SPACING; EditorGUI.LabelField(new Rect(r.xMin + 18, r.y, 100, FLDHGHT), new GUIContent("Offset")); EditorGUI.PropertyField(new Rect(r.xMin, r.y, 32, FLDHGHT), useOffset, GUIContent.none); if (useOffset.boolValue) { EditorGUI.PropertyField(new Rect(r.xMin + 100, r.y, r.width - 100, FLDHGHT), offset1, GUIContent.none); } } // Show Point1 and Point2 for capsule. if (hitscantype.IsCapsule()) { r.y += SPACING; EditorGUI.LabelField(new Rect(r.xMin, r.y, 100, FLDHGHT), new GUIContent("Offset1:")); EditorGUI.PropertyField(new Rect(r.xMin + 100, r.y, r.width - 100, FLDHGHT), offset1, GUIContent.none); r.y += SPACING; EditorGUI.LabelField(new Rect(r.xMin, r.y, 100, FLDHGHT), new GUIContent("Offset2:")); EditorGUI.PropertyField(new Rect(r.xMin + 100, r.y, r.width - 100, FLDHGHT), offset2, GUIContent.none); } else if (hitscantype.IsBox()) { r.y += SPACING; EditorGUI.LabelField(new Rect(r.xMin, r.y, 100, FLDHGHT), new GUIContent("Half Extents:")); EditorGUI.PropertyField(new Rect(r.xMin + 100, r.y, r.width - 100, FLDHGHT), halfExtents, GUIContent.none); r.y += SPACING; EditorGUI.LabelField(new Rect(r.xMin, r.y, 100, FLDHGHT), new GUIContent("Orientation:")); EditorGUI.PropertyField(new Rect(r.xMin + 100, r.y, r.width - 100, FLDHGHT), orientation, GUIContent.none); } /// Not sure this is actually needed. bool haschanged = EditorGUI.EndChangeCheck(); if (haschanged) { EditorUtility.SetDirty(_property.serializedObject.targetObject); } EditorGUI.EndProperty(); // Draw closing black separator r.xMin -= PAD; r.xMax += PAD; EditorGUI.DrawRect(new Rect(r) { y = r.y + 26, height = 2 }, new Color(.15f, .15f, .15f)); }
public static int GenericCastNonAlloc(this Transform srcT, Collider[] hits, RaycastHit[] rayhits, float distance, float radius, int mask, Quaternion orientation, bool useOffset, Vector3 offset1, Vector3 offset2, HitscanType hitscanType) { int hitcount; Vector3 srcPos = (useOffset) ? (srcT.position + srcT.TransformDirection(offset1)) : srcT.position; switch (hitscanType) { case HitscanType.Raycast: hitcount = Physics.RaycastNonAlloc(new Ray(srcPos, srcT.forward), rayhits, distance, mask); break; case HitscanType.SphereCast: hitcount = Physics.SphereCastNonAlloc(new Ray(srcPos, srcT.forward), radius, rayhits, distance, mask); break; case HitscanType.BoxCast: hitcount = Physics.BoxCastNonAlloc(srcPos, offset2, srcT.forward, rayhits, orientation, distance, mask); break; case HitscanType.CapsuleCast: hitcount = Physics.CapsuleCastNonAlloc(srcT.TransformPoint(offset1), srcT.TransformPoint(offset2), radius, srcT.forward, rayhits, distance, mask); break; case HitscanType.OverlapSphere: hitcount = Physics.OverlapSphereNonAlloc(srcPos, radius, hits, mask); break; case HitscanType.OverlapBox: hitcount = Physics.OverlapBoxNonAlloc(srcPos, offset2, hits, orientation, mask); break; case HitscanType.OverlapCapsule: hitcount = Physics.OverlapCapsuleNonAlloc(srcT.TransformPoint(offset1), srcT.TransformPoint(offset2), radius, hits, mask); break; default: hitcount = 0; break; } // Convert the raycasthits to colliders[] if this was a cast and not an overlap if (hitscanType.IsCast()) { for (int i = 0; i < hitcount; i++) { hits[i] = rayhits[i].collider; } } return(hitcount); }
public static bool IsCapsule(this HitscanType hitscanType) { return((hitscanType == HitscanType.CapsuleCast) || (hitscanType == HitscanType.OverlapCapsule)); }
public static bool IsBox(this HitscanType hitscanType) { return((hitscanType == HitscanType.BoxCast) || (hitscanType == HitscanType.OverlapBox)); }
public static bool UsesRadius(this HitscanType hitscanType) { return(hitscanType == HitscanType.SphereCast || hitscanType == HitscanType.CapsuleCast || hitscanType == HitscanType.OverlapSphere || hitscanType == HitscanType.OverlapCapsule); }
public static bool IsOverlap(this HitscanType hitscanType) { return((int)hitscanType > 3); }
public static bool IsCast(this HitscanType hitscanType) { return((int)hitscanType < 4); }
/// <summary> /// Check a raycast hit, and call appropriate event handlers. /// </summary> /// <param name="dHealth"></param> /// <param name="hit"></param> /// <param name="OnHit"></param> private static void ApplyCastHit(HitscanType type, DeltaHealth dHealth, CEvent cEvent, RaycastHit hit, Action <Scanbox, RaycastHit> OnHit) { ApplyCastHit(hit.collider.GetComponent <Scanbox>(), type, dHealth, cEvent, hit, OnHit); }