Guest User

Untitled

a guest
Jan 4th, 2018
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 11.52 KB | None | 0 0
  1. using UnityEngine;
  2.  
  3. namespace Opsive.ThirdPersonController.Abilities
  4. {
  5.     public class StealthKill : Ability
  6.     {
  7.         [Tooltip("The layers that can be moved")]
  8.         [SerializeField]
  9.         protected LayerMask m_MoveableLayer;
  10.         [Tooltip("Start moving when the angle between the character and the Moveable object is less than this amount")]
  11.         [SerializeField]
  12.         protected float m_StartMoveMaxLookAngle = 15;
  13.         [Tooltip("Start moving when the distance between the character and the Moveable object is less than this amount")]
  14.         [SerializeField]
  15.         protected float m_StartMoveMaxDistance = 0.5f;
  16.         [Tooltip("The normalized speed that the character moves towards the move point")]
  17.         [SerializeField]
  18.         protected float m_MinMoveToTargetSpeed = 0.5f;
  19.         [Tooltip("The length of the character's arms")]
  20.         [SerializeField]
  21.         protected float m_ArmLength = 0.25f;
  22.         [Tooltip("The amount of force to move with")]
  23.         [SerializeField]
  24.         protected float m_MoveForce = 5;
  25.         [Tooltip("Can the object be moved in the horizontal direction?")]
  26.         [SerializeField]
  27.         protected bool m_AllowHorizontalMovement = true;
  28.         [Tooltip("Can the object be moved in the forward direction?")]
  29.         [SerializeField]
  30.         protected bool m_AllowForwardMovement = true;
  31.         [Tooltip("If Stop on State Complete is enabled, which layer should be used to determine if the state is complete?")]
  32.         [SerializeField]
  33.         protected int m_StopOnStateCompleteLayer;
  34.         [Tooltip("Should the ability be stopped after the animation state has finished?")]
  35.         [SerializeField]
  36.         protected bool m_StopOnStateComplete = true;
  37.         [SerializeField] Ability abilityToStop;
  38.         [SerializeField] GameObject stealthWeapon;
  39.         // Internal variables
  40.         private RaycastHit m_RaycastHit;
  41.         private Vector3 m_MoveableObjectCenterOffset;
  42.         private Vector3 m_Direction;
  43.  
  44.         private bool m_InPosition;
  45.  
  46.         // Component references
  47.         private KillableObject m_KillableObject;
  48.         private Transform m_MoveableTransform;
  49.         // Internal variables
  50.         private bool m_WaitForTransition;
  51.         /// <summary>
  52.         /// Can the ability be started?
  53.         /// </summary>
  54.         /// <returns>True if the ability can be started.</returns>
  55.         public override bool CanStartAbility()
  56.         {
  57.             // The character can move if the character is on the ground and a moveable object is near.
  58.             if (m_Controller.Grounded && Physics.Raycast(m_Transform.position + m_Controller.CapsuleCollider.center, m_Transform.forward, out m_RaycastHit, m_StartMoveMaxDistance, m_MoveableLayer.value))
  59.             {
  60.                 // The character must be mostly looking at the puseable object.
  61.                 if (Vector3.Angle(-m_RaycastHit.normal, m_Transform.forward) < m_StartMoveMaxLookAngle)
  62.                 {
  63.                     // The moveable object must have the MoveableObject component and is able to be Moveed.
  64.                     if ((m_KillableObject = (m_MoveableTransform = m_RaycastHit.transform).GetComponent<KillableObject>()) != null /*&& m_KillableObject.CanStartMove()*/)
  65.                     {
  66.                         // The closest point between the character and the Moveable object is needed in order to know how far out the character should start Moveing from.
  67.                         var closestPoint = m_RaycastHit.collider.ClosestPointOnBounds(m_Transform.position);
  68.                         m_MoveableObjectCenterOffset = ((m_RaycastHit.transform.position - closestPoint).magnitude + m_ArmLength) * m_RaycastHit.normal;
  69.                         m_Direction = m_RaycastHit.normal;
  70.                         return true;
  71.                     }
  72.                 }
  73.             }
  74.             return false;
  75.         }
  76.  
  77.         /// <summary>
  78.         /// Starts executing the ability.
  79.         /// </summary>
  80.         protected override void AbilityStarted()
  81.         {
  82.             base.AbilityStarted();
  83.  
  84.             // Prevent the existing velocity from interferring with the move position movement by stopping all movement.
  85.             m_Controller.StopMovement();
  86.             m_Controller.TryStopAbility(m_Controller.Abilities[0]);
  87.             m_KillableObject.GetComponent<BehaviorDesigner.Runtime.BehaviorTree>().enabled = false;
  88.             m_WaitForTransition = true;
  89.             m_Controller.ForceRootMotion = true;
  90.  
  91.             // Move into move position.
  92.             var targetPosition = m_MoveableTransform.position + m_MoveableObjectCenterOffset;
  93.             targetPosition.y = m_Transform.position.y;
  94.  
  95.             MoveToTarget(targetPosition, Quaternion.LookRotation(-m_Direction), m_MinMoveToTargetSpeed, InPosition);
  96.         }
  97.  
  98.         /// <summary>
  99.         /// Returns the destination state for the given layer.
  100.         /// </summary>
  101.         /// <param name="layer">The Animator layer index.</param>
  102.         /// <returns>The state that the Animator should be in for the given layer. An empty string indicates no change.</returns>
  103.         public override string GetDestinationState(int layer)
  104.         {
  105.             // The ability only affects the base and upper layers.
  106.             if (layer != m_AnimatorMonitor.BaseLayerIndex && layer != m_AnimatorMonitor.UpperLayerIndex)
  107.             {
  108.                 return string.Empty;
  109.             }
  110.  
  111.             return "Stealth Kill.Move";
  112.         }
  113.  
  114.         /// <summary>
  115.         /// The character has arrived at the target position and the ability can start.
  116.         /// </summary>
  117.         private void InPosition()
  118.         {
  119.             stealthWeapon.SetActive(true);
  120.             // The character has arrived at the move position. Start moving.
  121.             m_InPosition = true;
  122.             EventHandler.ExecuteEvent(m_KillableObject.gameObject, "OnStealthKillDeath", true);
  123.             EventHandler.ExecuteEvent(KillableObject, "OnStealthKillDeath");
  124.             //            m_KillableObject.StartMove(m_Transform); - play kill ability next
  125.             m_AnimatorMonitor.DetermineStates();
  126.         }
  127.  
  128.         /// <summary>
  129.         /// Prevent the controller from having control when the MoveToTarget coroutine is updating.
  130.         /// </summary>
  131.         /// <returns>Should the RigidbodyCharacterController continue execution of its Move method?</returns>
  132.         public override bool Move()
  133.         {
  134.             // Return early if the character isn't in move position yet.
  135.             if (!m_InPosition)
  136.             {
  137.                 return false;
  138.             }
  139.             // GetNextAnimatorStateInfo hash will be 0 when the Animator is not in a transition.
  140.             if (m_StopOnStateComplete && !m_WaitForTransition && m_Animator.GetNextAnimatorStateInfo(0).fullPathHash == 0)
  141.             {
  142.                 if (m_Animator.GetCurrentAnimatorStateInfo(m_StopOnStateCompleteLayer).normalizedTime > 1)
  143.                 {
  144.                     StopAbility();
  145.                 }
  146.             }
  147.             else
  148.             {
  149.                 m_WaitForTransition = false;
  150.             }
  151.  
  152.             return true;
  153.         }
  154.  
  155.  
  156.         /// <summary>
  157.         /// Apply any external forces not caused by root motion, such as an explosion force.
  158.         /// <param name="xPercent">The percent that the x root motion force affected the current velocity.</param>
  159.         /// <param name="yPercent">The percent that the y root motion force affected the current velocity.</param>
  160.         /// <returns>Should the RigidbodyCharacterController continue execution of its CheckForExternalForces method?</returns>
  161.         /// </summary>
  162.         public override bool CheckForExternalForces(float xPercent, float zPercent)
  163.         {
  164.             // If there is an external force then leave move.
  165.             if ((Mathf.Abs(m_Controller.Velocity.x * (1 - xPercent)) + Mathf.Abs(m_Controller.Velocity.z * (1 - zPercent))) > 0.5f)
  166.             {
  167.                 StopAbility();
  168.             }
  169.             return false;
  170.         }
  171.  
  172.         /// <summary>
  173.         /// Move with the MoveableObject.
  174.         /// </summary>
  175.         /// <returns>Should the RigidbodyCharacterController continue execution of its UpdateMovement method?</returns>
  176.         public override bool UpdateMovement()
  177.         {
  178.             // Don't use Root Motion to move - just stay with the object.
  179.             var targetPosition = m_MoveableTransform.position + m_MoveableObjectCenterOffset;
  180.             targetPosition.y = m_Transform.position.y;
  181.             m_Controller.SetPosition(targetPosition);
  182.  
  183.             return false;
  184.         }
  185.  
  186.         /// <summary>
  187.         /// Update the rotation forces.
  188.         /// </summary>
  189.         /// <returns>Should the RigidbodyCharacterController continue execution of its UpdateRotation method?</returns>
  190.         public override bool UpdateRotation()
  191.         {
  192.             // Always face the pushable object.
  193.             m_Transform.rotation = Quaternion.Slerp(m_Transform.rotation, Quaternion.LookRotation(-m_Direction), m_Controller.RotationSpeed * Time.deltaTime);
  194.  
  195.             return false;
  196.         }
  197.  
  198.         /// <summary>
  199.         /// The ability has stopped running.
  200.         /// </summary>
  201.         protected override void AbilityStopped()
  202.         {
  203.             base.AbilityStopped();
  204.  
  205.             //            m_KillableObject.StopMove();
  206.             m_MoveableTransform = null;
  207.             m_KillableObject = null;
  208.             m_Controller.ForceRootMotion = false;
  209.             m_InPosition = false;
  210.             stealthWeapon.SetActive(false);
  211.         }
  212.  
  213.         public override bool UpdateAnimator()
  214.         {
  215.             if (!m_AllowHorizontalMovement)
  216.                 m_AnimatorMonitor.SetHorizontalInputValue(0f);
  217.             else
  218.                 m_AnimatorMonitor.SetHorizontalInputValue(m_Controller.RelativeInputVector.x);
  219.  
  220.             if (!m_AllowForwardMovement)
  221.                 m_AnimatorMonitor.SetForwardInputValue(0f);
  222.             else
  223.                 m_AnimatorMonitor.SetForwardInputValue(m_Controller.RelativeInputVector.z);
  224.  
  225.  
  226.             return false;
  227.         }
  228.  
  229.         /// <summary>
  230.         /// Does the ability have complete control of the Animator states?
  231.         /// </summary>
  232.         /// <returns>True if the Animator should not update to reflect the current state.</returns>
  233.         public override bool HasAnimatorControl()
  234.         {
  235.             return m_InPosition;
  236.         }
  237.  
  238.         /// <summary>
  239.         /// Should IK at the specified layer be used?
  240.         /// </summary>
  241.         /// <param name="layer">The IK layer in question.</param>
  242.         /// <returns>True if the IK should be used.</returns>
  243.         public override bool CanUseIK(int layer)
  244.         {
  245.             if (layer == m_AnimatorMonitor.UpperLayerIndex)
  246.             {
  247.                 return false;
  248.             }
  249.             return true;
  250.         }
  251.  
  252.         /// <summary>
  253.         /// Can the character have an item equipped while the ability is active?
  254.         /// </summary>
  255.         /// <returns>False to indicate that the character cannot have an item equipped.</returns>
  256.         public override bool CanHaveItemEquipped()
  257.         {
  258.             return false;
  259.         }
  260.  
  261.         /// <summary>
  262.         /// The character wants to interact with the item. Return false if there is a reason why the character shouldn't be able to.
  263.         /// </summary>
  264.         /// <returns>True if the item can be interacted with.</returns>
  265.         public override bool CanInteractItem()
  266.         {
  267.             return !m_InPosition;
  268.         }
  269.     }
  270. }
Advertisement
Add Comment
Please, Sign In to add comment