Update
This commit is contained in:
@@ -1,88 +0,0 @@
|
||||
/// ---------------------------------------------
|
||||
/// Ultimate Character Controller
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
|
||||
namespace Opsive.UltimateCharacterController.Character.Effects
|
||||
{
|
||||
using Opsive.Shared.Game;
|
||||
using Opsive.UltimateCharacterController.Utility;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Moves the camera downward similar to how a large boss would shake the camera as they are stomping on the ground.
|
||||
/// </summary>
|
||||
public class BossStomp : Effect
|
||||
{
|
||||
[Tooltip("The direction to apply the positional force.")]
|
||||
[SerializeField] protected Vector3 m_PositionalStompDirection = Vector3.down;
|
||||
[Tooltip("The strength of the positional boss stomp.")]
|
||||
[SerializeField] protected MinMaxFloat m_PositionalStrength = new MinMaxFloat(0.5f, 1);
|
||||
[Tooltip("The direction to apply the rotational force.")]
|
||||
[SerializeField] protected Vector3 m_RotationalStompDirection = Vector3.forward;
|
||||
[Tooltip("The strength of the rotational boss stomp.")]
|
||||
[SerializeField] protected MinMaxFloat m_RotationalStrength = new MinMaxFloat(10, 15);
|
||||
[Tooltip("The number of times the stomp effect should play. Set to -1 to play the efffect until the effect is stopped or disabled.")]
|
||||
[SerializeField] protected int m_RepeatCount;
|
||||
[Tooltip("The delay until the stomp plays again.")]
|
||||
[SerializeField] protected float m_RepeatDelay = 1;
|
||||
|
||||
public Vector3 PositionalStompDirection { get { return m_PositionalStompDirection; } set { m_PositionalStompDirection = value; } }
|
||||
public MinMaxFloat PositionalStrength { get { return m_PositionalStrength; } set { m_PositionalStrength = value; } }
|
||||
public Vector3 RotationalStompDirection { get { return m_RotationalStompDirection; } set { m_RotationalStompDirection = value; } }
|
||||
public MinMaxFloat RotationalStrength { get { return m_RotationalStrength; } set { m_RotationalStrength = value; } }
|
||||
public int RepeatCount { get { return m_RepeatCount; } set { m_RepeatCount = value; } }
|
||||
public float RepeatDelay { get { return m_RepeatDelay; } set { m_RepeatDelay = value; } }
|
||||
|
||||
private int m_StopCount;
|
||||
private ScheduledEventBase m_StopEvent;
|
||||
|
||||
/// <summary>
|
||||
/// Can the effect be started?
|
||||
/// </summary>
|
||||
/// <returns>True if the effect can be started.</returns>
|
||||
public override bool CanStartEffect()
|
||||
{
|
||||
return m_CameraController != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The effect has been started.
|
||||
/// </summary>
|
||||
protected override void EffectStarted()
|
||||
{
|
||||
base.EffectStarted();
|
||||
|
||||
m_StopCount = 0;
|
||||
Stomp();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs the stomp effect.
|
||||
/// </summary>
|
||||
private void Stomp()
|
||||
{
|
||||
m_CameraController.AddSecondaryPositionalForce(m_PositionalStompDirection * m_PositionalStrength.RandomValue, 0);
|
||||
m_CameraController.AddSecondaryRotationalForce(m_RotationalStompDirection * m_RotationalStrength.RandomValue * (Random.value > 0.5f ? 1 : -1), 0);
|
||||
m_StopCount++;
|
||||
|
||||
if (m_RepeatCount == -1 || m_StopCount < m_RepeatCount) {
|
||||
m_StopEvent = Scheduler.ScheduleFixed(m_RepeatDelay, Stomp);
|
||||
} else {
|
||||
StopEffect();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The effect has stopped running.
|
||||
/// </summary>
|
||||
protected override void EffectStopped()
|
||||
{
|
||||
base.EffectStopped();
|
||||
|
||||
Scheduler.Cancel(m_StopEvent);
|
||||
m_StopEvent = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0330f89383dd08c4d9d5a41c627b8daa
|
||||
timeCreated: 1497381574
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,188 +0,0 @@
|
||||
/// ---------------------------------------------
|
||||
/// Ultimate Character Controller
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
|
||||
namespace Opsive.UltimateCharacterController.Character.Effects
|
||||
{
|
||||
using Opsive.Shared.Events;
|
||||
using Opsive.Shared.Utility;
|
||||
using Opsive.UltimateCharacterController.Camera;
|
||||
using Opsive.UltimateCharacterController.StateSystem;
|
||||
using Opsive.UltimateCharacterController.Utility;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Effects allow for extra camera/item movements that are applied to the character. Examples of an effect include an earthquake shake or a boss stomp. Effects
|
||||
/// do not affect the Animator and are not synchronized over the network. For anything more involved an Ability should be used instead.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
[AllowDuplicateTypes]
|
||||
public abstract class Effect : StateObject
|
||||
{
|
||||
[Tooltip("Can the ability be activated?")]
|
||||
[HideInInspector] [SerializeField] protected bool m_Enabled = true;
|
||||
[Tooltip("Should the effect be started when it is enabled?")]
|
||||
[SerializeField] protected bool m_StartWhenEnabled;
|
||||
[Tooltip("Specifies the name of the state that the effect should activate.")]
|
||||
[SerializeField] protected string m_State;
|
||||
#if UNITY_EDITOR
|
||||
[Tooltip("An editor only description of the effect.")]
|
||||
[HideInInspector] [SerializeField] protected string m_InspectorDescription;
|
||||
#endif
|
||||
|
||||
public bool Enabled { get { return m_Enabled; }
|
||||
set
|
||||
{
|
||||
if (m_Enabled == value) {
|
||||
return;
|
||||
}
|
||||
m_Enabled = value;
|
||||
if (!m_Enabled && IsActive) {
|
||||
StopEffect(false);
|
||||
} else if (Application.isPlaying && m_Enabled && !IsActive && m_StartWhenEnabled) {
|
||||
StartEffect();
|
||||
}
|
||||
}
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
public string InspectorDescription { get { return m_InspectorDescription; } set { m_InspectorDescription = value; } }
|
||||
#endif
|
||||
public bool StartWhenEnabled { get { return m_StartWhenEnabled; } set { m_StartWhenEnabled = value; } }
|
||||
|
||||
protected GameObject m_GameObject;
|
||||
protected Transform m_Transform;
|
||||
protected UltimateCharacterLocomotion m_CharacterLocomotion;
|
||||
protected CameraController m_CameraController;
|
||||
|
||||
private int m_ActiveIndex = -1;
|
||||
private int m_Index = -1;
|
||||
|
||||
public bool IsActive { get { return m_ActiveIndex != -1; } }
|
||||
[NonSerialized] public int Index { get { return m_Index; } set { m_Index = value; } }
|
||||
[NonSerialized] public int ActiveIndex { get { return m_ActiveIndex; } set { m_ActiveIndex = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the effect to the specified controller.
|
||||
/// </summary>
|
||||
/// <param name="characterLocomotion">The character locomotion component to initialize the effect to.</param>
|
||||
/// <param name="index">The prioirty index of the ability within the controller.</param>
|
||||
public void Initialize(UltimateCharacterLocomotion characterLocomotion, int index)
|
||||
{
|
||||
m_CharacterLocomotion = characterLocomotion;
|
||||
m_GameObject = characterLocomotion.gameObject;
|
||||
m_Transform = characterLocomotion.transform;
|
||||
m_Index = index;
|
||||
|
||||
// The StateObject class needs to initialize itself.
|
||||
Initialize(m_GameObject);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method called by MonoBehaviour.Awake. Can be used for initialization.
|
||||
/// </summary>
|
||||
public virtual void Awake()
|
||||
{
|
||||
EventHandler.RegisterEvent<CameraController>(m_GameObject, "OnCharacterAttachCamera", OnAttachCamera);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method called by MonoBehaviour.Start. This method is called on all effects when the MonoBehaviour.Start method is called.
|
||||
/// </summary>
|
||||
public virtual void Start() { }
|
||||
|
||||
/// <summary>
|
||||
/// Can the effect be started?
|
||||
/// </summary>
|
||||
/// <returns>True if the effect can be started.</returns>
|
||||
public virtual bool CanStartEffect() { return true; }
|
||||
|
||||
/// <summary>
|
||||
/// Tries to start the effect.
|
||||
/// </summary>
|
||||
/// <returns>True if the effect was successfully started.</param>
|
||||
public bool StartEffect()
|
||||
{
|
||||
return m_CharacterLocomotion.TryStartEffect(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts executing the effect.
|
||||
/// </summary>
|
||||
public void StartEffect(int index)
|
||||
{
|
||||
m_ActiveIndex = index;
|
||||
|
||||
EffectStarted();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The effect has been started.
|
||||
/// </summary>
|
||||
protected virtual void EffectStarted()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(m_State)) {
|
||||
StateManager.SetState(m_GameObject, m_State, true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the effect. Called during the MonoBehaviour.Update loop.
|
||||
/// </summary>
|
||||
public virtual void Update() { }
|
||||
|
||||
/// <summary>
|
||||
/// Stop the effect from running.
|
||||
/// </summary>
|
||||
public void StopEffect()
|
||||
{
|
||||
StopEffect(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop the effect from running.
|
||||
/// </summary>
|
||||
/// <param name="fromController">Is the effect being stopped from the UltimateCharacterController?</param>
|
||||
public void StopEffect(bool fromController)
|
||||
{
|
||||
// If the effect wasn't stopped from the character controller then call the controller's stop effect method. The controller must be aware of the stopping.
|
||||
if (!fromController) {
|
||||
m_CharacterLocomotion.TryStopEffect(this);
|
||||
return;
|
||||
}
|
||||
|
||||
m_ActiveIndex = -1;
|
||||
|
||||
EffectStopped();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The effect has stopped running.
|
||||
/// </summary>
|
||||
protected virtual void EffectStopped()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(m_State)) {
|
||||
StateManager.SetState(m_GameObject, m_State, false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The character has been attached to the camera. Initialze the camera-related values.
|
||||
/// </summary>
|
||||
/// <param name="cameraController">The camera controller attached to the character. Can be null.</param>
|
||||
private void OnAttachCamera(CameraController cameraController)
|
||||
{
|
||||
m_CameraController = cameraController;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the character is destroyed.
|
||||
/// </summary>
|
||||
public virtual void OnDestroy()
|
||||
{
|
||||
EventHandler.UnregisterEvent<CameraController>(m_GameObject, "OnCharacterAttachCamera", OnAttachCamera);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 832652a73851e8649a13fa09bdbfc943
|
||||
timeCreated: 1483429005
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,45 +0,0 @@
|
||||
/// ---------------------------------------------
|
||||
/// Ultimate Character Controller
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
|
||||
namespace Opsive.UltimateCharacterController.Character.Effects
|
||||
{
|
||||
using Opsive.Shared.Game;
|
||||
using Opsive.UltimateCharacterController.Audio;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Plays an AudioClip when the effect starts.
|
||||
/// </summary>
|
||||
public class PlayAudioClip : Effect
|
||||
{
|
||||
[Tooltip("A set of AudioClips that can be played when the effect is started.")]
|
||||
[HideInInspector] [SerializeField] protected AudioClipSet m_AudioClipSet = new AudioClipSet();
|
||||
|
||||
public AudioClipSet AudioClipSet { get { return m_AudioClipSet; } set { m_AudioClipSet = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Can the effect be started?
|
||||
/// </summary>
|
||||
/// <returns>True if the effect can be started.</returns>
|
||||
public override bool CanStartEffect()
|
||||
{
|
||||
return m_AudioClipSet.AudioClips.Length > 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The effect has been started.
|
||||
/// </summary>
|
||||
protected override void EffectStarted()
|
||||
{
|
||||
base.EffectStarted();
|
||||
|
||||
var audioSource = m_AudioClipSet.PlayAudioClip(m_GameObject);
|
||||
if (audioSource != null) {
|
||||
Scheduler.ScheduleFixed(audioSource.clip.length, StopEffect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b4633c2aca0067a4f98d64e7cda42ae0
|
||||
timeCreated: 1497381574
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,140 +0,0 @@
|
||||
/// ---------------------------------------------
|
||||
/// Ultimate Character Controller
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
|
||||
namespace Opsive.UltimateCharacterController.Character.Effects
|
||||
{
|
||||
using Opsive.Shared.Events;
|
||||
using Opsive.UltimateCharacterController.Motion;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Shakes the camera, item, or character based on a force magnitude.
|
||||
/// </summary>
|
||||
public class Shake : Effect
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies which objects to apply the shaking force to.
|
||||
/// </summary>
|
||||
public enum ShakeTarget
|
||||
{
|
||||
Camera = 1, // Shakes the camera.
|
||||
Item = 2, // Shakes the equipped item.
|
||||
Character = 4 // Shakes the character.
|
||||
}
|
||||
|
||||
[Tooltip("Specifies which objects to apply the shaking force to.")]
|
||||
[HideInInspector] [SerializeField] protected ShakeTarget m_Target = ShakeTarget.Camera | ShakeTarget.Item | ShakeTarget.Character;
|
||||
[Tooltip("The amount of force to apply to the shake.")]
|
||||
[SerializeField] protected Vector2 m_Force = new Vector2(0.4f, 0.4f);
|
||||
[Tooltip("Should a smooth horizontal force be added? If false a random force between 0 and Force.x will be used.")]
|
||||
[SerializeField] protected bool m_SmoothHorizontalForce = true;
|
||||
[Tooltip("Specifies the probability that a vertical force will be applied.")]
|
||||
[SerializeField] protected float m_VerticalForceProbability = 0.3f;
|
||||
[Tooltip("The amount of time that it takes for the effect to fade out.")]
|
||||
[SerializeField] protected float m_FadeOutDuration = 4;
|
||||
[Tooltip("Exaggerates or reduces the positional force imposed.")]
|
||||
[SerializeField] protected float m_PositionalFactor = 1;
|
||||
[Tooltip("Exaggerates or reduces the rotational force imposed.")]
|
||||
[SerializeField] protected float m_RotationalFactor = 3;
|
||||
[Tooltip("The number of seconds that the effect will last.")]
|
||||
[SerializeField] protected float m_Duration = 7;
|
||||
|
||||
public ShakeTarget Target { get { return m_Target; } set { m_Target = value; } }
|
||||
public Vector2 Force { get { return m_Force; } set { m_Force = value; } }
|
||||
public bool SmoothHorizontalForce { get { return m_SmoothHorizontalForce; } set { m_SmoothHorizontalForce = value; } }
|
||||
public float VerticalForceProbability { get { return m_VerticalForceProbability; } set { m_VerticalForceProbability = value; } }
|
||||
public float FadeOutDuration { get { return m_FadeOutDuration; } set { m_FadeOutDuration = value; } }
|
||||
public float PositionalFactor { get { return m_PositionalFactor; } set { m_PositionalFactor = value; } }
|
||||
public float RotationalFactor { get { return m_RotationalFactor; } set { m_RotationalFactor = value; } }
|
||||
public float Duration { get { return m_Duration; } set { m_Duration = value; } }
|
||||
|
||||
private float m_StartTime;
|
||||
private Vector3 m_TotalForce;
|
||||
|
||||
/// <summary>
|
||||
/// Can the effect be started?
|
||||
/// </summary>
|
||||
/// <returns>True if the effect can be started.</returns>
|
||||
public override bool CanStartEffect()
|
||||
{
|
||||
if (m_Target == 0) {
|
||||
return false;
|
||||
}
|
||||
return base.CanStartEffect();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The effect has been started.
|
||||
/// </summary>
|
||||
protected override void EffectStarted()
|
||||
{
|
||||
base.EffectStarted();
|
||||
|
||||
m_StartTime = Time.unscaledTime;
|
||||
m_TotalForce = Vector3.zero;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the effect.
|
||||
/// </summary>
|
||||
public override void Update()
|
||||
{
|
||||
// Stop the effect if it has occurred for more than the duration.
|
||||
var endTime = m_StartTime + m_Duration;
|
||||
if (endTime < Time.unscaledTime) {
|
||||
StopEffect();
|
||||
return;
|
||||
}
|
||||
|
||||
var force = Vector3.zero;
|
||||
if (m_SmoothHorizontalForce) {
|
||||
// Apply a horizontal force which is the perlin noise value between 0 and the force. This force will ease out during the specified fade out duration.
|
||||
force.x = SmoothRandom.GetVector3Centered(1).x * m_Force.x * Mathf.Min(endTime - Time.unscaledTime, m_FadeOutDuration) * Time.timeScale * m_CharacterLocomotion.TimeScale;
|
||||
} else {
|
||||
// If smooth horizontal force is false then apply a random force which will ease out during the specified fade out duration.
|
||||
force.x = Random.Range(-m_Force.x, m_Force.x) * Mathf.Min(endTime - Time.unscaledTime, m_FadeOutDuration);
|
||||
|
||||
// Alternates between positive and negative to produce sharp shakes with nice spring smoothness.
|
||||
if (Mathf.Sign(m_TotalForce.x) == Mathf.Sign(force.x)) {
|
||||
force.x = -force.x;
|
||||
}
|
||||
}
|
||||
|
||||
// Restrict the number of times a vertical force is applied to prevent a jerky movements.
|
||||
if (Random.value <= m_VerticalForceProbability) {
|
||||
// Smoothly fade out during the specified fade out duration.
|
||||
force.y = Random.Range(0, m_Force.y) * Mathf.Min(endTime - Time.unscaledTime, m_FadeOutDuration);
|
||||
|
||||
// Alternates between positive and negative to produce sharp shakes with nice spring smoothness.
|
||||
if (Mathf.Sign(m_TotalForce.y) == Mathf.Sign(force.y)) {
|
||||
force.y = -force.y;
|
||||
}
|
||||
}
|
||||
|
||||
m_TotalForce += force;
|
||||
|
||||
// Add the force to the camera.
|
||||
if ((m_Target & ShakeTarget.Camera) != 0 && m_CameraController != null) {
|
||||
m_CameraController.AddPositionalForce(force * m_PositionalFactor);
|
||||
m_CameraController.AddRotationalForce(-force * 2 * m_RotationalFactor);
|
||||
}
|
||||
|
||||
// Add the force to the item.
|
||||
if ((m_Target & ShakeTarget.Item) != 0) {
|
||||
var positionalForce = Vector3.forward * force.x * 0.015f;
|
||||
var rotationalForce = positionalForce;
|
||||
rotationalForce.Set(force.y * 2, -force.x, force.x * 2);
|
||||
EventHandler.ExecuteEvent(m_GameObject, "OnAddSecondaryForce", -1, positionalForce, rotationalForce, true);
|
||||
}
|
||||
|
||||
// Add the horizontal force to the character.
|
||||
if ((m_Target & ShakeTarget.Character) != 0) {
|
||||
force.y = 0;
|
||||
m_CharacterLocomotion.AddForce(force * m_PositionalFactor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cc343863c06ffb84ab06598433d5c507
|
||||
timeCreated: 1497125968
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user