/// <summary> /// spawns the footprint effect resulting from the 'impactEvent' + 'surface'. /// 'footprintDirection' should be the forward vector of the foot. if /// 'footprintFlip' is true, the decal's X-scale will be inverted. if /// 'footprintVerifyGroundContact' is true (not recommended) the decal /// system will perform four extra raycasts per footstep (!) to verify /// ground contact /// </summary> public static void SpawnFootprintEffect(RaycastHit hit, vp_SurfaceType surface, vp_ImpactEvent impactEvent, Vector3 footprintDirection, bool footprintFlip, bool footprintVerifyGroundContact = false, AudioSource audioSource = null, bool allowDecal = true) { // set footprint flags on the vp_SurfaceEffect system before spawning vp_SurfaceEffect.FootprintDirection = footprintDirection; vp_SurfaceEffect.FootprintFlip = footprintFlip; vp_SurfaceEffect.FootprintVerifyGroundContact = footprintVerifyGroundContact; SpawnEffect(hit, impactEvent, surface, audioSource, allowDecal); vp_SurfaceEffect.FootprintDirection = vp_SurfaceEffect.NO_DIRECTION; vp_SurfaceEffect.FootprintVerifyGroundContact = false; }
/// <summary> /// returns the surface effect stored in 'surfaceType' under 'impact' /// (or null if no match) /// </summary> protected static vp_SurfaceEffect GetPrimaryEffect(vp_SurfaceType surfaceType, vp_ImpactEvent impact) { Dictionary <vp_ImpactEvent, vp_SurfaceEffect> impacts = GetImpactFXDictionary(surfaceType); if (impacts == null) { return(null); } if (impacts.Count == 0) { return(null); } vp_SurfaceEffect fx; impacts.TryGetValue(impact, out fx); return(fx); }
/// <summary> /// spawns the effect resulting from 'impactEvent' + 'surface'. if 'surface' /// is null, derives it from the raycast hit /// </summary> public static bool SpawnEffect(RaycastHit hit, vp_ImpactEvent impact, vp_SurfaceType surface = null, AudioSource audioSource = null, bool allowDecal = true) { // 'surface' is optional. if we don't already know it we try to derive it from the RaycastHit if (surface == null) { surface = GetSurfaceType(hit); // if this returns null we will rely on fallbacks } if (allowDecal) { // a surface identifier can always force 'allowdecal' to false allowDecal = AllowsDecals(hit.collider); // test against stretched decals on non-uniform objects if (allowDecal && // if decal is allowed ... (vp_DecalManager.Instance != null) && // ... and we have a decalmanager ... !vp_DecalManager.Instance.AllowStretchedDecals && // ... which is concered about stretching ... !hit.transform.gameObject.isStatic) // ... then unless the target is static ... (decals don't get childed to static objects so there won't be stretching) { // ... then only allow decal in case the object has uniform scale! // (but use an epsilon of '0.00001' in case there is a slight but insignificant scale difference) allowDecal = vp_MathUtility.IsUniform(hit.transform.localScale, 0.00001f); } } vp_SurfaceEffect fx = GetResultingEffect(impact, surface, ref allowDecal); if (fx == null) { return(false); } if (allowDecal) { fx.SpawnWithDecal(hit, audioSource); } else { fx.Spawn(hit, audioSource); } return(true); }
/// <summary> /// arrives at the most suitable surface effect based on one combo /// of surfaceType + impactEvent (or predefined fallbacks) plus the /// merged 'allowDecal' settings (from the calling method, any surface /// identifiers and the effect itself) /// </summary> protected static vp_SurfaceEffect GetResultingEffect(vp_ImpactEvent impact, vp_SurfaceType surface, ref bool allowDecals) { m_UsingFallbackImpact = false; m_UsingFallbackSurface = false; // if no IMPACT EVENT was provided - attempt to use fallback impact if ((impact == null) && (Instance != null)) { impact = Instance.Fallbacks.ImpactEvent; m_UsingFallbackImpact = true; } if (impact == null) { return(null); } // if no SURFACE TYPE could be found - attempt to use fallback surface if ((surface == null) && (Instance != null)) { surface = Instance.Fallbacks.SurfaceType; m_UsingFallbackSurface = true; } if (surface == null) { return(null); } if (surface.ImpactFX == null) { return(null); } if (surface.ImpactFX.Count == 0) { return(null); } vp_SurfaceEffect fx = GetPrimaryEffect(surface, impact); // if fx is null here and we are not using a fallback surface, it means the // level surface did not contain our impact event: so use fallback surface if ((fx == null) && !m_UsingFallbackSurface && (Instance != null)) { surface = Instance.Fallbacks.SurfaceType; fx = GetPrimaryEffect(surface, impact); } // if fx is null here, the detected surface does not recognize the impact // event, so try again with the SurfaceManager's fallback impact event // (this can solve cases where the surface is the fallback surface and the // impact type is a new, unknown impact type that has not been assigned to // anything) if (fx == null) { fx = GetPrimaryEffect(surface, Instance.Fallbacks.ImpactEvent); } // if fx is null here, we have nothing to work with: abort if (fx == null) { return(null); } // we have an effect! determine if it can be spawned with a decal // (global fallbacks are allowed to override 'allowDecals') if (allowDecals && (fx.Decal.m_Prefabs.Count > 0)) { if (m_UsingFallbackSurface || m_UsingFallbackImpact) { allowDecals = Instance.Fallbacks.AllowDecals; } } else { allowDecals = false; // spawn with sounds & objects only } return(fx); }
/// <summary> /// spawns the footprint effect resulting from 'impactEvent' + the surface /// detected at the raycasthit. 'footprintDirection' should be the forward /// vector of the foot. if 'footPrintFlip' is true, the decal's X-scale /// will be inverted /// </summary> public static void SpawnFootprintEffect(RaycastHit hit, vp_ImpactEvent impactEvent, Vector3 footprintDirection, bool footprintFlip, bool footprintVerifyGroundContact = false, AudioSource audioSource = null, bool allowDecal = true) { SpawnFootprintEffect(hit, null, impactEvent, footprintDirection, footprintFlip, footprintVerifyGroundContact, audioSource, allowDecal); }
/// <summary> /// spawns the effect resulting from an impactEvent and the surface /// detected at the raycasthit /// </summary> public static bool SpawnEffect(RaycastHit hit, vp_ImpactEvent impactEvent, AudioSource audioSource, bool allowDecal = true) { return(SpawnEffect(hit, impactEvent, null, audioSource, allowDecal)); }