Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Error CS1031 Type excepted

Discussion in 'Scripting' started by Bil0n, Jun 3, 2015.

  1. Bil0n

    Bil0n

    Joined:
    Jun 3, 2015
    Posts:
    4
    I have small problem in my script.

    Assets/acParkour/Scripts/Gameplay/Player/Local/dsa.cs(21,42): error CS1031: Type expected


    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. [RequireComponent(typeof(vp_FPController))]
    6.  
    7. public class ac_FPParkour : "vp_Component"
    8.  
    9. {
    10.     // anim
    11.     public GameObject ParkourArmPrefab = null ;                    // parkour arm prefab that will be seen during ledgegrab
    12.     public AnimationClip ParkourArmClimbAnim = null;            // parkour's arm ledge climbing animation that will be played.
    13.     public Vector3 ParkourArmPos = Vector3.zero;              
    14.  
    15.     // sounds
    16.     protected vp_FootstepManager m_FootstepManager ;            // Can be used to cache the player vp_FootStepManager
    17.     protected Terrain m_CurrentTerrain = null;                    // caches the current terrain the controller is on
    18.        
    19.     // general
    20.     protected CharacterController m_CharacterController = null;    // Can be used to cache the player CharacterController
    21.     protected vp_FPController m_Controller = null;                 // Can be used to cache the players vp_FPController
    22.     protected vp_FPCamera m_Camera = null;                         // Can be used to cache the players vp_FPCamera
    23.     protected ac_FPParkourEventHandler m_Player = null;         // Need this to access the above and the player.
    24.  
    25.     // dash
    26.     public bool Dashing {get {return m_Dashing; } }
    27.     public bool MotorDashDone { get {return m_MotorDashDone; } }
    28.     public int CurrentDash {get {return m_CurrentDash; } }
    29.     public float DashTimer {get {return m_DashTimer; } }
    30.    
    31.     public float DashCooldown = 1f;              
    32.     public float MotorDashForce = 0.50f;      
    33.     public int DashCount = 1;
    34.     public float DashRecoverSpeed = 1.0f;
    35.     public float DashSensitivtiy = 0.25f;
    36.     protected bool m_MotorDashDone = true;
    37.     protected int m_CurrentDash = 0;
    38.     protected float m_DashInputTimer = 0f;
    39.     protected float m_DashTimer = 0f;
    40.     protected bool m_Dashing = false;
    41.     protected float m_CanDashAgain = 0f ;
    42.  
    43.  
    44.     // walljump
    45.     public string IgnoreWallJumpTag = "";                        // tag that disallow Walljump
    46.     public float WallJumpForwardForce = 0.05f;
    47.     public float WallJumpForce = 0.1f;
    48.     public float WallJumpUpForce = 0.3f;
    49.     protected bool m_MotorWallJumpDone = true;
    50.     protected bool m_WallJumpAble = false;
    51.     protected Vector3 m_WallJumpHitNormal;                        // contains info about the wall we collided
    52.  
    53.     // wallhang
    54.     public string IgnoreWallHangTag = "";                        // tag that disallow wallhang
    55.     public bool IsWallHanging {get {return m_IsWallHanging; } }
    56.     public float WallHangDuration = 3.0f;
    57.     public float LosingGripStart = 0.75f;
    58.     public float LosingGripGravity = 0.003f;
    59.     protected float m_WallHangTimer = 0f;
    60.     protected Vector3 m_WallHangHitNormal = Vector3.zero;
    61.     protected bool m_CanWallHang = false;
    62.     protected bool m_IsWallHanging = false;
    63.  
    64.     // doublejump
    65.     public float DoubleJumpForwardForce = 0.15f ;
    66.     public float DoubleJumpForce = 0.4f;
    67.     public int DoubleJumpCount = 1;
    68.     protected bool m_DoubleJumpAble = false;
    69.     protected int m_currentDoubleJump = 1 ;
    70.     protected bool m_MotorDoubleJumpDone = true;
    71.    
    72.     // groundslide
    73.     public bool GroundSliding {get {return m_GroundSliding; } }
    74.     public float MotorGroundSlideForce = 0.2f;
    75.     public float MinBuildUp = 2.0f;
    76.     public float MinSpeedToBuildup = 20.0f;
    77.     public float GroundSlideSpeedMinimum = 2.0f;
    78.     public float GroundSlideCooldown = 1.5f;
    79.     protected float m_GroundSlideBuildup;
    80.     protected float m_CanGroundslideAgain = 0f;
    81.     protected Vector3 m_GroundSlideLookDirection = Vector3.zero;
    82.     protected bool m_GroundSliding = false;
    83.    
    84.     // wallrun
    85.     public string IgnoreWallRunTag = "";            // tag that disallow wallrun
    86.     public Transform WallRunObject {get {return m_WallRunObject; } }
    87.     public bool IsWallRunning {get { return m_IsWallRunning; } }
    88.     public bool IsWallOnRight {get {return m_IsWallOnRight; } }
    89.     public bool IsWallInFront {get {return m_IsWallInFront; } }
    90.  
    91.     public float WallRunGravity = 0.08f;
    92.     public float WallRunTilt = 1.0f;
    93.     public float WallRunDuration = 2.0f;
    94.     public float WallRunUpForce = 0.1f;
    95.     public float WallRunSpeedMinimum = 8.0f ;
    96.     public float WallRunAgainTimeout = 1f;
    97.     public float WallRunRange = 1.0f;                 // the distance to keep from the climbable while climbing
    98.     public float WallRunDismountForce = 0.1f;        // force applied at end of wallrun
    99.     public float WallAngle {get { return m_WallAngle; } }
    100.     public bool WallRunInfinite = false;
    101.     public bool WallRunAutoRotateYaw = false;        // if enabled, camera yaw will be rotated parallel of wallrun direction
    102.  
    103.     protected float m_WallAngle;
    104.     protected float m_WallRunMaxSpeed = 0f;
    105.     protected bool m_WallRunable = false ;
    106.     protected bool m_IsWallOnRight = false;
    107.     protected bool m_IsWallInFront = false;
    108.     protected Transform m_WallRunObject;
    109.     protected bool m_IsWallRunning = false;
    110.     protected float m_WallRunTimer = 0f;
    111.     protected float m_CanWallRunAgain = 0f ;
    112.     protected Vector3 m_WallRunHitPoint = Vector3.zero;
    113.     protected Vector3 m_WallRunHitNormal = Vector3.zero;
    114.     protected Vector3 m_WallRunDismountDirection = Vector3.zero;
    115.     protected Vector3 m_WallRunLookDirection = Vector3.zero;
    116.     private bool autoYawed = false;
    117.    
    118.     // ledge grab
    119.     public string IgnoreLedgeGrabTag = "";                // tag that disallow ledgegrab
    120.     public bool LedgeGrabable { get {return m_LedgeGrabable; } }
    121.     public bool IsLedgeGrabbing { get { return m_IsLedgeGrabbing; } }
    122.     public bool IsHanging { get {return m_IsHanging; } }
    123.     public Vector3 HangPosition {get {return m_HangPosition; } }
    124.     public Vector3 WallNormal {get {return m_ClimbObjectNormal; } }
    125.     public Vector3 ClimbObjectPosition {get {return m_ClimbObjectPosition; } }
    126.     public Vector3 ClimbPositionOffset = Vector3.zero;  
    127.     public float HeadOffset = 0.1f;                        // how high the top-down raycast should start
    128.  
    129.     public float FirstPersonLedgeOffset = 0.4f;
    130.     public float ThirdPersonLedgeOffset = 0.53f;
    131.     public float PullUpSpeed = 0.08f;
    132.     public float MinDistanceToVault =  1.0f;            // check if player can vault instead.
    133.     public float MinDistanceToClimb = 10.0f ;            // check if player is within grabing distance
    134.     public float DistancePlayerToTop ;                    // gets the distance between player and the top of distance
    135.     public float LedgeGrabRange = 1.5f;                    // minimum ray casting range.
    136.     public float LedgeGrabDuration = 0.5f;                // duration of the whole LedgeGrab coroutine
    137.     public float ClimbAlignDuration = 0.4f;                // how fast to align to ledge
    138.     public float ClimbDismountForce = 0.02f;            // additional force applied at end of climb
    139.  
    140.     protected bool m_LedgeGrabable = false;
    141.     protected bool m_IsLedgeGrabbing = false;
    142.     protected bool m_IsHanging = false;
    143.     protected Vector3 m_HangPosOffset = Vector3.zero;
    144.     protected Vector3 m_HangPosition = Vector3.zero;            // position to lerp to when hanging  
    145.     protected Vector3 m_HangRotation = Vector3.zero;
    146.     protected Vector3 m_ClimbObjectPosition = Vector3.zero;        // position to lerp to when climbing
    147.     protected Vector3 m_ClimbObjectNormal = Vector3.zero;
    148.     protected Vector3 m_CachedDirection = Vector3.zero;         // cache the direction to keep proper distance from climbable
    149.     protected Vector2 m_CachedRotation  = Vector2.zero;
    150.     protected Vector3 m_LedgeLeft = Vector3.zero;
    151.     protected Vector3 m_LedgeRight = Vector3.zero;
    152.     protected Transform m_Platform = null;                        // current rigidbody or object in the 'MovableObject' layer that we are standing on
    153.  
    154.     private bool shouldCrouch = false ;
    155.     private bool isLiningUp = false;
    156.    
    157.     // physics
    158.     float targetDamping = 0.15f;
    159.    
    160.     // misc
    161.     public Vector3 LocalVelocity { get {return GetLocalVelocity(); } }
    162.     protected int m_LastWeaponEquipped = 0;                        // cache last weapon equipped
    163.  
    164.     // Use this for initialization
    165.     protected override void  Awake ()
    166.     {
    167.         base.Awake();
    168.  
    169.         // initial setup
    170.         m_Audio = audio;
    171.         m_CharacterController = gameObject.GetComponent<CharacterController>();
    172.         m_Controller = (vp_FPController)transform.root.GetComponentInChildren(typeof(vp_FPController));
    173.         m_Player  = (ac_FPParkourEventHandler)transform.root.GetComponentInChildren(typeof(ac_FPParkourEventHandler));
    174.         m_Camera = GetComponentInChildren<vp_FPCamera>();
    175.         m_Transform = transform;
    176.         m_FootstepManager = (vp_FootstepManager)transform.root.GetComponentInChildren(typeof(vp_FootstepManager));
    177.  
    178.         m_currentDoubleJump = DoubleJumpCount ;
    179.         m_CanWallRunAgain = Time.time;
    180.         m_CanDashAgain = Time.time;
    181.         m_CanGroundslideAgain = Time.time;
    182.  
    183.         // spawn the parkour arm at world origin and hide it
    184.         if(ParkourArmPrefab != null)
    185.         {
    186.             ParkourArmPrefab = (GameObject)Object.Instantiate(ParkourArmPrefab,Vector3.zero,Quaternion.identity);
    187.             ParkourArmPrefab.SetActive(false);
    188.         }
    189.  
    190.  
    191.     }
    192.    
    193.     protected override void Start()
    194.     {
    195.         // setup the correct amount of dash count
    196.         m_CurrentDash = DashCount ;
    197.  
    198.         // hacky way to setwallrun maxspeed from  preset
    199.         m_Player.WallRun.Start();
    200.         m_WallRunMaxSpeed = m_Controller.MotorAcceleration;
    201.         m_Player.WallRun.Stop();
    202.  
    203.     }
    204.  
    205.     /// <summary>
    206.     /// registers this component with the event handler (if any)
    207.     /// </summary>
    208.     protected override void OnEnable()
    209.     {  
    210.  
    211.         if (m_Player != null)
    212.             m_Player.Register(this);
    213.  
    214.         // add the wallrun footstep callback;
    215.         m_Camera.BobStepCallback += WallRunFootstep;
    216.     }
    217.    
    218.     /// <summary>
    219.     /// unregisters this component from the event handler (if any)
    220.     /// </summary>
    221.     protected override void OnDisable()
    222.     {
    223.  
    224.         // unregister this monobehaviour from the player event handler
    225.         if (m_Player != null)
    226.             m_Player.Unregister(this);  
    227.  
    228.         // remove the wallrun footstep callback
    229.         m_Camera.BobStepCallback -= WallRunFootstep;
    230.     }
    231.  
    232.     protected override void Update()
    233.     {
    234.         base.Update();
    235.  
    236.         // handles ledgegrab, walljump and doublejump input
    237.         InputJump();
    238.        
    239.         // handles dash input
    240.         InputDash();
    241.        
    242.         // handles ground slide input
    243.         InputGroundSlide();
    244.        
    245.         // handles wallhang input
    246.         InputWallHang();
    247.  
    248.     }
    249.  
    250.     protected override void FixedUpdate()
    251.     {
    252.         // handle ledgegrab raycast and collision check
    253.         UpdateLedgeGrab();
    254.  
    255.         // handle wallrun raycast and motion during wallrunning
    256.         UpdateWallrun();
    257.  
    258.         // apply a camera Z tilt when wallrun
    259.         UpdateWallrunTilt();
    260.  
    261.         // limit groundsliding based on speed and duration
    262.         UpdateGroundSliding();
    263.  
    264.         // update dash cooldown and dash regen
    265.         UpdateDash();
    266.  
    267.         // handles a parkour hanging before transitioning to parkour climb
    268.         UpdateLedgeHanging();
    269.  
    270.         // handles sticking to the wall
    271.         UpdateWallHang();
    272.  
    273. //        UpdatePhysics();
    274.     }
    275.    
    276.     /// <summary>
    277.     /// Takes controllercollider hit and convert to raycast
    278.     /// before passing it over for wall parkour related activity
    279.     /// as raycast is much more accurate then controllercolliderhit
    280.     /// </summary>
    281.     protected virtual void OnControllerColliderHit(ControllerColliderHit hit)
    282.     {
    283.         RaycastHit raycastHit;
    284.  
    285.         Vector3 localpos = transform.root.position + new Vector3 (0,m_CharacterController.height*0.8f,0);
    286.  
    287.         Physics.Raycast( localpos , hit.point- localpos , out raycastHit, WallRunRange);
    288.  
    289.         // check if the surface allows wallrun.
    290.         CheckWallRun(raycastHit);
    291.  
    292.         // check if the surface allows walljump and wallhang
    293.         CheckWallJump(raycastHit);
    294.  
    295.         // check if the surface allows wallhang
    296.         CheckWallHang(raycastHit);
    297.     }
    298.  
    299.     protected virtual bool CanStart_Run()
    300.     {
    301.         // can only run from a forward
    302.         if (m_Player.InputMoveVector.Get().y <= 0)
    303.             return false;
    304.         // can't start running while crouching
    305.         if (m_Player.Crouch.Active)
    306.             return false;
    307.        
    308.         return true;
    309.        
    310.     }
    311.  
    312.     protected virtual bool CanStart_Crouch()
    313.     {
    314.         // can't start running while crouching
    315.         if (m_Player.WallRun.Active)
    316.             return false;
    317.        
    318.         return true;
    319.        
    320.     }
    321.    
    322.     protected virtual bool CanStart_WallRun()
    323.     {
    324.         if(WallRunDuration == 0)  
    325.             return false;
    326.         if(Time.time < m_CanWallRunAgain)    // wallrun is refreshing
    327.             return false;
    328.         if (m_Controller.Grounded)            // Can't wallrun on the ground
    329.             return false;
    330.         if (m_LedgeGrabable)                // If can ledge grab, should ledge grab instead
    331.             return false;
    332.         if (m_IsWallRunning )                // Already wallrunning      
    333.             return false;
    334.         if (!m_WallRunable)                    // Surface is not wallrunable
    335.             return false;
    336.         if (m_Player.Velocity.Get().magnitude < WallRunSpeedMinimum) // Not fast not enough
    337.             return false;
    338. //        if (!m_Player.Run.Active)            // Must start from a Run
    339. //            return false;
    340.         if (m_Player.Crouch.Active)            // cannot wallrun while crouching
    341.             return false;
    342.         if (GetLocalVelocity().z < -1)        // cannot wallrun backwards
    343.             return false;
    344.  
    345.         return true;
    346.        
    347.     }
    348.  
    349.     protected virtual bool CanStart_WallHang()
    350.     {
    351.         if(m_Controller.Grounded)            // still grounded
    352.             return false;
    353.         if(!m_CanWallHang)                    // not near a wall
    354.             return false;
    355.         if(m_IsWallHanging)                    // already wallhanging
    356.             return false;
    357.  
    358.         return true;
    359.     }
    360.  
    361.     protected virtual bool CanStart_GroundSlide()
    362.     {
    363.         if(m_GroundSlideBuildup < MinBuildUp)                // run distance too short
    364.             return false;
    365.         if(Time.time < m_CanGroundslideAgain)            // groundslide is still refreshing
    366.             return false;
    367.         if (vp_Input.GetAxisRaw("Vertical") != 1)        // Can only groundslide if going forward
    368.             return false;
    369.         if (!m_Controller.Grounded)                        // Not on ground, cannot groundslide
    370.             return false;
    371.         if(!m_Player.Run.Active)                        // Can only groundslide from a run
    372.             return false;
    373.  
    374.         return true;
    375.     }
    376.  
    377.     protected virtual bool CanStart_Dash()
    378.     {
    379.         // ran out of dash counter
    380.         if (m_CurrentDash <= 0)
    381.             return false;
    382.  
    383.         if (!m_MotorDashDone)
    384.             return false;
    385.  
    386.         if (Time.time < m_CanDashAgain)
    387.             return false;
    388.  
    389.         // if there's no movement input at all
    390.         if (vp_Input.GetAxisRaw("Vertical") == 0 && vp_Input.GetAxisRaw("Horizontal") == 0)
    391.             return false;
    392.  
    393.         if (m_IsHanging)
    394.             return false;
    395.  
    396.         if (m_Dashing)
    397.             return false;
    398.  
    399.         if (m_IsWallRunning)
    400.             return false;
    401.  
    402.         if (m_IsLedgeGrabbing)
    403.             return false;
    404.  
    405.         return true;
    406.     }
    407.    
    408.     protected virtual bool CanStart_WallJump()
    409.     {
    410.         if (!m_Player.MotorJumpDone.Get())    // if we are holding jump
    411.             return false;
    412.  
    413.         if (!m_WallJumpAble)                // can't wall jump without wall contact
    414.             return false;
    415.  
    416.         if (m_WallJumpHitNormal == new Vector3 (0,0,0)) // we can't walljump from ground
    417.             return false;
    418.  
    419.         if (m_LedgeGrabable)
    420.             return false;
    421.  
    422.         if (m_Controller.Grounded)            // Debug.Log ("Still on ground");
    423.             return false;
    424.         return true;
    425.     }
    426.    
    427.     protected virtual bool CanStart_DoubleJump()
    428.     {
    429.  
    430.         if (m_WallJumpAble)                    // check if we can walljump instead
    431.             return false;
    432.  
    433.         if (!m_MotorDoubleJumpDone)            // Still double jumping
    434.             return false;
    435.  
    436.         if (!m_DoubleJumpAble)                // Cannot doublejump
    437.             return false;
    438.  
    439.         if (m_currentDoubleJump <= 0)            // Ran out of airjump counter
    440.             return false;
    441.    
    442.         if (m_Controller.Grounded)            // Are we still on the ground
    443.             return false;
    444.  
    445.         if (!m_Player.MotorJumpDone.Get())    // Still jumping
    446.             return false;
    447.  
    448.         if (!m_MotorWallJumpDone)            // Still wall jumping
    449.             return false;
    450.  
    451.         if (m_IsWallHanging)                // Still wall hanging
    452.             return false;
    453.        
    454.         if (m_IsLedgeGrabbing)            // Still parkour climbing
    455.             return false;
    456.  
    457.         if (m_IsWallRunning)                // Still wallrunning
    458.             return false;
    459.  
    460.         return true;
    461.        
    462.     }
    463.  
    464.     /// <summary>
    465.     /// Prevent automatically jumping upon loading from a wall jump or doublejump if player holds jump
    466.     /// </summary>
    467.     protected virtual bool CanStart_Jump()
    468.     {
    469.         if(!m_MotorDoubleJumpDone)
    470.             return false;
    471.  
    472.         if(!m_MotorWallJumpDone)
    473.             return false;
    474.  
    475.         return true;
    476.     }
    477.    
    478.     protected virtual bool CanStart_LedgeGrab()
    479.     {
    480.  
    481.         if(m_Controller.Grounded)            // can't ledgegrab if grounded
    482.             return false;
    483.         if(m_IsLedgeGrabbing)                // is already ledgegrabbing
    484.         {
    485.             m_Player.LedgeGrab.TryStop();
    486.             return false;
    487.         }
    488.         if(m_LedgeGrabable == false)
    489.             return false;
    490.  
    491.         return true;
    492.        
    493.     }
    494.  
    495.     /// <summary>
    496.     /// Once WallRun is approved, this will setup all the variables to allow wallrunning
    497.     /// </summary>
    498.     protected virtual void OnStart_WallRun()
    499.     {
    500.         // setup the variables
    501.         m_IsWallRunning = true;
    502.         m_CanWallHang = true;
    503.         m_WallJumpAble = true;
    504.  
    505.         // reset camera initial rotation ,otherwise the camera
    506.         // will be rotated with the offset it had at spawn-time
    507.         m_Camera.SetRotation(m_Camera.Transform.eulerAngles, false, true);
    508.  
    509.         m_Player.Jump.Stop();
    510.        
    511.         // stop any movement on our controller.
    512.         // Comment this off if you want to maintain the momentum when wallrunning
    513.         m_Player.Stop.Send();
    514.  
    515.         // Gives a nice push upwards at start of wallrunning
    516.         m_Controller.AddSoftForce(transform.up*WallRunUpForce,WallRunDuration*0.5f);
    517.  
    518.         m_CachedDirection = m_Transform.forward;
    519.        
    520.     }
    521.  
    522.     protected virtual void OnStart_WallHang()
    523.     {
    524.         // setup the variables
    525.         m_CanWallHang = false;
    526.         m_IsWallHanging = true;
    527.         m_WallJumpAble = true;
    528.  
    529.         // stop wallrun
    530.         m_Player.WallRun.Stop();
    531.  
    532.         // stop controller completely
    533.         m_Controller.Stop();
    534.     }
    535.  
    536.     protected virtual void OnStart_GroundSlide()
    537.     {
    538.         m_Player.Run.Stop();
    539.         m_GroundSliding = true;
    540.  
    541.         // stores current look direction
    542.         m_GroundSlideLookDirection = m_Controller.transform.forward;
    543.         m_CachedRotation = m_Player.Rotation.Get ();
    544.  
    545.         // pushes player forward over a 10 frames
    546.         m_Controller.AddSoftForce(transform.forward*MotorGroundSlideForce,10f);
    547.  
    548.     }
    549.  
    550.     protected virtual void OnStart_Dash()
    551.     {
    552.         // decrease available dashcount by one
    553.         m_CurrentDash --;
    554.         m_Dashing = true;
    555.         m_MotorDashDone = false;
    556.  
    557.         // stores player inputMove vector as dashDirection
    558.         Vector3 dashDirection = transform.TransformDirection(new Vector3 (m_Player.InputMoveVector.Get().x,0,
    559.                                                                           m_Player.InputMoveVector.Get().y));
    560.  
    561.         // apply force to controller based dashDirection
    562.         m_Controller.AddSoftForce(dashDirection*MotorDashForce,5f);
    563.  
    564.     }
    565.  
    566.     protected virtual void OnStart_WallJump()
    567.     {
    568.         // stop jumping to prevent creating a double wall jump
    569.         m_Player.Jump.Stop();
    570.         // if we are wallrunning or wallhanging, stops immediately
    571.         m_Player.WallHang.Stop();
    572.         m_Player.WallRun.Stop();
    573.  
    574.         // setup for walljump
    575.         m_Player.MotorJumpDone.Set(false);
    576.         m_MotorWallJumpDone = false;
    577.         m_CanWallHang = false;
    578.         m_WallJumpAble = false;
    579.  
    580.         // store local velocity
    581. //        Vector3 localVelocity = m_Controller.Transform.InverseTransformDirection( m_Player.Velocity.Get() );
    582.  
    583.         Vector3 localVelocity = GetLocalVelocity() * 0.1f;
    584.  
    585.         // store MotorThrottle from walljump Normal
    586.         Vector3 tempMotorThrottle = (m_WallJumpHitNormal*WallJumpForce) +                                        // wall jump normal direction
    587.             (m_Camera.transform.TransformDirection(Vector3.forward)*(WallJumpForwardForce * localVelocity.z)) + // nudge it towards camera direction
    588.                                     new Vector3 (0,(WallJumpUpForce / Time.timeScale),0);                        // wall jump up force
    589.  
    590.         // perform impulse jump
    591.         m_Player.FallSpeed.Set( (Physics.gravity.y * (m_Controller.PhysicsGravityModifier * 0.002f)) );
    592.         m_Player.MotorThrottle.Set(tempMotorThrottle);
    593.     }
    594.  
    595.     protected virtual void OnStart_DoubleJump()
    596.     {
    597.         // setup for double jump
    598.         m_MotorDoubleJumpDone = false ;
    599.         m_DoubleJumpAble = false;
    600.  
    601.         // decrease the current double jump count left by 1
    602.         m_currentDoubleJump -= 1;
    603.  
    604.         m_Controller.StopSoftForce();
    605.  
    606.         // store current MotorThrottle
    607.         Vector3 tempMotorThrottle = m_Player.MotorThrottle.Get();
    608.         tempMotorThrottle.y = (DoubleJumpForce / Time.timeScale);
    609.  
    610.         // perform impulse jump
    611.         m_Player.FallSpeed.Set( (Physics.gravity.y * (m_Controller.PhysicsGravityModifier * 0.002f)) );
    612.         m_Player.MotorThrottle.Set(tempMotorThrottle);
    613.  
    614.  
    615.         // give it's a little nudge towards player's direction
    616.         Vector3 doubleJumpDirection = transform.TransformDirection(new Vector3 (
    617.             m_Player.InputMoveVector.Get().x,0,m_Player.InputMoveVector.Get().y));
    618.  
    619.         m_Controller.AddForce( doubleJumpDirection * DoubleJumpForwardForce);
    620.  
    621.     }
    622.  
    623.     protected virtual void OnStart_LedgeGrab()
    624.     {
    625.         // setup for ledgegrab
    626.         m_CanWallHang = false;
    627.         m_IsWallHanging = false ;
    628.         m_IsLedgeGrabbing = true;
    629. //        if(m_Platform != null)
    630. //            m_Player.Platform.Set(m_Platform);
    631.  
    632.  
    633.         // stop jump
    634.         m_Player.Jump.Stop();
    635.  
    636.         // stop the controller
    637.         m_Player.Stop.Send();
    638.  
    639.         // disallow player control while ledgegrab
    640.         m_Player.InputAllowGameplay.Set(false);
    641.  
    642.         // check the height of the obstacle, if it's over vault height then it will do ledge grab
    643.         if(DistancePlayerToTop < MinDistanceToClimb && DistancePlayerToTop > MinDistanceToVault)
    644.             StartCoroutine(LineUpLedge());
    645.         else
    646.             StartCoroutine(ClimbLedge(ClimbPositionOffset));    //else it will auto vault
    647.  
    648.     }
    649.  
    650.     /// <summary>
    651.     /// This lerps the camera towards the direction of the wallrunning
    652.     ///
    653.     protected virtual IEnumerator LineUpWallRun()
    654.     {
    655.  
    656.         Quaternion startingRotation = m_Camera.transform.rotation; // cache start rotation
    657.         Quaternion endRotation ; // cache end rotation
    658.        
    659.         endRotation = Quaternion.LookRotation(m_WallRunLookDirection,Vector3.up);
    660.  
    661.         float t = 0;
    662.        
    663.         float duration = 0.2f;
    664.         while(t < 1)
    665.         {  
    666.             t += Time.deltaTime/duration;
    667.            
    668.             Quaternion newRotation = Quaternion.Slerp(startingRotation, endRotation, t);
    669.             m_Player.Rotation.Set(new Vector2( newRotation.eulerAngles.x , WallRunAutoRotateYaw ? newRotation.eulerAngles.y : m_Player.Rotation.Get().y ));
    670.            
    671.             yield return new WaitForEndOfFrame();
    672.         }
    673.  
    674.         m_CachedDirection = m_Camera.Transform.forward;
    675.        
    676.     }
    677.  
    678.     /// <summary>
    679.     /// Lerps players towards the ideal ledgegrab position
    680.     /// </summary>
    681.     protected virtual IEnumerator LineUpLedge()
    682.     {
    683.         // setup for line up ledge
    684.         isLiningUp = true;
    685.         m_IsHanging = true;
    686.        
    687.         m_Camera.SetRotation(m_Camera.Transform.eulerAngles, false, true);
    688.        
    689.         // stop player
    690.         m_Player.Stop.Send();
    691.        
    692.         // store the current weapon
    693.         m_LastWeaponEquipped = m_Player.CurrentWeaponIndex.Get();
    694.        
    695.         // put the weapon away
    696.         vp_Timer.In(0.0f, delegate() { m_Player.SetWeapon.TryStart(0); } );
    697.        
    698.         // play parkour animation.
    699.         if(ParkourArmPrefab != null && ParkourArmClimbAnim != null)
    700.             vp_Timer.In(0.1f, ParkourArmClimb);
    701.        
    702.         Quaternion startingRotation = m_Camera.transform.rotation; // cache start rotation
    703.         Quaternion endRotation = Quaternion.LookRotation(m_HangRotation); // cache end rotation
    704.  
    705.         Vector3 startPosition = m_Player.Position.Get(); // cache the start position
    706.  
    707.         // position player about 0.5f in negative z away from ledgegrab position to
    708.         // minimize player being too close to the wall
    709.         Vector3 posOff ;
    710.  
    711.         posOff = m_ClimbObjectNormal*(m_Player.IsFirstPerson.Get() ? FirstPersonLedgeOffset : ThirdPersonLedgeOffset);
    712.  
    713.         Vector3 endPosition = m_HangPosition + posOff; // cache the end position
    714.  
    715.         float t = 0;
    716.        
    717.         while(t < 1)
    718.         {
    719.             t += Time.deltaTime/(ClimbAlignDuration);
    720.  
    721.             Quaternion newRotation = Quaternion.Slerp(startingRotation, endRotation, t);
    722.             m_Player.Rotation.Set(new Vector2( newRotation.eulerAngles.x , newRotation.eulerAngles.y));
    723.  
    724.             // Slerp players from current position to target position by t
    725.             Vector3 newPosition = Vector3.Slerp(startPosition, endPosition, t);
    726.  
    727.             m_Player.Position.Set(newPosition);
    728.  
    729.             m_Player.Stop.Send();
    730.             yield return new WaitForEndOfFrame();
    731.         }
    732.         m_CachedDirection = m_Camera.Transform.forward;
    733.         m_CachedRotation = m_Player.Rotation.Get();
    734.  
    735.  
    736. //        m_CachedRotation = new Vector2 (m_HangRotation.x, m_HangRotation.y);
    737.  
    738.         m_HangPosOffset = m_HangPosition + new Vector3 (0,0.5f,0);
    739.         isLiningUp = false;
    740.  
    741.     }
    742.  
    743.     /// <summary>
    744.     /// This is the actual function that will be used to climb obstacle or vault obstacle
    745.     /// It is triggered after OnStart_ClimbLedge
    746.     /// Takes a vector3 as a position offset
    747.     /// </summary>
    748.     protected virtual IEnumerator ClimbLedge(Vector3 posOff)
    749.     {
    750.         // disable player input and setup for climbledge
    751.         m_Player.InputAllowGameplay.Set(false);
    752.         m_IsHanging = false;
    753.         m_Player.Stop.Send();
    754.  
    755.         m_Player.ClimbingLedge.Send();
    756.         Vector3 startPosition = m_Player.Position.Get(); // cache the start position
    757.         m_CachedRotation = m_Player.Rotation.Get();    // cache the start rotation
    758.  
    759.         // convert positionOffset into controller's local space
    760.         posOff = m_Controller.Transform.TransformDirection(posOff);
    761.        
    762.         Vector3 endPosition = m_ClimbObjectPosition + posOff; // cache the end position
    763.  
    764.  
    765.         float t = 0;
    766.        
    767.         while(t < 1)
    768.         {
    769.             // lerp player current position to target position
    770.             t += Time.deltaTime/LedgeGrabDuration;
    771.             Vector3 newPosition = Vector3.Slerp(startPosition, endPosition, t);
    772.             m_Player.Position.Set(newPosition);
    773.             m_Player.Stop.Send();
    774.             yield return new WaitForEndOfFrame();
    775.         }
    776.  
    777.         // turn off ledgegrabbing, as we are done climbing
    778.         m_IsLedgeGrabbing = false;
    779.  
    780.         // equip cache weapon
    781.         m_Player.SetWeapon.TryStart(m_LastWeaponEquipped);
    782.         Vector3 force = gameObject.transform.root.forward * ClimbDismountForce;
    783.         force.y = ClimbDismountForce * 0.5f;    // dismounting at top: add slight up-force (push forward & up)
    784.         m_Player.Stop.Send();
    785.         m_Controller.AddForce(force);
    786.         m_Player.LedgeGrab.Stop();
    787.         m_Player.SetState("Default", true, true);
    788.         m_LedgeGrabable = false;
    789.  
    790.         // return control back to player
    791.         m_Player.InputAllowGameplay.Set(true);
    792.     }
    793.    
    794.     protected virtual IEnumerator ShimmyLedge(Vector3 posOff)
    795.     {
    796.         // disable player input and setup for climbledge
    797.         m_Player.InputAllowGameplay.Set(false);
    798.         m_Player.Stop.Send();
    799.        
    800.         Vector3 startPosition = m_Player.Position.Get(); // cache the start position
    801.  
    802.         Vector3 endPosition = posOff; // cache the end position
    803.        
    804.        
    805.         float t = 0;
    806.        
    807.         while(t < 1)
    808.         {
    809.             // lerp player current position to target position
    810.             t += Time.deltaTime/1f;
    811.             Vector3 newPosition = Vector3.Slerp(startPosition, endPosition, t);
    812.             m_Player.Position.Set(newPosition);
    813.             m_Player.Stop.Send();
    814.             yield return new WaitForEndOfFrame();
    815.         }
    816.  
    817.         // return control back to player
    818.         m_Player.InputAllowGameplay.Set(true);
    819.     }
    820.  
    821.     protected virtual void OnStop_WallRun()
    822.     {
    823.         autoYawed = false;
    824.         m_WallRunTimer = 0f;
    825.         m_CanWallHang = false;
    826.         m_WallJumpAble = false;
    827.         m_IsWallRunning = false;
    828.         m_DoubleJumpAble = true;
    829.         m_currentDoubleJump = DoubleJumpCount ;
    830.        
    831.         m_Player.Interactable.Set(null);
    832.  
    833.         m_CanWallRunAgain = Time.time + WallRunAgainTimeout;
    834.         m_Player.SetState("Default");
    835.  
    836.     }
    837.  
    838.     protected virtual void OnStop_WallHang()
    839.     {
    840.         m_IsWallHanging = false;
    841.     }
    842.    
    843.     protected virtual void OnStop_GroundSlide()
    844.     {
    845.         m_Player.Run.Stop();
    846.         m_GroundSliding = false;
    847.         m_CanGroundslideAgain = Time.time + GroundSlideCooldown;
    848.         m_CachedRotation = m_Player.Rotation.Get();
    849.     }
    850.  
    851.     protected virtual void OnStop_Dash()
    852.     {
    853.         m_Dashing = false;
    854.         m_MotorDashDone = true;
    855.         m_CanDashAgain = Time.time + DashCooldown;
    856.     }
    857.  
    858.     protected virtual void OnStop_DoubleJump()
    859.     {
    860.         m_DoubleJumpAble = true;
    861.         m_MotorDoubleJumpDone = true;
    862.        
    863.     }
    864.  
    865.     protected virtual void OnStop_WallJump()
    866.     {
    867.         m_Player.MotorJumpDone.Set(true);
    868.         m_MotorWallJumpDone = true ;
    869.         m_CanWallHang = false;
    870.         m_WallJumpAble = false;
    871.         m_DoubleJumpAble = true;
    872.         m_currentDoubleJump = DoubleJumpCount ;
    873.     }
    874.  
    875.     protected virtual void OnStop_LedgeGrab()
    876.     {
    877.         m_LedgeGrabable = false;
    878.         m_IsLedgeGrabbing = false;
    879.         m_IsHanging = false;
    880.  
    881. //        m_Platform = null ;
    882. //        m_Player.Platform.Set(m_Platform);
    883.  
    884.         m_Player.WallHang.Stop ();
    885.         if(shouldCrouch)
    886.         {
    887.             m_Player.Crouch.Start();
    888.         }
    889.         else
    890.             m_Player.SetState("Default", true, true);
    891.  
    892.         // hides parkour arm
    893.         if(ParkourArmPrefab != null)
    894.             ParkourArmPrefab.SetActive(false);
    895.  
    896.     }
    897.  
    898.     /// <summary>
    899.     /// Handles when player is hanging on to the ledge before they climb up.
    900.     /// </summary>
    901.     protected virtual void UpdateLedgeHanging()
    902.     {        
    903.         // no need to run through here if grounded
    904.         if(m_Controller.Grounded)
    905.             return;
    906.  
    907.         // no need to run through here if we aren't climbing
    908.         if(m_Player == null || !m_IsLedgeGrabbing)
    909.             return;
    910.  
    911.         // still lining up
    912.         if(isLiningUp)
    913.             return;
    914.  
    915.         // we aren't hanging so no point coming through here
    916.         if(!m_IsHanging)
    917.             return;
    918.  
    919.         // stops all run and wallrun activity
    920.         m_Player.Run.Stop();
    921.         m_Player.WallRun.Stop();
    922.  
    923.         // set gravity to 0
    924.         m_Controller.PhysicsGravityModifier = 0.0f;
    925.  
    926.         // limit player's view so they could only see 90 degrees to the left and right only
    927.         m_Camera.RotationYawLimit = new Vector2(m_CachedRotation.y - 50,  m_CachedRotation.y + 50);
    928.         m_Camera.RotationPitchLimit = new Vector2(90, -90);
    929.  
    930.         // stops player controller
    931.         m_Controller.Stop();
    932.  
    933.         // store players current position
    934.         Vector3 pos = m_Player.Position.Get() ;
    935.  
    936.         // Below is to simulate player building up momentum from the hanging to climbing up the ledge
    937.  
    938.         //if we reach the threshold, climb up the ledge
    939.         if(vp_Input.GetAxisRaw("Vertical") > 0)
    940.         {
    941.             StartCoroutine(ClimbLedge(ClimbPositionOffset));
    942.             return;
    943.         }
    944.  
    945.         // Build up momentum when pressing forward
    946.         if(vp_Input.GetAxisRaw("Vertical") > 0 && pos.y < m_HangPosOffset.y)
    947.         {
    948.             pos += new Vector3(0,PullUpSpeed,0);
    949.             m_Player.Position.Set(pos); // simulate moving upward
    950.         }
    951.         // drops down the default hanging position if there's no input
    952.         if(vp_Input.GetAxisRaw("Vertical") == 0 && pos.y > m_HangPosition.y)
    953.         {
    954.             pos -= new Vector3(0,PullUpSpeed,0);
    955.             m_Player.Position.Set(pos); // move back down
    956.         }
    957.  
    958.         // stop hanging and drop player down
    959.         if(vp_Input.GetAxisRaw("Vertical") < 0 || vp_Input.GetButton("Crouch"))
    960.         {
    961.             m_Player.LedgeGrab.Stop();
    962.             m_CachedRotation = m_Player.Rotation.Get();
    963.             m_Camera.SetRotation(m_Camera.Transform.eulerAngles, false, true);
    964.             m_Controller.AddForce(-m_Controller.Transform.forward * ClimbDismountForce);
    965.  
    966.             // reset back to default and give player control
    967.             m_Player.SetState("Default");
    968.             m_Player.SetWeapon.TryStart(m_LastWeaponEquipped);
    969.             m_Player.InputAllowGameplay.Set(true);
    970.  
    971.             // hide parkour arm
    972.             if(ParkourArmPrefab != null)
    973.                 ParkourArmPrefab.SetActive(false);
    974.         }
    975.     }
    976.  
    977.     /// <summary>
    978.     /// Handles the logic for wallhanging.
    979.     /// </summary>
    980.     protected virtual void UpdateWallHang()
    981.     {
    982.         if(!m_Player.WallHang.Active)                        // we are not currently wallhanging
    983.             return;
    984.         if(m_WallHangTimer >= WallHangDuration*LosingGripStart)            // if we are near the end of the wallhang duration
    985.             m_Controller.PhysicsGravityModifier = LosingGripGravity;    // set gravity to a low value to simulate slipping
    986.  
    987.         if(m_WallHangTimer >= WallHangDuration)                // we are over the duration allowed
    988.         {
    989.             m_WallHangTimer = 0;                            // reset the timer
    990.             m_Player.WallHang.TryStop();                    // and stop wallhanging
    991.             return;
    992.         }
    993.  
    994.         m_WallHangTimer += Time.deltaTime;          
    995.  
    996.     }
    997.  
    998.     /// <summary>
    999.     /// Handles the logic to stop groundsliding when it is active
    1000.     /// </summary>
    1001.     protected virtual void UpdateGroundSliding()
    1002.     {
    1003.         // This checks if player has been running forward for a predetermined amount of seconds
    1004.         // If true, then only could player attempt to groundslide.
    1005.         // This is to prevent from spamming groundslide infinitely.
    1006.         if(!m_Player.GroundSlide.Active && m_Player.Velocity.Get().magnitude > MinSpeedToBuildup)
    1007.             m_GroundSlideBuildup += Time.deltaTime;
    1008.         else
    1009.             m_GroundSlideBuildup = 0f;
    1010.  
    1011.         if(m_Player.GroundSlide.Active)
    1012.         {
    1013.             // constraint player transform to only look forward
    1014.             transform.rotation = Quaternion.LookRotation(m_GroundSlideLookDirection,Vector3.up);
    1015.  
    1016.             // limit camera to only be able to left and right
    1017.             m_Camera.RotationYawLimit = new Vector2(m_CachedRotation.y - 120,  m_CachedRotation.y + 120);
    1018.            
    1019.             // stops groundsliding if we are too slow, preventing sliding up ramp or infinite sliding
    1020.             if(m_Player.Velocity.Get().magnitude < GroundSlideSpeedMinimum )
    1021.                 m_Player.GroundSlide.Stop();
    1022.         }
    1023.     }
    1024.  
    1025.     /// <summary>
    1026.     /// Handles the cooldown logic for dashing
    1027.     /// </summary>
    1028.     protected virtual void UpdateDash()
    1029.     {
    1030.  
    1031.         if(m_CurrentDash > DashCount)        // we are over the dashcount
    1032.         {
    1033.             m_DashTimer = 0 ;                // reset timer
    1034.             m_CurrentDash = DashCount ;        // set it to the max alloawed
    1035.             return;
    1036.         }
    1037.  
    1038.         // we reached cooldown
    1039.         if(m_CurrentDash < DashCount && m_DashTimer >= DashRecoverSpeed)
    1040.         {
    1041.             m_DashTimer = 0 ;                // reset timer
    1042.             m_CurrentDash ++;                // add one more dash counter
    1043.             return;
    1044.         }
    1045.  
    1046.         // buildup  to cooldown
    1047.         if(m_CurrentDash < DashCount && m_DashTimer < DashRecoverSpeed)
    1048.             m_DashTimer += Time.deltaTime;
    1049.     }
    1050.  
    1051.     /// <summary>
    1052.     /// Handles logic for LedgeGrab. Cast a ray that is in front of the controller
    1053.     /// and returns the climbing position if within climbing distance
    1054.     /// Depending on the height of the obstacle, will either auto climb or go to ledge hanging
    1055.     /// </summary>
    1056.     protected virtual void UpdateLedgeGrab()
    1057.     {
    1058. //        if(m_Controller.Grounded)            // we are still on the ground
    1059. //            return;
    1060. //
    1061. //        if(m_IsLedgeGrabbing)                // already ledgegrabbing
    1062. //            return;
    1063. //
    1064. //        if(m_IsHanging)                        // we are currently hanging
    1065. //            return;
    1066.  
    1067.         if(LedgeGrabRange == 0 )            // ledgegrab disabled.
    1068.             return;
    1069.  
    1070.         RaycastHit checkCeilingHit ;      
    1071.  
    1072.         // check if there's a ceiling above while attempting to ledgegrab
    1073.         // if true, we are inside building, abort ledge grab
    1074.         if(Physics.SphereCast(transform.position,m_CharacterController.radius,Vector3.up, out checkCeilingHit, 2f))
    1075.                 return;
    1076.  
    1077.         // in the air and we are moving forward.
    1078.         if(!m_Controller.Grounded && GetLocalVelocity().z > 0)
    1079.         {
    1080.             m_Player.LedgeGrab.TryStart();    // automatically try to start LedgeGrab
    1081.         }
    1082.  
    1083.        
    1084.         RaycastHit hit;                        // stores collider hit in front of controller  
    1085.         RaycastHit topHit;                    // stores ceiling hit on top of climb position
    1086.         GameObject climbObject;
    1087.  
    1088.         // cast a ray forward about chest height to see if there's any climbable object
    1089.         if (Physics.Raycast( transform.root.position + new Vector3 (0,m_CharacterController.height*0.8f,0),
    1090.                                transform.root.forward, out hit, LedgeGrabRange, vp_Layer.Mask.ExternalBlockers))
    1091.         {
    1092.             if(!string.IsNullOrEmpty(IgnoreLedgeGrabTag))        // If tag is not empty
    1093.             {
    1094.                 if(hit.transform.tag == IgnoreLedgeGrabTag)        // Hit a ignore ledgegrab tag object
    1095.                     return;
    1096.             }
    1097.  
    1098.             Debug.DrawRay(hit.point, hit.normal, Color.green);
    1099.  
    1100.             climbObject = hit.transform.gameObject;
    1101.  
    1102.             if(hit.normal.y >  0.5f)    // wall is not vertically flat
    1103.                 return;
    1104.  
    1105. //            float height = hit.transform.localScale.y * hit.collider.bounds.size.y;// finds the height of collider
    1106.             float height = m_CharacterController.height + HeadOffset;
    1107.             float topMost;                                    // get the top climbing position based on raycast and climbObjectHeight
    1108.  
    1109.             Vector3 offset = hit.point + transform.root.TransformDirection(0,height,0.05f);
    1110.  
    1111.             Debug.DrawRay(offset, -transform.root.up, Color.blue);
    1112.  
    1113.  
    1114.             if(Physics.Raycast( offset, -transform.root.up, out topHit, LedgeGrabRange*2f, vp_Layer.Mask.ExternalBlockers))
    1115.             {
    1116.                 if(topHit.normal.y < 0.9f)
    1117.                     return;
    1118.  
    1119.                 if(topHit.point.y < hit.point.y || topHit.point.y < transform.position.y)
    1120.                     return;
    1121.  
    1122.                 if(topHit.transform.gameObject != climbObject)
    1123.                     return;
    1124.  
    1125.                 Debug.DrawRay(topHit.point, topHit.normal, Color.red);
    1126.  
    1127. //                if (topHit.collider.gameObject.layer == vp_Layer.MovableObject)
    1128. //                {
    1129. //                    m_Platform = topHit.transform;
    1130. //                }
    1131. //                else
    1132. //                    m_Platform = null;
    1133.  
    1134.                 topMost = topHit.point.y+0.1f;
    1135.  
    1136.                 if(m_Player.IsFirstPerson.Get())
    1137.                     m_HangPosition = new Vector3(hit.point.x,topMost-2.2f,hit.point.z);
    1138.                 else
    1139.                     m_HangPosition = new Vector3(hit.point.x,topMost-1.8f,hit.point.z);
    1140.  
    1141.                 m_HangRotation = Quaternion.AngleAxis(-180,Vector3.up) * hit.normal;
    1142.                 m_ClimbObjectPosition = new Vector3(hit.point.x,topMost,hit.point.z);
    1143.                 m_ClimbObjectNormal = hit.normal;
    1144.                 DistancePlayerToTop = Vector3.Distance(m_ClimbObjectPosition,new Vector3(m_ClimbObjectPosition.x,transform.root.position.y,m_ClimbObjectPosition.z));
    1145.  
    1146.                 Vector3 posOff = m_Controller.Transform.TransformDirection(ClimbPositionOffset);
    1147.  
    1148.                 if (DistancePlayerToTop < MinDistanceToClimb )
    1149.                 {
    1150.                     if(Physics.SphereCast(new Ray(    m_ClimbObjectPosition+posOff, Vector3.up),
    1151.                                           m_CharacterController.radius,
    1152.                                           m_CharacterController.height - (m_CharacterController.radius) + 0.01f))
    1153.                         shouldCrouch = true;
    1154.                     else
    1155.                     {
    1156.                         shouldCrouch = false;
    1157.                     }
    1158.  
    1159.                     m_LedgeGrabable = true ;                  
    1160.                    
    1161.                 }
    1162.                 else
    1163.                     m_LedgeGrabable = false;
    1164.             }          
    1165.         }
    1166.         else
    1167.             m_LedgeGrabable = false;
    1168.     }
    1169.  
    1170.     /// <summary>
    1171.     /// Handles the logic for Wallrun.
    1172.     /// Happens once OnStart_WallRun setup all the variables
    1173.     /// Will constraint the transform to the normal of the wall
    1174.     /// </summary>
    1175.     protected virtual void UpdateWallrun()
    1176.     {  
    1177.         if(m_IsLedgeGrabbing)
    1178.             return;
    1179.  
    1180.         if(m_IsHanging)
    1181.             return;
    1182.  
    1183.         if(!m_IsWallRunning)
    1184.             return;
    1185.  
    1186.         if(m_Player.Crouch.Active)
    1187.             return;
    1188.  
    1189.         // get the angle between the wallrun surface and the player's facing direction
    1190.         // used for controlling animationblending
    1191.        
    1192.         Vector3 cv = Vector3.Cross(-m_WallRunHitNormal, transform.forward);
    1193.         m_WallAngle = Vector3.Angle(-m_WallRunHitNormal, transform.forward);
    1194.        
    1195.         if(cv.y > 0) m_WallAngle = -m_WallAngle;
    1196.  
    1197.         RaycastHit hit;
    1198.         Vector3 raycastdirection = m_WallRunHitPoint - transform.position;
    1199.  
    1200.         // determines where is the wallrun in relation to the camera
    1201.         // this will determine where the raycast should be projected
    1202.         // so if wall is on camera right, the raycast will projected to camera right.
    1203.  
    1204. //        if(m_IsWallInFront )
    1205. //            raycastdirection = transform.root.forward;
    1206. //        else if (m_IsWallOnRight)
    1207. //            raycastdirection = transform.root.right;
    1208. //        else if (!m_IsWallOnRight)
    1209. //            raycastdirection = -transform.root.right;
    1210.    
    1211.         // stop wallrun if we ran out of time
    1212.         if(m_WallRunTimer >= WallRunDuration && !WallRunInfinite)
    1213.         {
    1214.             m_WallRunTimer = 0f;
    1215.             m_IsWallRunning = false;
    1216.  
    1217.             m_Player.WallRun.Stop ();
    1218.  
    1219.             m_Controller.AddForce (m_WallRunDismountDirection * WallRunDismountForce);
    1220.            
    1221.             return;
    1222.         }
    1223.  
    1224.         // override controller's gravity
    1225.         m_Controller.PhysicsGravityModifier = WallRunGravity;
    1226.  
    1227.         m_WallRunTimer += Time.deltaTime;
    1228.  
    1229.         float wallrunRelativeSpeed = Vector3.Dot(m_Camera.transform.forward, m_WallRunLookDirection);
    1230.         wallrunRelativeSpeed *= 10f;
    1231.         wallrunRelativeSpeed = Mathf.Round (wallrunRelativeSpeed);
    1232.         wallrunRelativeSpeed *= 0.1f;
    1233.  
    1234.         // rotates player towards wallrunning direction.
    1235.         if(m_WallAngle > 50f || m_WallAngle < -50f )
    1236.         {
    1237.             transform.rotation = Quaternion.LookRotation(m_WallRunLookDirection,Vector3.up);
    1238.             m_Controller.MotorAcceleration = Mathf.Lerp(0.2f,m_WallRunMaxSpeed,wallrunRelativeSpeed);
    1239.         }
    1240.  
    1241.  
    1242.         Vector2 tempInput = m_Player.InputMoveVector.Get();
    1243.         tempInput.x = 0f;
    1244.         m_Player.InputMoveVector.Set(tempInput);
    1245.  
    1246.         if(    Physics.Raycast( transform.root.position + new Vector3 (0,m_CharacterController.height*0.8f,0) , raycastdirection, out hit, WallRunRange))
    1247.         {
    1248.             if(hit.collider != null)
    1249.                 m_WallRunObject = hit.transform;
    1250.         }
    1251.  
    1252.         if (!Physics.CheckSphere(transform.root.position + new Vector3 (0,m_CharacterController.height*0.5f,0), 1.5f,vp_Layer.Mask.ExternalBlockers))
    1253.         {
    1254.             m_WallRunTimer = 0f;
    1255.             m_IsWallRunning = false;
    1256.             m_IsHanging = false ;
    1257.             m_Player.WallRun.Stop ();
    1258.             m_Controller.AddForce (m_WallRunDismountDirection * WallRunDismountForce);
    1259.  
    1260.         }
    1261.     }
    1262.        
    1263.     void UpdateWallrunTilt()
    1264.     {
    1265.         if(!m_Player.WallRun.Active)
    1266.             return;
    1267.  
    1268.         // disabled
    1269.         if(WallRunTilt == 0)
    1270.             return;
    1271.  
    1272.         print (WallAngle);
    1273.  
    1274.         Vector3 localVelocity = GetLocalVelocity() * 0.016f ;
    1275.  
    1276.         if(WallAngle > 25)
    1277.             m_Camera.AddRollForce(Mathf.Clamp(localVelocity.z * WallRunTilt,0f,WallRunTilt));
    1278.         else if (WallAngle < -25)
    1279.             m_Camera.AddRollForce(Mathf.Clamp(localVelocity.z * -WallRunTilt,-WallRunTilt,0f));
    1280.  
    1281.  
    1282. //        if(m_IsWallOnRight)
    1283. //            m_Camera.AddRollForce(Mathf.Clamp(localVelocity.z * WallRunTilt,0f,WallRunTilt));
    1284. //        else
    1285. //            m_Camera.AddRollForce(Mathf.Clamp(localVelocity.z * -WallRunTilt,-WallRunTilt,0f));
    1286.        
    1287.     }
    1288.  
    1289.     /// <summary>
    1290.     /// If press, will start LedgeGrab or Walljump or DoubleJump
    1291.     /// This utilizes GetButtonDown so it will only trigger once
    1292.     /// </summary>
    1293.     protected virtual void InputJump()
    1294.     {
    1295.         // uses default "Jump" button to check for double jumping.
    1296.         // feel free to change "Jump" to some other buttons to suit your project
    1297.         if(vp_Input.GetButtonDown("Jump"))
    1298.         {
    1299.             m_Player.LedgeGrab.TryStart();
    1300.             m_Player.WallJump.TryStart();
    1301.             m_Player.DoubleJump.TryStart();
    1302.         }
    1303.         else if(vp_Input.GetButtonUp("Jump"))
    1304.         {
    1305.             m_Player.WallJump.TryStop();
    1306.             m_Player.DoubleJump.TryStop();
    1307.  
    1308.         }
    1309.  
    1310.     }
    1311.  
    1312.     /// <summary>
    1313.     /// Input command for executing dash
    1314.     /// The main logic happens in the GetButtonUp, and if within the
    1315.     /// </summary>
    1316.     protected virtual void InputDash()
    1317.     {
    1318.  
    1319.         // uses default "Run" button to check for dashing
    1320.         if(vp_Input.GetButton("Run"))
    1321.         {
    1322.             m_DashInputTimer += Time.deltaTime;
    1323.         }
    1324.         // checks if we release "Run" button within the time frame allowed to trigger dash
    1325.         else if (vp_Input.GetButtonUp("Run") && m_DashInputTimer <= DashSensitivtiy)
    1326.         {
    1327.             m_Player.Dash.TryStart();
    1328.             m_DashInputTimer=0f;
    1329.         }
    1330.         else  
    1331.         {
    1332.             m_Player.Dash.TryStop();
    1333.             m_DashInputTimer=0f;
    1334.         }
    1335.  
    1336.     }
    1337.  
    1338.     protected virtual void InputGroundSlide()
    1339.     {
    1340.  
    1341.         //if (vp_Input.GetButton("Crouch"))    // suggested input axis
    1342.         if (vp_Input.GetButton("Crouch"))
    1343.         {
    1344.             m_Player.GroundSlide.TryStart();
    1345.             m_Player.WallHang.TryStop();
    1346.         }
    1347.         else
    1348.         {
    1349.             m_Player.GroundSlide.Stop();
    1350.         }
    1351.  
    1352.     }
    1353.  
    1354.     protected virtual void InputWallHang()
    1355.     {
    1356.         if (vp_Input.GetButtonDown("Zoom"))
    1357.         {
    1358.             if(!m_IsWallHanging)
    1359.                 m_Player.WallHang.TryStart();
    1360.             else
    1361.                 m_Player.WallHang.TryStop();
    1362.         }
    1363.     }
    1364.    
    1365.     /// <summary>
    1366.     /// Helper to check if the collision surface can be wallrun
    1367.     /// </summary>
    1368.     protected virtual void CheckWallRun(RaycastHit hit)
    1369.     {
    1370.         if(m_Controller.Grounded)
    1371.             return;
    1372.  
    1373.         if(m_IsLedgeGrabbing)
    1374.             return;
    1375.  
    1376.         if(!string.IsNullOrEmpty(IgnoreWallRunTag))            // If tag is not empty
    1377.         {
    1378.             if(hit.transform.tag == IgnoreWallRunTag &&
    1379.                hit.transform.tag != "Untagged")                // Hit a un-wallrunable object
    1380.                 return;
    1381.         }
    1382.  
    1383.         if(m_WallRunHitNormal == hit.normal)
    1384.         {
    1385.             m_CanWallRunAgain = Time.time + WallRunAgainTimeout;
    1386.             return;
    1387.         }
    1388.    
    1389.         if(hit.normal.y >  0.2f || hit.normal.y < -0.2f)
    1390.         {
    1391.             m_WallRunable = false;
    1392.             return;
    1393.         }
    1394.  
    1395.         if(hit.collider == null)
    1396.             return;
    1397.  
    1398.         m_WallRunHitNormal = hit.normal;
    1399.         m_WallRunHitPoint = hit.point;
    1400.  
    1401.         float colliderNormalForward ;
    1402.         float colliderNormalRight ;
    1403.  
    1404.         colliderNormalForward = Vector3.Dot (transform.forward,hit.normal);
    1405.         colliderNormalRight = Vector3.Dot (transform.right,hit.normal);
    1406.    
    1407.         if (colliderNormalForward < -0.95)        // check if we are facing the wall      
    1408.         {
    1409.             m_IsWallInFront = true;
    1410.  
    1411.             m_WallRunLookDirection = Quaternion.AngleAxis(-90,Vector3.forward) * m_WallRunHitNormal;
    1412.             m_WallRunDismountDirection = m_WallRunHitNormal;
    1413.             m_IsWallOnRight = false;
    1414.             m_WallRunable = true;
    1415.  
    1416.  
    1417.             m_Player.WallRun.TryStart();
    1418.             return;
    1419.  
    1420.         }
    1421.         else
    1422.         {
    1423.             m_IsWallInFront = false;
    1424.         }
    1425.  
    1426.         if(colliderNormalRight > 0)            // check if wall is on the left
    1427.         {
    1428.             m_WallRunLookDirection = Quaternion.AngleAxis(-89,Vector3.up) * m_WallRunHitNormal;
    1429.             m_WallRunDismountDirection = Quaternion.AngleAxis(-15,Vector3.up) * m_WallRunHitNormal;
    1430.             m_IsWallOnRight = false;
    1431.         }
    1432.        
    1433.         else if (colliderNormalRight < 0)    // else it's on the right
    1434.         {
    1435.             m_WallRunLookDirection = Quaternion.AngleAxis(89,Vector3.up) * m_WallRunHitNormal;
    1436.             m_WallRunDismountDirection = Quaternion.AngleAxis(15,Vector3.up) * m_WallRunHitNormal;
    1437.             m_IsWallOnRight = true;
    1438.         }
    1439.        
    1440.         m_WallRunable = true;
    1441.  
    1442.         if(m_IsWallRunning && !autoYawed && !m_IsWallInFront && WallRunAutoRotateYaw)// are we already wallrunning?
    1443.         {
    1444. //            autoYawed = true;
    1445.             StartCoroutine(LineUpWallRun());    // align the camera to the new vector instead.
    1446.             return;
    1447.         }
    1448.         else
    1449.             m_Player.WallRun.TryStart();
    1450.  
    1451.     }
    1452.  
    1453.     protected virtual void UpdatePhysics()
    1454.     {
    1455.         if(m_Controller.Grounded)
    1456.             return;
    1457.         if(m_Player.DoubleJump.Active)
    1458.             return;
    1459.         if(m_Player.WallRun.Active)
    1460.             return;
    1461.  
    1462.         m_Controller.MotorDamping = targetDamping;
    1463.     }
    1464.  
    1465.     /// <summary>
    1466.     /// Helper to check if the collision surface can be walljump
    1467.     /// </summary>
    1468.     protected virtual void CheckWallJump(RaycastHit hit)
    1469.     {
    1470.         if(!string.IsNullOrEmpty(IgnoreWallJumpTag))            // If tag is not empty
    1471.         {
    1472.             if(hit.transform.tag == IgnoreWallJumpTag &&
    1473.                hit.transform.tag != "Untagged")                    // Hit a un-walljumpable object
    1474.                 return;
    1475.         }
    1476.  
    1477. //        // hit the same wall, we can't walljump the same place twice
    1478. //        if(m_WallJumpHitNormal == hit.normal)
    1479. //        {
    1480. //            m_WallJumpAble = false;
    1481. //            return;
    1482. //        }
    1483.  
    1484.         if (!m_Controller.Grounded)
    1485.         {
    1486.             if(hit.normal.y <  0.1f && hit.normal.y > -0.1f) //if surface's orientation is flat like a wall
    1487.             {
    1488.                 m_WallJumpAble = true;
    1489.                 m_WallJumpHitNormal = hit.normal;
    1490.                 m_DoubleJumpAble = false;
    1491.             }
    1492.         }
    1493.         else
    1494.             m_WallJumpAble = false;
    1495.     }
    1496.  
    1497.     /// <summary>
    1498.     /// Helper to check if the collision surface can be wallhang
    1499.     /// </summary>
    1500.     protected virtual void CheckWallHang(RaycastHit hit)
    1501.     {
    1502.         if(!string.IsNullOrEmpty(IgnoreWallHangTag))        // If tag is not empty
    1503.         {
    1504.             if(hit.transform.tag == IgnoreWallHangTag &&
    1505.                hit.transform.tag != "Untagged")                // Hit a un-wallhangable object
    1506.                 return;
    1507.         }
    1508.  
    1509.         // hit the same wall, we can't wallhang the same place twice
    1510.         if(m_WallHangHitNormal == hit.normal)
    1511.             return;
    1512.  
    1513.         if (!m_Controller.Grounded)
    1514.         {
    1515.             if(hit.normal.y <  0.1f && hit.normal.y > -0.1f) //if surface's orientation is flat like a wall
    1516.             {
    1517.                 m_CanWallHang = true;
    1518.                 m_WallHangHitNormal = hit.normal ;
    1519.             }
    1520.         }
    1521.         else
    1522.             m_CanWallHang = false;
    1523.     }
    1524.    
    1525.  
    1526.  
    1527.     protected virtual void OnMessage_FallImpact(float impact)
    1528.     {
    1529.         // we are touching the ground again, reset all the variables
    1530.         m_CanWallRunAgain = Time.time;
    1531.         m_DoubleJumpAble = true;
    1532.         m_currentDoubleJump = DoubleJumpCount ;
    1533.         m_IsHanging = false;
    1534.         m_IsLedgeGrabbing = false;
    1535.         m_IsWallHanging = false;
    1536.         m_Player.LedgeGrab.Stop();
    1537.         m_Player.WallRun.Stop();
    1538.         m_Player.SetState("Default", true, true);
    1539.         m_Player.InputAllowGameplay.Set(true);
    1540.         m_WallRunHitNormal = new Vector3(0,0,0);
    1541.  
    1542.        
    1543.     }
    1544.  
    1545.         protected virtual Texture OnValue_WallTexture
    1546.     {
    1547.         get
    1548.         {  
    1549.             if (WallRunObject == null)
    1550.                 return null;
    1551.            
    1552.             // return if no renderer and no terrain under the controller
    1553.             if(WallRunObject.renderer == null && m_CurrentTerrain == null)
    1554.                 return null;
    1555.  
    1556.             int terrainTextureID = -1;
    1557.  
    1558.             // check to see if a main texture can be retrieved from the terrain
    1559.             if(m_CurrentTerrain != null)
    1560.             {
    1561.                 terrainTextureID = vp_FootstepManager.GetMainTerrainTexture( m_Player.Position.Get(), m_CurrentTerrain );
    1562.                 if(terrainTextureID > m_CurrentTerrain.terrainData.splatPrototypes.Length - 1)
    1563.                     return null;
    1564.             }
    1565.  
    1566.             // return the texture
    1567.             return m_CurrentTerrain == null ? WallRunObject.renderer.material.mainTexture : m_CurrentTerrain.terrainData.splatPrototypes[ terrainTextureID ].texture;
    1568.            
    1569.         }
    1570.     }
    1571.  
    1572.     /// <summary>
    1573.     /// This is copy from FootStepManager, derived from Footstep and made to work only with wallrun
    1574.     /// </summary>
    1575.     protected virtual void WallRunFootstep()
    1576.     {
    1577.         if(m_Controller.Grounded)
    1578.             return;
    1579.  
    1580.         // return if there no texture or surface type is found
    1581.         if(m_Player.WallTexture.Get() == null )
    1582.             return;
    1583.        
    1584.         // return if not wallrunning
    1585.         if(!m_Player.WallRun.Active)
    1586.             return;
    1587.  
    1588.         // loop through the surfaces
    1589.         foreach(vp_FootstepManager.vp_SurfaceTypes st in m_FootstepManager.SurfaceTypes)
    1590.         {
    1591.             // loop through the surfaces textures
    1592.             foreach(Texture tex in st.Textures)
    1593.             {
    1594.                 // if the texture is the same as the wall texture...
    1595.                 if(tex == m_Player.WallTexture.Get())
    1596.                 {
    1597.                     // play random surface sound
    1598.                     m_FootstepManager.PlaySound( st );
    1599.                     break;
    1600.                 }
    1601.             }
    1602.         }
    1603.     }
    1604.  
    1605.     protected virtual Vector3 GetLocalVelocity()
    1606.     {
    1607.         Vector3 localVelocity = m_Controller.Transform.InverseTransformDirection( m_Player.Velocity.Get() );
    1608.         return localVelocity;
    1609.     }
    1610.  
    1611.     protected virtual Vector3 GetNewPosition()
    1612.     {
    1613.         Vector3 newPosition = m_Controller.Transform.position;
    1614.  
    1615.         RaycastHit hit;
    1616.  
    1617.         Vector3 offSetPos = transform.InverseTransformDirection(new Vector3(0,0,1));
    1618.         Vector3 lastWallRunNormal = Quaternion.AngleAxis(-180,Vector3.up) * m_WallRunHitNormal;
    1619.  
    1620.         Ray ray = new Ray(offSetPos, lastWallRunNormal);
    1621.         Physics.Raycast(ray, out hit, 10f);
    1622.  
    1623.         newPosition = hit.point;
    1624.                
    1625.         return newPosition;
    1626.     }
    1627.    
    1628.     /// <summary>
    1629.     /// Plays parkour arm animation.
    1630.     /// </summary>
    1631.     protected virtual void ParkourArmClimb()
    1632.     {
    1633.         if(ParkourArmPrefab != null )
    1634.         {
    1635.             ParkourArmPrefab.SetActive(true);
    1636.  
    1637.             Vector3 armPosition = m_HangRotation ;
    1638.  
    1639.             RaycastHit hit;
    1640.  
    1641.             Physics.Raycast(transform.position, armPosition , out hit);
    1642.  
    1643. //            ParkourArmPrefab.transform.position = new Vector3(hit.point.x, m_ClimbObjectPosition.y, hit.point.z) + transform.InverseTransformDirection(ParkourArmPos);
    1644.  
    1645.             ParkourArmPrefab.transform.position = m_ClimbObjectPosition + transform.InverseTransformDirection(ParkourArmPos);
    1646.            
    1647.             ParkourArmPrefab.transform.rotation = Quaternion.LookRotation(m_HangRotation,Vector3.up);
    1648.             ParkourArmPrefab.animation.CrossFade(ParkourArmClimbAnim.name);    // play anim
    1649.         }
    1650.  
    1651.     }
    1652.  
    1653. }
    1654.  
    1655.  
     
  2. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    the error is in the script "dsa.cs"... can we see that?
     
  3. Bil0n

    Bil0n

    Joined:
    Jun 3, 2015
    Posts:
    4
    I know, and i add this script...
     
  4. dterbeest

    dterbeest

    Joined:
    Mar 23, 2012
    Posts:
    389
    Code (csharp):
    1. public class ac_FPParkour : vp_Component { }
     
    Bil0n likes this.
  5. Bil0n

    Bil0n

    Joined:
    Jun 3, 2015
    Posts:
    4
    Yes, working. Now i have

    Assets/acParkour/Scripts/Gameplay/Player/Local/dsa.cs(23,1): error CS8025: Parsing error


    Code (CSharp):
    1. public class ac_FPParkour : vp_Component { }
    2.  
    3. {
    4.     // anim
    5.     public GameObject ParkourArmPrefab = null ;                    // parkour arm prefab that will be seen during ledgegrab
    6.     public AnimationClip ParkourArmClimbAnim = null;            // parkour's arm ledge climbing animation that will be played.
    7.     public Vector3 ParkourArmPos = Vector3.zero;                
     
  6. ThomasCreate

    ThomasCreate

    Joined:
    Feb 23, 2015
    Posts:
    81
    You just copied dterbeest's code without considering its meaning. He added curly brackets after the class heading to signify where the content will go, but you already have the body of the class, surrounded by its own curly brackets. Just remove "{ }" after ": vp_Component".
     
    Bil0n likes this.
  7. Bil0n

    Bil0n

    Joined:
    Jun 3, 2015
    Posts:
    4
    I import copy this script and now i have this problem.


    Assets/acParkour/Scripts/Gameplay/Player/Local/ac_FPParkour.cs(21,29): error CS0246: The type or namespace name `vp_Component' could not be found. Are you missing a using directive or an assembly reference?



    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. [RequireComponent(typeof(vp_FPController))]
    6.  
    7. public class ac_FPParkour : vp_Component
    8.  
    9. {
    10.     // anim
    11.     public GameObject ParkourArmPrefab = null ;                    // parkour arm prefab that will be seen during ledgegrab
    12.     public AnimationClip ParkourArmClimbAnim = null;            // parkour's arm ledge climbing animation that will be played.
    13.     public Vector3 ParkourArmPos = Vector3.zero;              
    14.  
    15.     // sounds
    16.     protected vp_FootstepManager m_FootstepManager ;            // Can be used to cache the player vp_FootStepManager
    17.     protected Terrain m_CurrentTerrain = null;                    // caches the current terrain the controller is on
    18.        
    19.     // general
    20.     protected CharacterController m_CharacterController = null;    // Can be used to cache the player CharacterController
    21.     protected vp_FPController m_Controller = null;                 // Can be used to cache the players vp_FPController
    22.     protected vp_FPCamera m_Camera = null;                         // Can be used to cache the players vp_FPCamera
    23.     protected ac_FPParkourEventHandler m_Player = null;         // Need this to access the above and the player.
    24.  
    25.     // dash
    26.     public bool Dashing {get {return m_Dashing; } }
    27.     public bool MotorDashDone { get {return m_MotorDashDone; } }
    28.     public int CurrentDash {get {return m_CurrentDash; } }
    29.     public float DashTimer {get {return m_DashTimer; } }
    30.    
    31.     public float DashCooldown = 1f;              
    32.     public float MotorDashForce = 0.50f;      
    33.     public int DashCount = 1;
    34.     public float DashRecoverSpeed = 1.0f;
    35.     public float DashSensitivtiy = 0.25f;
    36.     protected bool m_MotorDashDone = true;
    37.     protected int m_CurrentDash = 0;
    38.     protected float m_DashInputTimer = 0f;
    39.     protected float m_DashTimer = 0f;
    40.     protected bool m_Dashing = false;
    41.     protected float m_CanDashAgain = 0f ;
    42.  
    43.  
    44.     // walljump
    45.     public string IgnoreWallJumpTag = "";                        // tag that disallow Walljump
    46.     public float WallJumpForwardForce = 0.05f;
    47.     public float WallJumpForce = 0.1f;
    48.     public float WallJumpUpForce = 0.3f;
    49.     protected bool m_MotorWallJumpDone = true;
    50.     protected bool m_WallJumpAble = false;
    51.     protected Vector3 m_WallJumpHitNormal;                        // contains info about the wall we collided
    52.  
    53.     // wallhang
    54.     public string IgnoreWallHangTag = "";                        // tag that disallow wallhang
    55.     public bool IsWallHanging {get {return m_IsWallHanging; } }
    56.     public float WallHangDuration = 3.0f;
    57.     public float LosingGripStart = 0.75f;
    58.     public float LosingGripGravity = 0.003f;
    59.     protected float m_WallHangTimer = 0f;
    60.     protected Vector3 m_WallHangHitNormal = Vector3.zero;
    61.     protected bool m_CanWallHang = false;
    62.     protected bool m_IsWallHanging = false;
    63.  
    64.     // doublejump
    65.     public float DoubleJumpForwardForce = 0.15f ;
    66.     public float DoubleJumpForce = 0.4f;
    67.     public int DoubleJumpCount = 1;
    68.     protected bool m_DoubleJumpAble = false;
    69.     protected int m_currentDoubleJump = 1 ;
    70.     protected bool m_MotorDoubleJumpDone = true;
    71.    
    72.     // groundslide
    73.     public bool GroundSliding {get {return m_GroundSliding; } }
    74.     public float MotorGroundSlideForce = 0.2f;
    75.     public float MinBuildUp = 2.0f;
    76.     public float MinSpeedToBuildup = 20.0f;
    77.     public float GroundSlideSpeedMinimum = 2.0f;
    78.     public float GroundSlideCooldown = 1.5f;
    79.     protected float m_GroundSlideBuildup;
    80.     protected float m_CanGroundslideAgain = 0f;
    81.     protected Vector3 m_GroundSlideLookDirection = Vector3.zero;
    82.     protected bool m_GroundSliding = false;
    83.    
    84.     // wallrun
    85.     public string IgnoreWallRunTag = "";            // tag that disallow wallrun
    86.     public Transform WallRunObject {get {return m_WallRunObject; } }
    87.     public bool IsWallRunning {get { return m_IsWallRunning; } }
    88.     public bool IsWallOnRight {get {return m_IsWallOnRight; } }
    89.     public bool IsWallInFront {get {return m_IsWallInFront; } }
    90.  
    91.     public float WallRunGravity = 0.08f;
    92.     public float WallRunTilt = 1.0f;
    93.     public float WallRunDuration = 2.0f;
    94.     public float WallRunUpForce = 0.1f;
    95.     public float WallRunSpeedMinimum = 8.0f ;
    96.     public float WallRunAgainTimeout = 1f;
    97.     public float WallRunRange = 1.0f;                 // the distance to keep from the climbable while climbing
    98.     public float WallRunDismountForce = 0.1f;        // force applied at end of wallrun
    99.     public float WallAngle {get { return m_WallAngle; } }
    100.     public bool WallRunInfinite = false;
    101.     public bool WallRunAutoRotateYaw = false;        // if enabled, camera yaw will be rotated parallel of wallrun direction
    102.  
    103.     protected float m_WallAngle;
    104.     protected float m_WallRunMaxSpeed = 0f;
    105.     protected bool m_WallRunable = false ;
    106.     protected bool m_IsWallOnRight = false;
    107.     protected bool m_IsWallInFront = false;
    108.     protected Transform m_WallRunObject;
    109.     protected bool m_IsWallRunning = false;
    110.     protected float m_WallRunTimer = 0f;
    111.     protected float m_CanWallRunAgain = 0f ;
    112.     protected Vector3 m_WallRunHitPoint = Vector3.zero;
    113.     protected Vector3 m_WallRunHitNormal = Vector3.zero;
    114.     protected Vector3 m_WallRunDismountDirection = Vector3.zero;
    115.     protected Vector3 m_WallRunLookDirection = Vector3.zero;
    116.     private bool autoYawed = false;
    117.    
    118.     // ledge grab
    119.     public string IgnoreLedgeGrabTag = "";                // tag that disallow ledgegrab
    120.     public bool LedgeGrabable { get {return m_LedgeGrabable; } }
    121.     public bool IsLedgeGrabbing { get { return m_IsLedgeGrabbing; } }
    122.     public bool IsHanging { get {return m_IsHanging; } }
    123.     public Vector3 HangPosition {get {return m_HangPosition; } }
    124.     public Vector3 WallNormal {get {return m_ClimbObjectNormal; } }
    125.     public Vector3 ClimbObjectPosition {get {return m_ClimbObjectPosition; } }
    126.     public Vector3 ClimbPositionOffset = Vector3.zero;  
    127.     public float HeadOffset = 0.1f;                        // how high the top-down raycast should start
    128.  
    129.     public float FirstPersonLedgeOffset = 0.4f;
    130.     public float ThirdPersonLedgeOffset = 0.53f;
    131.     public float PullUpSpeed = 0.08f;
    132.     public float MinDistanceToVault =  1.0f;            // check if player can vault instead.
    133.     public float MinDistanceToClimb = 10.0f ;            // check if player is within grabing distance
    134.     public float DistancePlayerToTop ;                    // gets the distance between player and the top of distance
    135.     public float LedgeGrabRange = 1.5f;                    // minimum ray casting range.
    136.     public float LedgeGrabDuration = 0.5f;                // duration of the whole LedgeGrab coroutine
    137.     public float ClimbAlignDuration = 0.4f;                // how fast to align to ledge
    138.     public float ClimbDismountForce = 0.02f;            // additional force applied at end of climb
    139.  
    140.     protected bool m_LedgeGrabable = false;
    141.     protected bool m_IsLedgeGrabbing = false;
    142.     protected bool m_IsHanging = false;
    143.     protected Vector3 m_HangPosOffset = Vector3.zero;
    144.     protected Vector3 m_HangPosition = Vector3.zero;            // position to lerp to when hanging  
    145.     protected Vector3 m_HangRotation = Vector3.zero;
    146.     protected Vector3 m_ClimbObjectPosition = Vector3.zero;        // position to lerp to when climbing
    147.     protected Vector3 m_ClimbObjectNormal = Vector3.zero;
    148.     protected Vector3 m_CachedDirection = Vector3.zero;         // cache the direction to keep proper distance from climbable
    149.     protected Vector2 m_CachedRotation  = Vector2.zero;
    150.     protected Vector3 m_LedgeLeft = Vector3.zero;
    151.     protected Vector3 m_LedgeRight = Vector3.zero;
    152.     protected Transform m_Platform = null;                        // current rigidbody or object in the 'MovableObject' layer that we are standing on
    153.  
    154.     private bool shouldCrouch = false ;
    155.     private bool isLiningUp = false;
    156.    
    157.     // physics
    158.     float targetDamping = 0.15f;
    159.    
    160.     // misc
    161.     public Vector3 LocalVelocity { get {return GetLocalVelocity(); } }
    162.     protected int m_LastWeaponEquipped = 0;                        // cache last weapon equipped
    163.  
    164.     // Use this for initialization
    165.     protected override void  Awake ()
    166.     {
    167.         base.Awake();
    168.  
    169.         // initial setup
    170.         m_Audio = audio;
    171.         m_CharacterController = gameObject.GetComponent<CharacterController>();
    172.         m_Controller = (vp_FPController)transform.root.GetComponentInChildren(typeof(vp_FPController));
    173.         m_Player  = (ac_FPParkourEventHandler)transform.root.GetComponentInChildren(typeof(ac_FPParkourEventHandler));
    174.         m_Camera = GetComponentInChildren<vp_FPCamera>();
    175.         m_Transform = transform;
    176.         m_FootstepManager = (vp_FootstepManager)transform.root.GetComponentInChildren(typeof(vp_FootstepManager));
    177.  
    178.         m_currentDoubleJump = DoubleJumpCount ;
    179.         m_CanWallRunAgain = Time.time;
    180.         m_CanDashAgain = Time.time;
    181.         m_CanGroundslideAgain = Time.time;
    182.  
    183.         // spawn the parkour arm at world origin and hide it
    184.         if(ParkourArmPrefab != null)
    185.         {
    186.             ParkourArmPrefab = (GameObject)Object.Instantiate(ParkourArmPrefab,Vector3.zero,Quaternion.identity);
    187.             ParkourArmPrefab.SetActive(false);
    188.         }
    189.  
    190.  
    191.     }
    192.    
    193.     protected override void Start()
    194.     {
    195.         // setup the correct amount of dash count
    196.         m_CurrentDash = DashCount ;
    197.  
    198.         // hacky way to setwallrun maxspeed from  preset
    199.         m_Player.WallRun.Start();
    200.         m_WallRunMaxSpeed = m_Controller.MotorAcceleration;
    201.         m_Player.WallRun.Stop();
    202.  
    203.     }
    204.  
    205.     /// <summary>
    206.     /// registers this component with the event handler (if any)
    207.     /// </summary>
    208.     protected override void OnEnable()
    209.     {  
    210.  
    211.         if (m_Player != null)
    212.             m_Player.Register(this);
    213.  
    214.         // add the wallrun footstep callback;
    215.         m_Camera.BobStepCallback += WallRunFootstep;
    216.     }
    217.    
    218.     /// <summary>
    219.     /// unregisters this component from the event handler (if any)
    220.     /// </summary>
    221.     protected override void OnDisable()
    222.     {
    223.  
    224.         // unregister this monobehaviour from the player event handler
    225.         if (m_Player != null)
    226.             m_Player.Unregister(this);  
    227.  
    228.         // remove the wallrun footstep callback
    229.         m_Camera.BobStepCallback -= WallRunFootstep;
    230.     }
    231.  
    232.     protected override void Update()
    233.     {
    234.         base.Update();
    235.  
    236.         // handles ledgegrab, walljump and doublejump input
    237.         InputJump();
    238.        
    239.         // handles dash input
    240.         InputDash();
    241.        
    242.         // handles ground slide input
    243.         InputGroundSlide();
    244.        
    245.         // handles wallhang input
    246.         InputWallHang();
    247.  
    248.     }
    249.  
    250.     protected override void FixedUpdate()
    251.     {
    252.         // handle ledgegrab raycast and collision check
    253.         UpdateLedgeGrab();
    254.  
    255.         // handle wallrun raycast and motion during wallrunning
    256.         UpdateWallrun();
    257.  
    258.         // apply a camera Z tilt when wallrun
    259.         UpdateWallrunTilt();
    260.  
    261.         // limit groundsliding based on speed and duration
    262.         UpdateGroundSliding();
    263.  
    264.         // update dash cooldown and dash regen
    265.         UpdateDash();
    266.  
    267.         // handles a parkour hanging before transitioning to parkour climb
    268.         UpdateLedgeHanging();
    269.  
    270.         // handles sticking to the wall
    271.         UpdateWallHang();
    272.  
    273. //        UpdatePhysics();
    274.     }
    275.    
    276.     /// <summary>
    277.     /// Takes controllercollider hit and convert to raycast
    278.     /// before passing it over for wall parkour related activity
    279.     /// as raycast is much more accurate then controllercolliderhit
    280.     /// </summary>
    281.     protected virtual void OnControllerColliderHit(ControllerColliderHit hit)
    282.     {
    283.         RaycastHit raycastHit;
    284.  
    285.         Vector3 localpos = transform.root.position + new Vector3 (0,m_CharacterController.height*0.8f,0);
    286.  
    287.         Physics.Raycast( localpos , hit.point- localpos , out raycastHit, WallRunRange);
    288.  
    289.         // check if the surface allows wallrun.
    290.         CheckWallRun(raycastHit);
    291.  
    292.         // check if the surface allows walljump and wallhang
    293.         CheckWallJump(raycastHit);
    294.  
    295.         // check if the surface allows wallhang
    296.         CheckWallHang(raycastHit);
    297.     }
    298.  
    299.     protected virtual bool CanStart_Run()
    300.     {
    301.         // can only run from a forward
    302.         if (m_Player.InputMoveVector.Get().y <= 0)
    303.             return false;
    304.         // can't start running while crouching
    305.         if (m_Player.Crouch.Active)
    306.             return false;
    307.        
    308.         return true;
    309.        
    310.     }
    311.  
    312.     protected virtual bool CanStart_Crouch()
    313.     {
    314.         // can't start running while crouching
    315.         if (m_Player.WallRun.Active)
    316.             return false;
    317.        
    318.         return true;
    319.        
    320.     }
    321.    
    322.     protected virtual bool CanStart_WallRun()
    323.     {
    324.         if(WallRunDuration == 0)  
    325.             return false;
    326.         if(Time.time < m_CanWallRunAgain)    // wallrun is refreshing
    327.             return false;
    328.         if (m_Controller.Grounded)            // Can't wallrun on the ground
    329.             return false;
    330.         if (m_LedgeGrabable)                // If can ledge grab, should ledge grab instead
    331.             return false;
    332.         if (m_IsWallRunning )                // Already wallrunning      
    333.             return false;
    334.         if (!m_WallRunable)                    // Surface is not wallrunable
    335.             return false;
    336.         if (m_Player.Velocity.Get().magnitude < WallRunSpeedMinimum) // Not fast not enough
    337.             return false;
    338. //        if (!m_Player.Run.Active)            // Must start from a Run
    339. //            return false;
    340.         if (m_Player.Crouch.Active)            // cannot wallrun while crouching
    341.             return false;
    342.         if (GetLocalVelocity().z < -1)        // cannot wallrun backwards
    343.             return false;
    344.  
    345.         return true;
    346.        
    347.     }
    348.  
    349.     protected virtual bool CanStart_WallHang()
    350.     {
    351.         if(m_Controller.Grounded)            // still grounded
    352.             return false;
    353.         if(!m_CanWallHang)                    // not near a wall
    354.             return false;
    355.         if(m_IsWallHanging)                    // already wallhanging
    356.             return false;
    357.  
    358.         return true;
    359.     }
    360.  
    361.     protected virtual bool CanStart_GroundSlide()
    362.     {
    363.         if(m_GroundSlideBuildup < MinBuildUp)                // run distance too short
    364.             return false;
    365.         if(Time.time < m_CanGroundslideAgain)            // groundslide is still refreshing
    366.             return false;
    367.         if (vp_Input.GetAxisRaw("Vertical") != 1)        // Can only groundslide if going forward
    368.             return false;
    369.         if (!m_Controller.Grounded)                        // Not on ground, cannot groundslide
    370.             return false;
    371.         if(!m_Player.Run.Active)                        // Can only groundslide from a run
    372.             return false;
    373.  
    374.         return true;
    375.     }
    376.  
    377.     protected virtual bool CanStart_Dash()
    378.     {
    379.         // ran out of dash counter
    380.         if (m_CurrentDash <= 0)
    381.             return false;
    382.  
    383.         if (!m_MotorDashDone)
    384.             return false;
    385.  
    386.         if (Time.time < m_CanDashAgain)
    387.             return false;
    388.  
    389.         // if there's no movement input at all
    390.         if (vp_Input.GetAxisRaw("Vertical") == 0 && vp_Input.GetAxisRaw("Horizontal") == 0)
    391.             return false;
    392.  
    393.         if (m_IsHanging)
    394.             return false;
    395.  
    396.         if (m_Dashing)
    397.             return false;
    398.  
    399.         if (m_IsWallRunning)
    400.             return false;
    401.  
    402.         if (m_IsLedgeGrabbing)
    403.             return false;
    404.  
    405.         return true;
    406.     }
    407.    
    408.     protected virtual bool CanStart_WallJump()
    409.     {
    410.         if (!m_Player.MotorJumpDone.Get())    // if we are holding jump
    411.             return false;
    412.  
    413.         if (!m_WallJumpAble)                // can't wall jump without wall contact
    414.             return false;
    415.  
    416.         if (m_WallJumpHitNormal == new Vector3 (0,0,0)) // we can't walljump from ground
    417.             return false;
    418.  
    419.         if (m_LedgeGrabable)
    420.             return false;
    421.  
    422.         if (m_Controller.Grounded)            // Debug.Log ("Still on ground");
    423.             return false;
    424.         return true;
    425.     }
    426.    
    427.     protected virtual bool CanStart_DoubleJump()
    428.     {
    429.  
    430.         if (m_WallJumpAble)                    // check if we can walljump instead
    431.             return false;
    432.  
    433.         if (!m_MotorDoubleJumpDone)            // Still double jumping
    434.             return false;
    435.  
    436.         if (!m_DoubleJumpAble)                // Cannot doublejump
    437.             return false;
    438.  
    439.         if (m_currentDoubleJump <= 0)            // Ran out of airjump counter
    440.             return false;
    441.    
    442.         if (m_Controller.Grounded)            // Are we still on the ground
    443.             return false;
    444.  
    445.         if (!m_Player.MotorJumpDone.Get())    // Still jumping
    446.             return false;
    447.  
    448.         if (!m_MotorWallJumpDone)            // Still wall jumping
    449.             return false;
    450.  
    451.         if (m_IsWallHanging)                // Still wall hanging
    452.             return false;
    453.        
    454.         if (m_IsLedgeGrabbing)            // Still parkour climbing
    455.             return false;
    456.  
    457.         if (m_IsWallRunning)                // Still wallrunning
    458.             return false;
    459.  
    460.         return true;
    461.        
    462.     }
    463.  
    464.     /// <summary>
    465.     /// Prevent automatically jumping upon loading from a wall jump or doublejump if player holds jump
    466.     /// </summary>
    467.     protected virtual bool CanStart_Jump()
    468.     {
    469.         if(!m_MotorDoubleJumpDone)
    470.             return false;
    471.  
    472.         if(!m_MotorWallJumpDone)
    473.             return false;
    474.  
    475.         return true;
    476.     }
    477.    
    478.     protected virtual bool CanStart_LedgeGrab()
    479.     {
    480.  
    481.         if(m_Controller.Grounded)            // can't ledgegrab if grounded
    482.             return false;
    483.         if(m_IsLedgeGrabbing)                // is already ledgegrabbing
    484.         {
    485.             m_Player.LedgeGrab.TryStop();
    486.             return false;
    487.         }
    488.         if(m_LedgeGrabable == false)
    489.             return false;
    490.  
    491.         return true;
    492.        
    493.     }
    494.  
    495.     /// <summary>
    496.     /// Once WallRun is approved, this will setup all the variables to allow wallrunning
    497.     /// </summary>
    498.     protected virtual void OnStart_WallRun()
    499.     {
    500.         // setup the variables
    501.         m_IsWallRunning = true;
    502.         m_CanWallHang = true;
    503.         m_WallJumpAble = true;
    504.  
    505.         // reset camera initial rotation ,otherwise the camera
    506.         // will be rotated with the offset it had at spawn-time
    507.         m_Camera.SetRotation(m_Camera.Transform.eulerAngles, false, true);
    508.  
    509.         m_Player.Jump.Stop();
    510.        
    511.         // stop any movement on our controller.
    512.         // Comment this off if you want to maintain the momentum when wallrunning
    513.         m_Player.Stop.Send();
    514.  
    515.         // Gives a nice push upwards at start of wallrunning
    516.         m_Controller.AddSoftForce(transform.up*WallRunUpForce,WallRunDuration*0.5f);
    517.  
    518.         m_CachedDirection = m_Transform.forward;
    519.        
    520.     }
    521.  
    522.     protected virtual void OnStart_WallHang()
    523.     {
    524.         // setup the variables
    525.         m_CanWallHang = false;
    526.         m_IsWallHanging = true;
    527.         m_WallJumpAble = true;
    528.  
    529.         // stop wallrun
    530.         m_Player.WallRun.Stop();
    531.  
    532.         // stop controller completely
    533.         m_Controller.Stop();
    534.     }
    535.  
    536.     protected virtual void OnStart_GroundSlide()
    537.     {
    538.         m_Player.Run.Stop();
    539.         m_GroundSliding = true;
    540.  
    541.         // stores current look direction
    542.         m_GroundSlideLookDirection = m_Controller.transform.forward;
    543.         m_CachedRotation = m_Player.Rotation.Get ();
    544.  
    545.         // pushes player forward over a 10 frames
    546.         m_Controller.AddSoftForce(transform.forward*MotorGroundSlideForce,10f);
    547.  
    548.     }
    549.  
    550.     protected virtual void OnStart_Dash()
    551.     {
    552.         // decrease available dashcount by one
    553.         m_CurrentDash --;
    554.         m_Dashing = true;
    555.         m_MotorDashDone = false;
    556.  
    557.         // stores player inputMove vector as dashDirection
    558.         Vector3 dashDirection = transform.TransformDirection(new Vector3 (m_Player.InputMoveVector.Get().x,0,
    559.                                                                           m_Player.InputMoveVector.Get().y));
    560.  
    561.         // apply force to controller based dashDirection
    562.         m_Controller.AddSoftForce(dashDirection*MotorDashForce,5f);
    563.  
    564.     }
    565.  
    566.     protected virtual void OnStart_WallJump()
    567.     {
    568.         // stop jumping to prevent creating a double wall jump
    569.         m_Player.Jump.Stop();
    570.         // if we are wallrunning or wallhanging, stops immediately
    571.         m_Player.WallHang.Stop();
    572.         m_Player.WallRun.Stop();
    573.  
    574.         // setup for walljump
    575.         m_Player.MotorJumpDone.Set(false);
    576.         m_MotorWallJumpDone = false;
    577.         m_CanWallHang = false;
    578.         m_WallJumpAble = false;
    579.  
    580.         // store local velocity
    581. //        Vector3 localVelocity = m_Controller.Transform.InverseTransformDirection( m_Player.Velocity.Get() );
    582.  
    583.         Vector3 localVelocity = GetLocalVelocity() * 0.1f;
    584.  
    585.         // store MotorThrottle from walljump Normal
    586.         Vector3 tempMotorThrottle = (m_WallJumpHitNormal*WallJumpForce) +                                        // wall jump normal direction
    587.             (m_Camera.transform.TransformDirection(Vector3.forward)*(WallJumpForwardForce * localVelocity.z)) + // nudge it towards camera direction
    588.                                     new Vector3 (0,(WallJumpUpForce / Time.timeScale),0);                        // wall jump up force
    589.  
    590.         // perform impulse jump
    591.         m_Player.FallSpeed.Set( (Physics.gravity.y * (m_Controller.PhysicsGravityModifier * 0.002f)) );
    592.         m_Player.MotorThrottle.Set(tempMotorThrottle);
    593.     }
    594.  
    595.     protected virtual void OnStart_DoubleJump()
    596.     {
    597.         // setup for double jump
    598.         m_MotorDoubleJumpDone = false ;
    599.         m_DoubleJumpAble = false;
    600.  
    601.         // decrease the current double jump count left by 1
    602.         m_currentDoubleJump -= 1;
    603.  
    604.         m_Controller.StopSoftForce();
    605.  
    606.         // store current MotorThrottle
    607.         Vector3 tempMotorThrottle = m_Player.MotorThrottle.Get();
    608.         tempMotorThrottle.y = (DoubleJumpForce / Time.timeScale);
    609.  
    610.         // perform impulse jump
    611.         m_Player.FallSpeed.Set( (Physics.gravity.y * (m_Controller.PhysicsGravityModifier * 0.002f)) );
    612.         m_Player.MotorThrottle.Set(tempMotorThrottle);
    613.  
    614.  
    615.         // give it's a little nudge towards player's direction
    616.         Vector3 doubleJumpDirection = transform.TransformDirection(new Vector3 (
    617.             m_Player.InputMoveVector.Get().x,0,m_Player.InputMoveVector.Get().y));
    618.  
    619.         m_Controller.AddForce( doubleJumpDirection * DoubleJumpForwardForce);
    620.  
    621.     }
    622.  
    623.     protected virtual void OnStart_LedgeGrab()
    624.     {
    625.         // setup for ledgegrab
    626.         m_CanWallHang = false;
    627.         m_IsWallHanging = false ;
    628.         m_IsLedgeGrabbing = true;
    629. //        if(m_Platform != null)
    630. //            m_Player.Platform.Set(m_Platform);
    631.  
    632.  
    633.         // stop jump
    634.         m_Player.Jump.Stop();
    635.  
    636.         // stop the controller
    637.         m_Player.Stop.Send();
    638.  
    639.         // disallow player control while ledgegrab
    640.         m_Player.InputAllowGameplay.Set(false);
    641.  
    642.         // check the height of the obstacle, if it's over vault height then it will do ledge grab
    643.         if(DistancePlayerToTop < MinDistanceToClimb && DistancePlayerToTop > MinDistanceToVault)
    644.             StartCoroutine(LineUpLedge());
    645.         else
    646.             StartCoroutine(ClimbLedge(ClimbPositionOffset));    //else it will auto vault
    647.  
    648.     }
    649.  
    650.     /// <summary>
    651.     /// This lerps the camera towards the direction of the wallrunning
    652.     ///
    653.     protected virtual IEnumerator LineUpWallRun()
    654.     {
    655.  
    656.         Quaternion startingRotation = m_Camera.transform.rotation; // cache start rotation
    657.         Quaternion endRotation ; // cache end rotation
    658.        
    659.         endRotation = Quaternion.LookRotation(m_WallRunLookDirection,Vector3.up);
    660.  
    661.         float t = 0;
    662.        
    663.         float duration = 0.2f;
    664.         while(t < 1)
    665.         {  
    666.             t += Time.deltaTime/duration;
    667.            
    668.             Quaternion newRotation = Quaternion.Slerp(startingRotation, endRotation, t);
    669.             m_Player.Rotation.Set(new Vector2( newRotation.eulerAngles.x , WallRunAutoRotateYaw ? newRotation.eulerAngles.y : m_Player.Rotation.Get().y ));
    670.            
    671.             yield return new WaitForEndOfFrame();
    672.         }
    673.  
    674.         m_CachedDirection = m_Camera.Transform.forward;
    675.        
    676.     }
    677.  
    678.     /// <summary>
    679.     /// Lerps players towards the ideal ledgegrab position
    680.     /// </summary>
    681.     protected virtual IEnumerator LineUpLedge()
    682.     {
    683.         // setup for line up ledge
    684.         isLiningUp = true;
    685.         m_IsHanging = true;
    686.        
    687.         m_Camera.SetRotation(m_Camera.Transform.eulerAngles, false, true);
    688.        
    689.         // stop player
    690.         m_Player.Stop.Send();
    691.        
    692.         // store the current weapon
    693.         m_LastWeaponEquipped = m_Player.CurrentWeaponIndex.Get();
    694.        
    695.         // put the weapon away
    696.         vp_Timer.In(0.0f, delegate() { m_Player.SetWeapon.TryStart(0); } );
    697.        
    698.         // play parkour animation.
    699.         if(ParkourArmPrefab != null && ParkourArmClimbAnim != null)
    700.             vp_Timer.In(0.1f, ParkourArmClimb);
    701.        
    702.         Quaternion startingRotation = m_Camera.transform.rotation; // cache start rotation
    703.         Quaternion endRotation = Quaternion.LookRotation(m_HangRotation); // cache end rotation
    704.  
    705.         Vector3 startPosition = m_Player.Position.Get(); // cache the start position
    706.  
    707.         // position player about 0.5f in negative z away from ledgegrab position to
    708.         // minimize player being too close to the wall
    709.         Vector3 posOff ;
    710.  
    711.         posOff = m_ClimbObjectNormal*(m_Player.IsFirstPerson.Get() ? FirstPersonLedgeOffset : ThirdPersonLedgeOffset);
    712.  
    713.         Vector3 endPosition = m_HangPosition + posOff; // cache the end position
    714.  
    715.         float t = 0;
    716.        
    717.         while(t < 1)
    718.         {
    719.             t += Time.deltaTime/(ClimbAlignDuration);
    720.  
    721.             Quaternion newRotation = Quaternion.Slerp(startingRotation, endRotation, t);
    722.             m_Player.Rotation.Set(new Vector2( newRotation.eulerAngles.x , newRotation.eulerAngles.y));
    723.  
    724.             // Slerp players from current position to target position by t
    725.             Vector3 newPosition = Vector3.Slerp(startPosition, endPosition, t);
    726.  
    727.             m_Player.Position.Set(newPosition);
    728.  
    729.             m_Player.Stop.Send();
    730.             yield return new WaitForEndOfFrame();
    731.         }
    732.         m_CachedDirection = m_Camera.Transform.forward;
    733.         m_CachedRotation = m_Player.Rotation.Get();
    734.  
    735.  
    736. //        m_CachedRotation = new Vector2 (m_HangRotation.x, m_HangRotation.y);
    737.  
    738.         m_HangPosOffset = m_HangPosition + new Vector3 (0,0.5f,0);
    739.         isLiningUp = false;
    740.  
    741.     }
    742.  
    743.     /// <summary>
    744.     /// This is the actual function that will be used to climb obstacle or vault obstacle
    745.     /// It is triggered after OnStart_ClimbLedge
    746.     /// Takes a vector3 as a position offset
    747.     /// </summary>
    748.     protected virtual IEnumerator ClimbLedge(Vector3 posOff)
    749.     {
    750.         // disable player input and setup for climbledge
    751.         m_Player.InputAllowGameplay.Set(false);
    752.         m_IsHanging = false;
    753.         m_Player.Stop.Send();
    754.  
    755.         m_Player.ClimbingLedge.Send();
    756.         Vector3 startPosition = m_Player.Position.Get(); // cache the start position
    757.         m_CachedRotation = m_Player.Rotation.Get();    // cache the start rotation
    758.  
    759.         // convert positionOffset into controller's local space
    760.         posOff = m_Controller.Transform.TransformDirection(posOff);
    761.        
    762.         Vector3 endPosition = m_ClimbObjectPosition + posOff; // cache the end position
    763.  
    764.  
    765.         float t = 0;
    766.        
    767.         while(t < 1)
    768.         {
    769.             // lerp player current position to target position
    770.             t += Time.deltaTime/LedgeGrabDuration;
    771.             Vector3 newPosition = Vector3.Slerp(startPosition, endPosition, t);
    772.             m_Player.Position.Set(newPosition);
    773.             m_Player.Stop.Send();
    774.             yield return new WaitForEndOfFrame();
    775.         }
    776.  
    777.         // turn off ledgegrabbing, as we are done climbing
    778.         m_IsLedgeGrabbing = false;
    779.  
    780.         // equip cache weapon
    781.         m_Player.SetWeapon.TryStart(m_LastWeaponEquipped);
    782.         Vector3 force = gameObject.transform.root.forward * ClimbDismountForce;
    783.         force.y = ClimbDismountForce * 0.5f;    // dismounting at top: add slight up-force (push forward & up)
    784.         m_Player.Stop.Send();
    785.         m_Controller.AddForce(force);
    786.         m_Player.LedgeGrab.Stop();
    787.         m_Player.SetState("Default", true, true);
    788.         m_LedgeGrabable = false;
    789.  
    790.         // return control back to player
    791.         m_Player.InputAllowGameplay.Set(true);
    792.     }
    793.    
    794.     protected virtual IEnumerator ShimmyLedge(Vector3 posOff)
    795.     {
    796.         // disable player input and setup for climbledge
    797.         m_Player.InputAllowGameplay.Set(false);
    798.         m_Player.Stop.Send();
    799.        
    800.         Vector3 startPosition = m_Player.Position.Get(); // cache the start position
    801.  
    802.         Vector3 endPosition = posOff; // cache the end position
    803.        
    804.        
    805.         float t = 0;
    806.        
    807.         while(t < 1)
    808.         {
    809.             // lerp player current position to target position
    810.             t += Time.deltaTime/1f;
    811.             Vector3 newPosition = Vector3.Slerp(startPosition, endPosition, t);
    812.             m_Player.Position.Set(newPosition);
    813.             m_Player.Stop.Send();
    814.             yield return new WaitForEndOfFrame();
    815.         }
    816.  
    817.         // return control back to player
    818.         m_Player.InputAllowGameplay.Set(true);
    819.     }
    820.  
    821.     protected virtual void OnStop_WallRun()
    822.     {
    823.         autoYawed = false;
    824.         m_WallRunTimer = 0f;
    825.         m_CanWallHang = false;
    826.         m_WallJumpAble = false;
    827.         m_IsWallRunning = false;
    828.         m_DoubleJumpAble = true;
    829.         m_currentDoubleJump = DoubleJumpCount ;
    830.        
    831.         m_Player.Interactable.Set(null);
    832.  
    833.         m_CanWallRunAgain = Time.time + WallRunAgainTimeout;
    834.         m_Player.SetState("Default");
    835.  
    836.     }
    837.  
    838.     protected virtual void OnStop_WallHang()
    839.     {
    840.         m_IsWallHanging = false;
    841.     }
    842.    
    843.     protected virtual void OnStop_GroundSlide()
    844.     {
    845.         m_Player.Run.Stop();
    846.         m_GroundSliding = false;
    847.         m_CanGroundslideAgain = Time.time + GroundSlideCooldown;
    848.         m_CachedRotation = m_Player.Rotation.Get();
    849.     }
    850.  
    851.     protected virtual void OnStop_Dash()
    852.     {
    853.         m_Dashing = false;
    854.         m_MotorDashDone = true;
    855.         m_CanDashAgain = Time.time + DashCooldown;
    856.     }
    857.  
    858.     protected virtual void OnStop_DoubleJump()
    859.     {
    860.         m_DoubleJumpAble = true;
    861.         m_MotorDoubleJumpDone = true;
    862.        
    863.     }
    864.  
    865.     protected virtual void OnStop_WallJump()
    866.     {
    867.         m_Player.MotorJumpDone.Set(true);
    868.         m_MotorWallJumpDone = true ;
    869.         m_CanWallHang = false;
    870.         m_WallJumpAble = false;
    871.         m_DoubleJumpAble = true;
    872.         m_currentDoubleJump = DoubleJumpCount ;
    873.     }
    874.  
    875.     protected virtual void OnStop_LedgeGrab()
    876.     {
    877.         m_LedgeGrabable = false;
    878.         m_IsLedgeGrabbing = false;
    879.         m_IsHanging = false;
    880.  
    881. //        m_Platform = null ;
    882. //        m_Player.Platform.Set(m_Platform);
    883.  
    884.         m_Player.WallHang.Stop ();
    885.         if(shouldCrouch)
    886.         {
    887.             m_Player.Crouch.Start();
    888.         }
    889.         else
    890.             m_Player.SetState("Default", true, true);
    891.  
    892.         // hides parkour arm
    893.         if(ParkourArmPrefab != null)
    894.             ParkourArmPrefab.SetActive(false);
    895.  
    896.     }
    897.  
    898.     /// <summary>
    899.     /// Handles when player is hanging on to the ledge before they climb up.
    900.     /// </summary>
    901.     protected virtual void UpdateLedgeHanging()
    902.     {        
    903.         // no need to run through here if grounded
    904.         if(m_Controller.Grounded)
    905.             return;
    906.  
    907.         // no need to run through here if we aren't climbing
    908.         if(m_Player == null || !m_IsLedgeGrabbing)
    909.             return;
    910.  
    911.         // still lining up
    912.         if(isLiningUp)
    913.             return;
    914.  
    915.         // we aren't hanging so no point coming through here
    916.         if(!m_IsHanging)
    917.             return;
    918.  
    919.         // stops all run and wallrun activity
    920.         m_Player.Run.Stop();
    921.         m_Player.WallRun.Stop();
    922.  
    923.         // set gravity to 0
    924.         m_Controller.PhysicsGravityModifier = 0.0f;
    925.  
    926.         // limit player's view so they could only see 90 degrees to the left and right only
    927.         m_Camera.RotationYawLimit = new Vector2(m_CachedRotation.y - 50,  m_CachedRotation.y + 50);
    928.         m_Camera.RotationPitchLimit = new Vector2(90, -90);
    929.  
    930.         // stops player controller
    931.         m_Controller.Stop();
    932.  
    933.         // store players current position
    934.         Vector3 pos = m_Player.Position.Get() ;
    935.  
    936.         // Below is to simulate player building up momentum from the hanging to climbing up the ledge
    937.  
    938.         //if we reach the threshold, climb up the ledge
    939.         if(vp_Input.GetAxisRaw("Vertical") > 0)
    940.         {
    941.             StartCoroutine(ClimbLedge(ClimbPositionOffset));
    942.             return;
    943.         }
    944.  
    945.         // Build up momentum when pressing forward
    946.         if(vp_Input.GetAxisRaw("Vertical") > 0 && pos.y < m_HangPosOffset.y)
    947.         {
    948.             pos += new Vector3(0,PullUpSpeed,0);
    949.             m_Player.Position.Set(pos); // simulate moving upward
    950.         }
    951.         // drops down the default hanging position if there's no input
    952.         if(vp_Input.GetAxisRaw("Vertical") == 0 && pos.y > m_HangPosition.y)
    953.         {
    954.             pos -= new Vector3(0,PullUpSpeed,0);
    955.             m_Player.Position.Set(pos); // move back down
    956.         }
    957.  
    958.         // stop hanging and drop player down
    959.         if(vp_Input.GetAxisRaw("Vertical") < 0 || vp_Input.GetButton("Crouch"))
    960.         {
    961.             m_Player.LedgeGrab.Stop();
    962.             m_CachedRotation = m_Player.Rotation.Get();
    963.             m_Camera.SetRotation(m_Camera.Transform.eulerAngles, false, true);
    964.             m_Controller.AddForce(-m_Controller.Transform.forward * ClimbDismountForce);
    965.  
    966.             // reset back to default and give player control
    967.             m_Player.SetState("Default");
    968.             m_Player.SetWeapon.TryStart(m_LastWeaponEquipped);
    969.             m_Player.InputAllowGameplay.Set(true);
    970.  
    971.             // hide parkour arm
    972.             if(ParkourArmPrefab != null)
    973.                 ParkourArmPrefab.SetActive(false);
    974.         }
    975.     }
    976.  
    977.     /// <summary>
    978.     /// Handles the logic for wallhanging.
    979.     /// </summary>
    980.     protected virtual void UpdateWallHang()
    981.     {
    982.         if(!m_Player.WallHang.Active)                        // we are not currently wallhanging
    983.             return;
    984.         if(m_WallHangTimer >= WallHangDuration*LosingGripStart)            // if we are near the end of the wallhang duration
    985.             m_Controller.PhysicsGravityModifier = LosingGripGravity;    // set gravity to a low value to simulate slipping
    986.  
    987.         if(m_WallHangTimer >= WallHangDuration)                // we are over the duration allowed
    988.         {
    989.             m_WallHangTimer = 0;                            // reset the timer
    990.             m_Player.WallHang.TryStop();                    // and stop wallhanging
    991.             return;
    992.         }
    993.  
    994.         m_WallHangTimer += Time.deltaTime;          
    995.  
    996.     }
    997.  
    998.     /// <summary>
    999.     /// Handles the logic to stop groundsliding when it is active
    1000.     /// </summary>
    1001.     protected virtual void UpdateGroundSliding()
    1002.     {
    1003.         // This checks if player has been running forward for a predetermined amount of seconds
    1004.         // If true, then only could player attempt to groundslide.
    1005.         // This is to prevent from spamming groundslide infinitely.
    1006.         if(!m_Player.GroundSlide.Active && m_Player.Velocity.Get().magnitude > MinSpeedToBuildup)
    1007.             m_GroundSlideBuildup += Time.deltaTime;
    1008.         else
    1009.             m_GroundSlideBuildup = 0f;
    1010.  
    1011.         if(m_Player.GroundSlide.Active)
    1012.         {
    1013.             // constraint player transform to only look forward
    1014.             transform.rotation = Quaternion.LookRotation(m_GroundSlideLookDirection,Vector3.up);
    1015.  
    1016.             // limit camera to only be able to left and right
    1017.             m_Camera.RotationYawLimit = new Vector2(m_CachedRotation.y - 120,  m_CachedRotation.y + 120);
    1018.            
    1019.             // stops groundsliding if we are too slow, preventing sliding up ramp or infinite sliding
    1020.             if(m_Player.Velocity.Get().magnitude < GroundSlideSpeedMinimum )
    1021.                 m_Player.GroundSlide.Stop();
    1022.         }
    1023.     }
    1024.  
    1025.     /// <summary>
    1026.     /// Handles the cooldown logic for dashing
    1027.     /// </summary>
    1028.     protected virtual void UpdateDash()
    1029.     {
    1030.  
    1031.         if(m_CurrentDash > DashCount)        // we are over the dashcount
    1032.         {
    1033.             m_DashTimer = 0 ;                // reset timer
    1034.             m_CurrentDash = DashCount ;        // set it to the max alloawed
    1035.             return;
    1036.         }
    1037.  
    1038.         // we reached cooldown
    1039.         if(m_CurrentDash < DashCount && m_DashTimer >= DashRecoverSpeed)
    1040.         {
    1041.             m_DashTimer = 0 ;                // reset timer
    1042.             m_CurrentDash ++;                // add one more dash counter
    1043.             return;
    1044.         }
    1045.  
    1046.         // buildup  to cooldown
    1047.         if(m_CurrentDash < DashCount && m_DashTimer < DashRecoverSpeed)
    1048.             m_DashTimer += Time.deltaTime;
    1049.     }
    1050.  
    1051.     /// <summary>
    1052.     /// Handles logic for LedgeGrab. Cast a ray that is in front of the controller
    1053.     /// and returns the climbing position if within climbing distance
    1054.     /// Depending on the height of the obstacle, will either auto climb or go to ledge hanging
    1055.     /// </summary>
    1056.     protected virtual void UpdateLedgeGrab()
    1057.     {
    1058. //        if(m_Controller.Grounded)            // we are still on the ground
    1059. //            return;
    1060. //
    1061. //        if(m_IsLedgeGrabbing)                // already ledgegrabbing
    1062. //            return;
    1063. //
    1064. //        if(m_IsHanging)                        // we are currently hanging
    1065. //            return;
    1066.  
    1067.         if(LedgeGrabRange == 0 )            // ledgegrab disabled.
    1068.             return;
    1069.  
    1070.         RaycastHit checkCeilingHit ;      
    1071.  
    1072.         // check if there's a ceiling above while attempting to ledgegrab
    1073.         // if true, we are inside building, abort ledge grab
    1074.         if(Physics.SphereCast(transform.position,m_CharacterController.radius,Vector3.up, out checkCeilingHit, 2f))
    1075.                 return;
    1076.  
    1077.         // in the air and we are moving forward.
    1078.         if(!m_Controller.Grounded && GetLocalVelocity().z > 0)
    1079.         {
    1080.             m_Player.LedgeGrab.TryStart();    // automatically try to start LedgeGrab
    1081.         }
    1082.  
    1083.        
    1084.         RaycastHit hit;                        // stores collider hit in front of controller  
    1085.         RaycastHit topHit;                    // stores ceiling hit on top of climb position
    1086.         GameObject climbObject;
    1087.  
    1088.         // cast a ray forward about chest height to see if there's any climbable object
    1089.         if (Physics.Raycast( transform.root.position + new Vector3 (0,m_CharacterController.height*0.8f,0),
    1090.                                transform.root.forward, out hit, LedgeGrabRange, vp_Layer.Mask.ExternalBlockers))
    1091.         {
    1092.             if(!string.IsNullOrEmpty(IgnoreLedgeGrabTag))        // If tag is not empty
    1093.             {
    1094.                 if(hit.transform.tag == IgnoreLedgeGrabTag)        // Hit a ignore ledgegrab tag object
    1095.                     return;
    1096.             }
    1097.  
    1098.             Debug.DrawRay(hit.point, hit.normal, Color.green);
    1099.  
    1100.             climbObject = hit.transform.gameObject;
    1101.  
    1102.             if(hit.normal.y >  0.5f)    // wall is not vertically flat
    1103.                 return;
    1104.  
    1105. //            float height = hit.transform.localScale.y * hit.collider.bounds.size.y;// finds the height of collider
    1106.             float height = m_CharacterController.height + HeadOffset;
    1107.             float topMost;                                    // get the top climbing position based on raycast and climbObjectHeight
    1108.  
    1109.             Vector3 offset = hit.point + transform.root.TransformDirection(0,height,0.05f);
    1110.  
    1111.             Debug.DrawRay(offset, -transform.root.up, Color.blue);
    1112.  
    1113.  
    1114.             if(Physics.Raycast( offset, -transform.root.up, out topHit, LedgeGrabRange*2f, vp_Layer.Mask.ExternalBlockers))
    1115.             {
    1116.                 if(topHit.normal.y < 0.9f)
    1117.                     return;
    1118.  
    1119.                 if(topHit.point.y < hit.point.y || topHit.point.y < transform.position.y)
    1120.                     return;
    1121.  
    1122.                 if(topHit.transform.gameObject != climbObject)
    1123.                     return;
    1124.  
    1125.                 Debug.DrawRay(topHit.point, topHit.normal, Color.red);
    1126.  
    1127. //                if (topHit.collider.gameObject.layer == vp_Layer.MovableObject)
    1128. //                {
    1129. //                    m_Platform = topHit.transform;
    1130. //                }
    1131. //                else
    1132. //                    m_Platform = null;
    1133.  
    1134.                 topMost = topHit.point.y+0.1f;
    1135.  
    1136.                 if(m_Player.IsFirstPerson.Get())
    1137.                     m_HangPosition = new Vector3(hit.point.x,topMost-2.2f,hit.point.z);
    1138.                 else
    1139.                     m_HangPosition = new Vector3(hit.point.x,topMost-1.8f,hit.point.z);
    1140.  
    1141.                 m_HangRotation = Quaternion.AngleAxis(-180,Vector3.up) * hit.normal;
    1142.                 m_ClimbObjectPosition = new Vector3(hit.point.x,topMost,hit.point.z);
    1143.                 m_ClimbObjectNormal = hit.normal;
    1144.                 DistancePlayerToTop = Vector3.Distance(m_ClimbObjectPosition,new Vector3(m_ClimbObjectPosition.x,transform.root.position.y,m_ClimbObjectPosition.z));
    1145.  
    1146.                 Vector3 posOff = m_Controller.Transform.TransformDirection(ClimbPositionOffset);
    1147.  
    1148.                 if (DistancePlayerToTop < MinDistanceToClimb )
    1149.                 {
    1150.                     if(Physics.SphereCast(new Ray(    m_ClimbObjectPosition+posOff, Vector3.up),
    1151.                                           m_CharacterController.radius,
    1152.                                           m_CharacterController.height - (m_CharacterController.radius) + 0.01f))
    1153.                         shouldCrouch = true;
    1154.                     else
    1155.                     {
    1156.                         shouldCrouch = false;
    1157.                     }
    1158.  
    1159.                     m_LedgeGrabable = true ;                  
    1160.                    
    1161.                 }
    1162.                 else
    1163.                     m_LedgeGrabable = false;
    1164.             }          
    1165.         }
    1166.         else
    1167.             m_LedgeGrabable = false;
    1168.     }
    1169.  
    1170.     /// <summary>
    1171.     /// Handles the logic for Wallrun.
    1172.     /// Happens once OnStart_WallRun setup all the variables
    1173.     /// Will constraint the transform to the normal of the wall
    1174.     /// </summary>
    1175.     protected virtual void UpdateWallrun()
    1176.     {  
    1177.         if(m_IsLedgeGrabbing)
    1178.             return;
    1179.  
    1180.         if(m_IsHanging)
    1181.             return;
    1182.  
    1183.         if(!m_IsWallRunning)
    1184.             return;
    1185.  
    1186.         if(m_Player.Crouch.Active)
    1187.             return;
    1188.  
    1189.         // get the angle between the wallrun surface and the player's facing direction
    1190.         // used for controlling animationblending
    1191.        
    1192.         Vector3 cv = Vector3.Cross(-m_WallRunHitNormal, transform.forward);
    1193.         m_WallAngle = Vector3.Angle(-m_WallRunHitNormal, transform.forward);
    1194.        
    1195.         if(cv.y > 0) m_WallAngle = -m_WallAngle;
    1196.  
    1197.         RaycastHit hit;
    1198.         Vector3 raycastdirection = m_WallRunHitPoint - transform.position;
    1199.  
    1200.         // determines where is the wallrun in relation to the camera
    1201.         // this will determine where the raycast should be projected
    1202.         // so if wall is on camera right, the raycast will projected to camera right.
    1203.  
    1204. //        if(m_IsWallInFront )
    1205. //            raycastdirection = transform.root.forward;
    1206. //        else if (m_IsWallOnRight)
    1207. //            raycastdirection = transform.root.right;
    1208. //        else if (!m_IsWallOnRight)
    1209. //            raycastdirection = -transform.root.right;
    1210.    
    1211.         // stop wallrun if we ran out of time
    1212.         if(m_WallRunTimer >= WallRunDuration && !WallRunInfinite)
    1213.         {
    1214.             m_WallRunTimer = 0f;
    1215.             m_IsWallRunning = false;
    1216.  
    1217.             m_Player.WallRun.Stop ();
    1218.  
    1219.             m_Controller.AddForce (m_WallRunDismountDirection * WallRunDismountForce);
    1220.            
    1221.             return;
    1222.         }
    1223.  
    1224.         // override controller's gravity
    1225.         m_Controller.PhysicsGravityModifier = WallRunGravity;
    1226.  
    1227.         m_WallRunTimer += Time.deltaTime;
    1228.  
    1229.         float wallrunRelativeSpeed = Vector3.Dot(m_Camera.transform.forward, m_WallRunLookDirection);
    1230.         wallrunRelativeSpeed *= 10f;
    1231.         wallrunRelativeSpeed = Mathf.Round (wallrunRelativeSpeed);
    1232.         wallrunRelativeSpeed *= 0.1f;
    1233.  
    1234.         // rotates player towards wallrunning direction.
    1235.         if(m_WallAngle > 50f || m_WallAngle < -50f )
    1236.         {
    1237.             transform.rotation = Quaternion.LookRotation(m_WallRunLookDirection,Vector3.up);
    1238.             m_Controller.MotorAcceleration = Mathf.Lerp(0.2f,m_WallRunMaxSpeed,wallrunRelativeSpeed);
    1239.         }
    1240.  
    1241.  
    1242.         Vector2 tempInput = m_Player.InputMoveVector.Get();
    1243.         tempInput.x = 0f;
    1244.         m_Player.InputMoveVector.Set(tempInput);
    1245.  
    1246.         if(    Physics.Raycast( transform.root.position + new Vector3 (0,m_CharacterController.height*0.8f,0) , raycastdirection, out hit, WallRunRange))
    1247.         {
    1248.             if(hit.collider != null)
    1249.                 m_WallRunObject = hit.transform;
    1250.         }
    1251.  
    1252.         if (!Physics.CheckSphere(transform.root.position + new Vector3 (0,m_CharacterController.height*0.5f,0), 1.5f,vp_Layer.Mask.ExternalBlockers))
    1253.         {
    1254.             m_WallRunTimer = 0f;
    1255.             m_IsWallRunning = false;
    1256.             m_IsHanging = false ;
    1257.             m_Player.WallRun.Stop ();
    1258.             m_Controller.AddForce (m_WallRunDismountDirection * WallRunDismountForce);
    1259.  
    1260.         }
    1261.     }
    1262.        
    1263.     void UpdateWallrunTilt()
    1264.     {
    1265.         if(!m_Player.WallRun.Active)
    1266.             return;
    1267.  
    1268.         // disabled
    1269.         if(WallRunTilt == 0)
    1270.             return;
    1271.  
    1272.         print (WallAngle);
    1273.  
    1274.         Vector3 localVelocity = GetLocalVelocity() * 0.016f ;
    1275.  
    1276.         if(WallAngle > 25)
    1277.             m_Camera.AddRollForce(Mathf.Clamp(localVelocity.z * WallRunTilt,0f,WallRunTilt));
    1278.         else if (WallAngle < -25)
    1279.             m_Camera.AddRollForce(Mathf.Clamp(localVelocity.z * -WallRunTilt,-WallRunTilt,0f));
    1280.  
    1281.  
    1282. //        if(m_IsWallOnRight)
    1283. //            m_Camera.AddRollForce(Mathf.Clamp(localVelocity.z * WallRunTilt,0f,WallRunTilt));
    1284. //        else
    1285. //            m_Camera.AddRollForce(Mathf.Clamp(localVelocity.z * -WallRunTilt,-WallRunTilt,0f));
    1286.        
    1287.     }
    1288.  
    1289.     /// <summary>
    1290.     /// If press, will start LedgeGrab or Walljump or DoubleJump
    1291.     /// This utilizes GetButtonDown so it will only trigger once
    1292.     /// </summary>
    1293.     protected virtual void InputJump()
    1294.     {
    1295.         // uses default "Jump" button to check for double jumping.
    1296.         // feel free to change "Jump" to some other buttons to suit your project
    1297.         if(vp_Input.GetButtonDown("Jump"))
    1298.         {
    1299.             m_Player.LedgeGrab.TryStart();
    1300.             m_Player.WallJump.TryStart();
    1301.             m_Player.DoubleJump.TryStart();
    1302.         }
    1303.         else if(vp_Input.GetButtonUp("Jump"))
    1304.         {
    1305.             m_Player.WallJump.TryStop();
    1306.             m_Player.DoubleJump.TryStop();
    1307.  
    1308.         }
    1309.  
    1310.     }
    1311.  
    1312.     /// <summary>
    1313.     /// Input command for executing dash
    1314.     /// The main logic happens in the GetButtonUp, and if within the
    1315.     /// </summary>
    1316.     protected virtual void InputDash()
    1317.     {
    1318.  
    1319.         // uses default "Run" button to check for dashing
    1320.         if(vp_Input.GetButton("Run"))
    1321.         {
    1322.             m_DashInputTimer += Time.deltaTime;
    1323.         }
    1324.         // checks if we release "Run" button within the time frame allowed to trigger dash
    1325.         else if (vp_Input.GetButtonUp("Run") && m_DashInputTimer <= DashSensitivtiy)
    1326.         {
    1327.             m_Player.Dash.TryStart();
    1328.             m_DashInputTimer=0f;
    1329.         }
    1330.         else  
    1331.         {
    1332.             m_Player.Dash.TryStop();
    1333.             m_DashInputTimer=0f;
    1334.         }
    1335.  
    1336.     }
    1337.  
    1338.     protected virtual void InputGroundSlide()
    1339.     {
    1340.  
    1341.         //if (vp_Input.GetButton("Crouch"))    // suggested input axis
    1342.         if (vp_Input.GetButton("Crouch"))
    1343.         {
    1344.             m_Player.GroundSlide.TryStart();
    1345.             m_Player.WallHang.TryStop();
    1346.         }
    1347.         else
    1348.         {
    1349.             m_Player.GroundSlide.Stop();
    1350.         }
    1351.  
    1352.     }
    1353.  
    1354.     protected virtual void InputWallHang()
    1355.     {
    1356.         if (vp_Input.GetButtonDown("Zoom"))
    1357.         {
    1358.             if(!m_IsWallHanging)
    1359.                 m_Player.WallHang.TryStart();
    1360.             else
    1361.                 m_Player.WallHang.TryStop();
    1362.         }
    1363.     }
    1364.    
    1365.     /// <summary>
    1366.     /// Helper to check if the collision surface can be wallrun
    1367.     /// </summary>
    1368.     protected virtual void CheckWallRun(RaycastHit hit)
    1369.     {
    1370.         if(m_Controller.Grounded)
    1371.             return;
    1372.  
    1373.         if(m_IsLedgeGrabbing)
    1374.             return;
    1375.  
    1376.         if(!string.IsNullOrEmpty(IgnoreWallRunTag))            // If tag is not empty
    1377.         {
    1378.             if(hit.transform.tag == IgnoreWallRunTag &&
    1379.                hit.transform.tag != "Untagged")                // Hit a un-wallrunable object
    1380.                 return;
    1381.         }
    1382.  
    1383.         if(m_WallRunHitNormal == hit.normal)
    1384.         {
    1385.             m_CanWallRunAgain = Time.time + WallRunAgainTimeout;
    1386.             return;
    1387.         }
    1388.    
    1389.         if(hit.normal.y >  0.2f || hit.normal.y < -0.2f)
    1390.         {
    1391.             m_WallRunable = false;
    1392.             return;
    1393.         }
    1394.  
    1395.         if(hit.collider == null)
    1396.             return;
    1397.  
    1398.         m_WallRunHitNormal = hit.normal;
    1399.         m_WallRunHitPoint = hit.point;
    1400.  
    1401.         float colliderNormalForward ;
    1402.         float colliderNormalRight ;
    1403.  
    1404.         colliderNormalForward = Vector3.Dot (transform.forward,hit.normal);
    1405.         colliderNormalRight = Vector3.Dot (transform.right,hit.normal);
    1406.    
    1407.         if (colliderNormalForward < -0.95)        // check if we are facing the wall      
    1408.         {
    1409.             m_IsWallInFront = true;
    1410.  
    1411.             m_WallRunLookDirection = Quaternion.AngleAxis(-90,Vector3.forward) * m_WallRunHitNormal;
    1412.             m_WallRunDismountDirection = m_WallRunHitNormal;
    1413.             m_IsWallOnRight = false;
    1414.             m_WallRunable = true;
    1415.  
    1416.  
    1417.             m_Player.WallRun.TryStart();
    1418.             return;
    1419.  
    1420.         }
    1421.         else
    1422.         {
    1423.             m_IsWallInFront = false;
    1424.         }
    1425.  
    1426.         if(colliderNormalRight > 0)            // check if wall is on the left
    1427.         {
    1428.             m_WallRunLookDirection = Quaternion.AngleAxis(-89,Vector3.up) * m_WallRunHitNormal;
    1429.             m_WallRunDismountDirection = Quaternion.AngleAxis(-15,Vector3.up) * m_WallRunHitNormal;
    1430.             m_IsWallOnRight = false;
    1431.         }
    1432.        
    1433.         else if (colliderNormalRight < 0)    // else it's on the right
    1434.         {
    1435.             m_WallRunLookDirection = Quaternion.AngleAxis(89,Vector3.up) * m_WallRunHitNormal;
    1436.             m_WallRunDismountDirection = Quaternion.AngleAxis(15,Vector3.up) * m_WallRunHitNormal;
    1437.             m_IsWallOnRight = true;
    1438.         }
    1439.        
    1440.         m_WallRunable = true;
    1441.  
    1442.         if(m_IsWallRunning && !autoYawed && !m_IsWallInFront && WallRunAutoRotateYaw)// are we already wallrunning?
    1443.         {
    1444. //            autoYawed = true;
    1445.             StartCoroutine(LineUpWallRun());    // align the camera to the new vector instead.
    1446.             return;
    1447.         }
    1448.         else
    1449.             m_Player.WallRun.TryStart();
    1450.  
    1451.     }
    1452.  
    1453.     protected virtual void UpdatePhysics()
    1454.     {
    1455.         if(m_Controller.Grounded)
    1456.             return;
    1457.         if(m_Player.DoubleJump.Active)
    1458.             return;
    1459.         if(m_Player.WallRun.Active)
    1460.             return;
    1461.  
    1462.         m_Controller.MotorDamping = targetDamping;
    1463.     }
    1464.  
    1465.     /// <summary>
    1466.     /// Helper to check if the collision surface can be walljump
    1467.     /// </summary>
    1468.     protected virtual void CheckWallJump(RaycastHit hit)
    1469.     {
    1470.         if(!string.IsNullOrEmpty(IgnoreWallJumpTag))            // If tag is not empty
    1471.         {
    1472.             if(hit.transform.tag == IgnoreWallJumpTag &&
    1473.                hit.transform.tag != "Untagged")                    // Hit a un-walljumpable object
    1474.                 return;
    1475.         }
    1476.  
    1477. //        // hit the same wall, we can't walljump the same place twice
    1478. //        if(m_WallJumpHitNormal == hit.normal)
    1479. //        {
    1480. //            m_WallJumpAble = false;
    1481. //            return;
    1482. //        }
    1483.  
    1484.         if (!m_Controller.Grounded)
    1485.         {
    1486.             if(hit.normal.y <  0.1f && hit.normal.y > -0.1f) //if surface's orientation is flat like a wall
    1487.             {
    1488.                 m_WallJumpAble = true;
    1489.                 m_WallJumpHitNormal = hit.normal;
    1490.                 m_DoubleJumpAble = false;
    1491.             }
    1492.         }
    1493.         else
    1494.             m_WallJumpAble = false;
    1495.     }
    1496.  
    1497.     /// <summary>
    1498.     /// Helper to check if the collision surface can be wallhang
    1499.     /// </summary>
    1500.     protected virtual void CheckWallHang(RaycastHit hit)
    1501.     {
    1502.         if(!string.IsNullOrEmpty(IgnoreWallHangTag))        // If tag is not empty
    1503.         {
    1504.             if(hit.transform.tag == IgnoreWallHangTag &&
    1505.                hit.transform.tag != "Untagged")                // Hit a un-wallhangable object
    1506.                 return;
    1507.         }
    1508.  
    1509.         // hit the same wall, we can't wallhang the same place twice
    1510.         if(m_WallHangHitNormal == hit.normal)
    1511.             return;
    1512.  
    1513.         if (!m_Controller.Grounded)
    1514.         {
    1515.             if(hit.normal.y <  0.1f && hit.normal.y > -0.1f) //if surface's orientation is flat like a wall
    1516.             {
    1517.                 m_CanWallHang = true;
    1518.                 m_WallHangHitNormal = hit.normal ;
    1519.             }
    1520.         }
    1521.         else
    1522.             m_CanWallHang = false;
    1523.     }
    1524.    
    1525.  
    1526.  
    1527.     protected virtual void OnMessage_FallImpact(float impact)
    1528.     {
    1529.         // we are touching the ground again, reset all the variables
    1530.         m_CanWallRunAgain = Time.time;
    1531.         m_DoubleJumpAble = true;
    1532.         m_currentDoubleJump = DoubleJumpCount ;
    1533.         m_IsHanging = false;
    1534.         m_IsLedgeGrabbing = false;
    1535.         m_IsWallHanging = false;
    1536.         m_Player.LedgeGrab.Stop();
    1537.         m_Player.WallRun.Stop();
    1538.         m_Player.SetState("Default", true, true);
    1539.         m_Player.InputAllowGameplay.Set(true);
    1540.         m_WallRunHitNormal = new Vector3(0,0,0);
    1541.  
    1542.        
    1543.     }
    1544.  
    1545.         protected virtual Texture OnValue_WallTexture
    1546.     {
    1547.         get
    1548.         {  
    1549.             if (WallRunObject == null)
    1550.                 return null;
    1551.            
    1552.             // return if no renderer and no terrain under the controller
    1553.             if(WallRunObject.renderer == null && m_CurrentTerrain == null)
    1554.                 return null;
    1555.  
    1556.             int terrainTextureID = -1;
    1557.  
    1558.             // check to see if a main texture can be retrieved from the terrain
    1559.             if(m_CurrentTerrain != null)
    1560.             {
    1561.                 terrainTextureID = vp_FootstepManager.GetMainTerrainTexture( m_Player.Position.Get(), m_CurrentTerrain );
    1562.                 if(terrainTextureID > m_CurrentTerrain.terrainData.splatPrototypes.Length - 1)
    1563.                     return null;
    1564.             }
    1565.  
    1566.             // return the texture
    1567.             return m_CurrentTerrain == null ? WallRunObject.renderer.material.mainTexture : m_CurrentTerrain.terrainData.splatPrototypes[ terrainTextureID ].texture;
    1568.            
    1569.         }
    1570.     }
    1571.  
    1572.     /// <summary>
    1573.     /// This is copy from FootStepManager, derived from Footstep and made to work only with wallrun
    1574.     /// </summary>
    1575.     protected virtual void WallRunFootstep()
    1576.     {
    1577.         if(m_Controller.Grounded)
    1578.             return;
    1579.  
    1580.         // return if there no texture or surface type is found
    1581.         if(m_Player.WallTexture.Get() == null )
    1582.             return;
    1583.        
    1584.         // return if not wallrunning
    1585.         if(!m_Player.WallRun.Active)
    1586.             return;
    1587.  
    1588.         // loop through the surfaces
    1589.         foreach(vp_FootstepManager.vp_SurfaceTypes st in m_FootstepManager.SurfaceTypes)
    1590.         {
    1591.             // loop through the surfaces textures
    1592.             foreach(Texture tex in st.Textures)
    1593.             {
    1594.                 // if the texture is the same as the wall texture...
    1595.                 if(tex == m_Player.WallTexture.Get())
    1596.                 {
    1597.                     // play random surface sound
    1598.                     m_FootstepManager.PlaySound( st );
    1599.                     break;
    1600.                 }
    1601.             }
    1602.         }
    1603.     }
    1604.  
    1605.     protected virtual Vector3 GetLocalVelocity()
    1606.     {
    1607.         Vector3 localVelocity = m_Controller.Transform.InverseTransformDirection( m_Player.Velocity.Get() );
    1608.         return localVelocity;
    1609.     }
    1610.  
    1611.     protected virtual Vector3 GetNewPosition()
    1612.     {
    1613.         Vector3 newPosition = m_Controller.Transform.position;
    1614.  
    1615.         RaycastHit hit;
    1616.  
    1617.         Vector3 offSetPos = transform.InverseTransformDirection(new Vector3(0,0,1));
    1618.         Vector3 lastWallRunNormal = Quaternion.AngleAxis(-180,Vector3.up) * m_WallRunHitNormal;
    1619.  
    1620.         Ray ray = new Ray(offSetPos, lastWallRunNormal);
    1621.         Physics.Raycast(ray, out hit, 10f);
    1622.  
    1623.         newPosition = hit.point;
    1624.                
    1625.         return newPosition;
    1626.     }
    1627.    
    1628.     /// <summary>
    1629.     /// Plays parkour arm animation.
    1630.     /// </summary>
    1631.     protected virtual void ParkourArmClimb()
    1632.     {
    1633.         if(ParkourArmPrefab != null )
    1634.         {
    1635.             ParkourArmPrefab.SetActive(true);
    1636.  
    1637.             Vector3 armPosition = m_HangRotation ;
    1638.  
    1639.             RaycastHit hit;
    1640.  
    1641.             Physics.Raycast(transform.position, armPosition , out hit);
    1642.  
    1643. //            ParkourArmPrefab.transform.position = new Vector3(hit.point.x, m_ClimbObjectPosition.y, hit.point.z) + transform.InverseTransformDirection(ParkourArmPos);
    1644.  
    1645.             ParkourArmPrefab.transform.position = m_ClimbObjectPosition + transform.InverseTransformDirection(ParkourArmPos);
    1646.            
    1647.             ParkourArmPrefab.transform.rotation = Quaternion.LookRotation(m_HangRotation,Vector3.up);
    1648.             ParkourArmPrefab.animation.CrossFade(ParkourArmClimbAnim.name);    // play anim
    1649.         }
    1650.  
    1651.     }
    1652.  
    1653. }
    1654.  
    1655.  
     
  8. ThomasCreate

    ThomasCreate

    Joined:
    Feb 23, 2015
    Posts:
    81
    It tells you you're missing the vp_Component class. You probably haven't imported it yet. Judging by your questions it seems like you would do well with some basic programming lessons before you attempt to create a parkour game with someone else's code. ;)