Impact Actions
Impact Actions are objects containing a OnImpact function. They are usually in a list called ImpactActionGroup and can be found on most usable items and on projectiles.
The ImpactAction is initialized by a character and a CharacterItemAction. Impact Actions are not limited to Items. Anything can trigger an ImpactAction as long as there is an ImpactCollisionData.
Inspected Fields
Enabled
If the ImpactAction is not enabled it will not be invoked.
Delay
The impact can be delayed, this uses the Scheduler for delaying the function call.
Allow Multi Hits
In some cases impacts can be called by physics cast that happen every frame. Preventing multi hits will ensure only one impact happens until the impact action is reset.
Impact Callback Context
The OnImpact function takes in a ImpactCallbackContext parameter. The ImpactCallbackContext contains two main objects: the ImpactCollisionData and the ImpactDamageData.
Impact Collision Data
The Impact Collision Data contains all the information about the collision.
It contains the following properties:
uint m_SourceID; LayerMask m_LayerMask; RaycastHit m_RaycastHit; Vector3 m_ImpactPosition; GameObject m_ImpactGameObject; Rigidbody m_ImpactRigidbody; Collider m_ImpactCollider; Vector3 m_ImpactDirection; float m_ImpactStrength; IDamageTarget m_DamageTarget; IDamageSource m_DamageSource; Component m_SourceComponent; GameObject m_SourceGameObject; GameObject m_SourceOwner; GameObject m_SourceRootOwner; CharacterLocomotion m_SourceCharacterLocomotion; int m_HitCount; ListSlice<Collider> m_HitColliders; UsableAction m_SourceItemAction; SurfaceImpact m_SurfaceImpact;
It is usually initialized by a RaycastHit. In the example below the ShooterModule uses the ImpactCollisionData:
var impactData = m_ShootableImpactCallbackContext.ImpactCollisionData; impactData.Reset(); impactData.Initialize(); impactData.SetRaycast(closestRaycastHit); impactData.SetImpactSource(ShootableAction); { impactData.ImpactDirection = fireDirection; impactData.ImpactStrength = strength; } ShootableAction.OnFireImpact(m_ShootableImpactCallbackContext);
It can also be initialized manually. The example below is from the ImpactZone demo script:
var impactCollisionData = m_ImpactCallbackContext.ImpactCollisionData; impactCollisionData.Reset(); impactCollisionData.Initialize(); impactCollisionData.SetImpactSource(gameObject,null); impactCollisionData.SetImpactTarget(collider); impactCollisionData.ImpactDirection = Vector3.zero; impactCollisionData.ImpactPosition = collider.transform.position + Random.insideUnitSphere; impactCollisionData.ImpactStrength = 1; impactCollisionData.SurfaceImpact = m_SurfaceImpact;
Impact Damage Data
The ImpactDamageData is optional. It contains additional information about the impact which can be used by certain ImpactActions. It is often used in items to change the damage without changing the ImpactAction. It contains the following properties:
/// <summary> /// An interface that contains information about the damage caused by an impact. /// </summary> public interface IImpactDamageData { LayerMask LayerMask { get; set; } DamageProcessor DamageProcessor { get; set; } float DamageAmount { get; set; } float ImpactForce { get; set; } int ImpactForceFrames { get; set; } float ImpactRadius { get; set; } string ImpactStateName { get; set; } float ImpactStateDisableTimer { get; set; } SurfaceImpact SurfaceImpact { get; set; } }
Impact Action Group Object
If you wish to reuse the same ImpactActions across multiple objects or simply want to use ImpactActions in your own custom scripts without writing custom inspectors, the ImpactActionGroupObject is a great solution.
A simple ScriptableObject that contains an ImpactActionGroup with a simple DoImpact function. Create the object using right-click context menu: Create -> Opsive -> Ultimate Character Controller -> Impact -> Impact Action Group Object.
Custom Impact Actions
Making a custom Impact Action is very easy. Simply override the OnImpactInternal function and use the data within the Context
[Serializable] public class MyImpactAction : ImpactAction { /// <summary> /// Internal method which performs the impact action. /// </summary> /// <param name="ctx">Context about the hit.</param> protected override void OnImpactInternal(ImpactCallbackContext ctx) { Debug.Log(ctx); // The ImpacCollisionData should never be null. Debug.Log(ctx.ImpactCollisionData.ImpactCollider); // The Damage Data is optional so it can be null. if (ctx.ImpactDamageData != null) { Debug.Log(ctx.ImpactDamageData?.DamageAmount); } } }
Built-in Impact Actions
There are a lot of Impact Actions and more will be added as time goes on.
To find a full list of the built-in ImpactActions use your IDE of choice (such as Visual Studio) and look for all classes inheriting the ImpactAction class.
DebugImpactContext
The impact isn’t working as you would like? Try to debug it using this action that logs the data within the ImpactContext.
Add Force
Add a force to the impacted object.
Add Torque
Add torque to the impacted object.
State Impact
Set a state object that was impacted.
Use Impact Action Object
Call the DoImpact function on a ImpactActionObject that can be used across multiple objects.
Spawn Surface Effect
Use the surface system to spawn surface effects.
Simple Damage
Deal damage to the impacted object. It can optionally use the ImpactDamageData such that the object calling the impact can set the damage rather than being constant. Use the DamageProcessor if you wish to have even more control over the damage.
Heal
The impacted object can be healed.