From 61980f55cffc07db940b12795b4075cbd515fdbd Mon Sep 17 00:00:00 2001 From: wheatv3015 <60979035+wheatv3015@users.noreply.github.com> Date: Mon, 11 Oct 2021 10:25:52 -0500 Subject: [PATCH] Wallrun Updates -WallRunItem made for equipping/unequipping wall run -Added Method to PlayerInventory for trying to add special items as items -Added better method for checking if player isGrounded to PlayerMovement -Added a setup file for preconfiguring player loadouts -Added complex wallrun file as a work in progress to allow for robust polished wallrun mechanic --- Assets/Scenes/Demos/UI-UX_Demos.unity | 165 ++++++++++++++- .../PlayerScripts/ItemScripts/WallRunItem.cs | 15 ++ .../ItemScripts/WallRunItem.cs.meta | 11 + .../Scripts/PlayerScripts/PlayerInventory.cs | 8 + .../Scripts/PlayerScripts/PlayerMovement.cs | 123 ++++++++---- Assets/Scripts/PlayerScripts/Setup.cs | 18 ++ Assets/Scripts/PlayerScripts/Setup.cs.meta | 11 + Assets/Scripts/PlayerScripts/WallRun.cs | 189 ++++++++++++++++++ Assets/Scripts/PlayerScripts/WallRun.cs.meta | 11 + 9 files changed, 506 insertions(+), 45 deletions(-) create mode 100644 Assets/Scripts/PlayerScripts/ItemScripts/WallRunItem.cs create mode 100644 Assets/Scripts/PlayerScripts/ItemScripts/WallRunItem.cs.meta create mode 100644 Assets/Scripts/PlayerScripts/Setup.cs create mode 100644 Assets/Scripts/PlayerScripts/Setup.cs.meta create mode 100644 Assets/Scripts/PlayerScripts/WallRun.cs create mode 100644 Assets/Scripts/PlayerScripts/WallRun.cs.meta diff --git a/Assets/Scenes/Demos/UI-UX_Demos.unity b/Assets/Scenes/Demos/UI-UX_Demos.unity index 84138ed..1751220 100644 --- a/Assets/Scenes/Demos/UI-UX_Demos.unity +++ b/Assets/Scenes/Demos/UI-UX_Demos.unity @@ -377,6 +377,101 @@ Transform: m_Father: {fileID: 944325791} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 25, y: 0, z: 0} +--- !u!1 &605052955 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 605052959} + - component: {fileID: 605052958} + - component: {fileID: 605052957} + - component: {fileID: 605052956} + m_Layer: 0 + m_Name: Wall (2) + m_TagString: WallRun + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!65 &605052956 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 605052955} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &605052957 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 605052955} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 730a2ba314caf9742823631b050afe28, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &605052958 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 605052955} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!4 &605052959 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 605052955} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: -8.16, y: 2.89, z: 70.8} + m_LocalScale: {x: 1, y: 10, z: 20} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 10 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &696875328 GameObject: m_ObjectHideFlags: 0 @@ -472,6 +567,9 @@ GameObject: - component: {fileID: 944325787} - component: {fileID: 944325792} - component: {fileID: 944325786} + - component: {fileID: 944325794} + - component: {fileID: 944325793} + - component: {fileID: 944325795} m_Layer: 0 m_Name: Player Capsule m_TagString: Player @@ -492,8 +590,10 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: pStats: {fileID: 944325792} - minimumWallrunningHeight: 1.75 - maximumDistanceToWall: 1 + groundCheckDistance: 0.05 + groundCheckLayers: + serializedVersion: 2 + m_Bits: 4294967295 minAngle: -15 maxAngle: 30 sensitivity: 105 @@ -605,6 +705,55 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: addc2e37ff81c1b4989ec34b6150b4f7, type: 3} m_Name: m_EditorClassIdentifier: +--- !u!114 &944325793 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 944325785} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ed382e04d00059e40a6803fa4ad43469, type: 3} + m_Name: + m_EditorClassIdentifier: + hasWallRun: 1 + maxSpeed: 15 +--- !u!114 &944325794 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 944325785} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5a5d879591af1084ab5d3a35fcd53086, type: 3} + m_Name: + m_EditorClassIdentifier: + items: [] + pStats: {fileID: 944325792} +--- !u!114 &944325795 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 944325785} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 535009eaa735a4c4e95c6fc270e32741, type: 3} + m_Name: + m_EditorClassIdentifier: + wallMaxDistance: 1 + wallSpeedMultiplier: 1 + minimumHeight: 0.25 + maxAngleRoll: 30 + normalizedAngleThreshold: 0.3 + jumpDuration: 0.25 + wallBouncing: 3 + cameraTransitionDuration: 1 + wallGravityDownForce: -1 --- !u!1 &951764787 GameObject: m_ObjectHideFlags: 0 @@ -760,8 +909,8 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1142615211} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 5.43, y: 2.89, z: 31.38} - m_LocalScale: {x: 1, y: 10, z: 20} + m_LocalPosition: {x: 7, y: 3, z: 60} + m_LocalScale: {x: 1, y: 10, z: 80} m_Children: [] m_Father: {fileID: 0} m_RootOrder: 9 @@ -783,7 +932,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 1 + m_IsActive: 0 --- !u!114 &1206487914 MonoBehaviour: m_ObjectHideFlags: 0 @@ -841,7 +990,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 1 + m_IsActive: 0 --- !u!114 &1320399128 MonoBehaviour: m_ObjectHideFlags: 0 @@ -1071,7 +1220,7 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1458711923} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 51.53} + m_LocalPosition: {x: 0, y: 0, z: 104.7} m_LocalScale: {x: 10, y: 1, z: 25} m_Children: [] m_Father: {fileID: 0} @@ -1166,7 +1315,7 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1496353121} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: -5.35, y: 2.89, z: 31.38} + m_LocalPosition: {x: -5.44, y: 2.89, z: 29.21} m_LocalScale: {x: 1, y: 10, z: 20} m_Children: [] m_Father: {fileID: 0} diff --git a/Assets/Scripts/PlayerScripts/ItemScripts/WallRunItem.cs b/Assets/Scripts/PlayerScripts/ItemScripts/WallRunItem.cs new file mode 100644 index 0000000..83a6e03 --- /dev/null +++ b/Assets/Scripts/PlayerScripts/ItemScripts/WallRunItem.cs @@ -0,0 +1,15 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class WallRunItem : Item +{ + public void Equip(PlayerStats p){ + p.HasWallrun = true; + } + + public void Unequip(PlayerStats p) + { + p.HasWallrun = false; + } +} diff --git a/Assets/Scripts/PlayerScripts/ItemScripts/WallRunItem.cs.meta b/Assets/Scripts/PlayerScripts/ItemScripts/WallRunItem.cs.meta new file mode 100644 index 0000000..ae3533b --- /dev/null +++ b/Assets/Scripts/PlayerScripts/ItemScripts/WallRunItem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 80dbcf4212f11a74ebd5289c2b5eb309 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/PlayerScripts/PlayerInventory.cs b/Assets/Scripts/PlayerScripts/PlayerInventory.cs index 28821dd..64b918e 100644 --- a/Assets/Scripts/PlayerScripts/PlayerInventory.cs +++ b/Assets/Scripts/PlayerScripts/PlayerInventory.cs @@ -12,6 +12,14 @@ public class PlayerInventory : MonoBehaviour return true; } + public bool AddSpecialItem(T itemCandidate) { // Unless we don't want the four special items to be handled by inventory/inventory manager? + if (itemCandidate is Item) { + items.Add(itemCandidate as Item); + } + return true; + } + + public bool RemoveItem(Item item){ if(items.Remove(item)){ return true; diff --git a/Assets/Scripts/PlayerScripts/PlayerMovement.cs b/Assets/Scripts/PlayerScripts/PlayerMovement.cs index 8a55002..4b96890 100644 --- a/Assets/Scripts/PlayerScripts/PlayerMovement.cs +++ b/Assets/Scripts/PlayerScripts/PlayerMovement.cs @@ -30,16 +30,17 @@ public class PlayerMovement : MonoBehaviour Vector3 impact = Vector3.zero; //Wallrunning - public float minimumWallrunningHeight = 1.75f; - public float maximumDistanceToWall = 0.75f; - private Vector3[] directions = new Vector3[]{ - Vector3.right, - Vector3.right+Vector3.forward, - Vector3.forward, - Vector3.left+Vector3.forward, - Vector3.left - }; - + private WallRun wallRun; + + //Ground Check + public bool isGrounded { get; private set; } //Better custom is grounded + public float groundCheckDistance = 0.05f; //how far away from the ground to not be considered grounded + private float lastTimeJumped = 0f; //Last time the player jumped + const float jumpGroundingPreventionTime = 0.2f; // delay in checking if we are grounded after a jump + const float groundCheckDistanceInAir = 0.07f; //How close we have to get to ground to start checking for grounded again + public LayerMask groundCheckLayers = -1; //Physics layers checked to consider the player grounded + + //Camera Variables private Vector3 camRotation; private Transform cam; @@ -73,6 +74,9 @@ public class PlayerMovement : MonoBehaviour //camera transform cam = Camera.main.transform; Cam = Camera.main; //RENAME WHEN CLEANING UP BLINK + + //Wallrun + wallRun = gameObject.GetComponent(); } void Start(){ @@ -104,6 +108,8 @@ public class PlayerMovement : MonoBehaviour //Reads inputs and moves player private void InputController(){ + //Check if player is grounded before each frame + GroundCheck(); //Keyboard inputs //Checks if movement keys have been pressed and calculates correct vector @@ -115,21 +121,18 @@ public class PlayerMovement : MonoBehaviour vel = moveX + moveZ; //Gravity - vel.y -= pStats.PlayerGrav * Time.deltaTime; + Gravity(); driftVel = Vector3.Lerp(driftVel, vel, pStats.Traction*Time.deltaTime); //Jump Function Jump(); - //Gravity - vel.y -= Gravity(); - moveController.Move(driftVel); } //Calculates speed current player needs to be going - private float PlayerSpeed(){ + public float PlayerSpeed(){ //If nothing is pressed speed is 0 if(Input.GetAxis("Vertical") == 0.0f && Input.GetAxis("Horizontal") == 0.0f){ pStats.CurVel = 0.0f; @@ -167,7 +170,9 @@ public class PlayerMovement : MonoBehaviour curJumpNum++; jumpPressed = true; } - + + lastTimeJumped = Time.time; + //NEEDS TO BE MASSIVELY CHANGE LIKELY USE RAYCAST TO CHECK IF ACTUALLY ON GROUND //CANNOT USE CHARACTERCONTROLLER.ISGROUNDED IT IS UNRELIABLE //If grounded no jumps have been used @@ -177,7 +182,22 @@ public class PlayerMovement : MonoBehaviour if(Input.GetAxis("Jump")==0) jumpPressed = false; } + public bool GetJumpPressed() { + return jumpPressed; + } + public Camera GetPlayerCamera() { + return Cam; + } + + public void AddPlayerVelocity(Vector3 additiveVelocity) { + vel += additiveVelocity; + } + + public void SetPlayerVelocity(Vector3 newVelocity) + { + vel = newVelocity; + } //Camera private void Rotate() @@ -201,32 +221,61 @@ public class PlayerMovement : MonoBehaviour } //Gravity Function for adjusting y-vel due to wallrun/glide/etc - private float Gravity(){ + private void Gravity(){ + //Normal Gravity + vel.y -= pStats.PlayerGrav * Time.deltaTime; //Wallrunning - if (!moveController.isGrounded && Input.GetAxisRaw("Vertical") != 0) { //If in the air, and moving forward - RaycastHit hit; - Physics.Raycast(moveController.transform.position, Vector3.down, out hit); - if (hit.distance > minimumWallrunningHeight) //If distance from player to ground is > min ground height - { - foreach (Vector3 direction in directions) - { //For each direction we can wallrun in - Ray ray = new Ray(moveController.transform.position, direction); //Cast a Ray to see if we are by a wall - if (Physics.Raycast(ray, out hit, maximumDistanceToWall)) //If the ray hits a wallrun wall - { - if (hit.collider.tag == "WallRun") - { - return 0; //Don't fall down - } - } - } - } - } + if (pStats.HasWallrun) { wallRun.WallRunRoutine(); } //adjusted later if we are wallrunning //If gliding //Go down slowly - //Else normal gravity - return pStats.PlayerGrav * Time.deltaTime; } + void GroundCheck() + { + // Make sure that the ground check distance while already in air is very small, to prevent suddenly snapping to ground + float chosenGroundCheckDistance = isGrounded ? (moveController.skinWidth + groundCheckDistance) : groundCheckDistanceInAir; + + // reset values before the ground check + isGrounded = false; + Vector3 groundNormal = Vector3.up; + + // only try to detect ground if it's been a short amount of time since last jump; otherwise we may snap to the ground instantly after we try jumping + if (Time.time >= lastTimeJumped + jumpGroundingPreventionTime) + { + // if we're grounded, collect info about the ground normal with a downward capsule cast representing our character capsule + if (Physics.CapsuleCast(GetCapsuleBottomHemisphere(), GetCapsuleTopHemisphere(moveController.height), moveController.radius, Vector3.down, out RaycastHit hit, chosenGroundCheckDistance, groundCheckLayers, QueryTriggerInteraction.Ignore)) + { + // storing the upward direction for the surface found + groundNormal = hit.normal; + + // Only consider this a valid ground hit if the ground normal goes in the same direction as the character up + // and if the slope angle is lower than the character controller's limit + if (Vector3.Dot(hit.normal, transform.up) > 0f && IsNormalUnderSlopeLimit(groundNormal)) + { + isGrounded = true; + + // handle snapping to the ground + if (hit.distance > moveController.skinWidth) + { + moveController.Move(Vector3.down * hit.distance); + } + } + } + } + } + + private bool IsNormalUnderSlopeLimit(Vector3 normal){ // Returns true if the slope angle represented by the given normal is under the slope angle limit of the character controller + return Vector3.Angle(transform.up, normal) <= moveController.slopeLimit; + } + + private Vector3 GetCapsuleBottomHemisphere(){ // Gets the center point of the bottom hemisphere of the character controller capsule + return transform.position + (transform.up * moveController.radius); + } + + private Vector3 GetCapsuleTopHemisphere(float atHeight){ // Gets the center point of the top hemisphere of the character controller capsule + + return transform.position + (transform.up * (atHeight - moveController.radius)); + } //ADJUST SO DISTANCE IS DETERMINED BY SCROLL WHEEL //blinks the player forwards diff --git a/Assets/Scripts/PlayerScripts/Setup.cs b/Assets/Scripts/PlayerScripts/Setup.cs new file mode 100644 index 0000000..aa28d53 --- /dev/null +++ b/Assets/Scripts/PlayerScripts/Setup.cs @@ -0,0 +1,18 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class Setup : MonoBehaviour +{ + private PlayerStats pstats; + public bool hasWallRun; + [Range( 1, 50)] + public float maxSpeed; + // Start is called before the first frame update + void Start() + { + pstats = this.gameObject.GetComponent(); + pstats.HasWallrun = hasWallRun; + pstats.MaxVel = maxSpeed; + } +} diff --git a/Assets/Scripts/PlayerScripts/Setup.cs.meta b/Assets/Scripts/PlayerScripts/Setup.cs.meta new file mode 100644 index 0000000..84b5c93 --- /dev/null +++ b/Assets/Scripts/PlayerScripts/Setup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ed382e04d00059e40a6803fa4ad43469 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/PlayerScripts/WallRun.cs b/Assets/Scripts/PlayerScripts/WallRun.cs new file mode 100644 index 0000000..bc7d4ba --- /dev/null +++ b/Assets/Scripts/PlayerScripts/WallRun.cs @@ -0,0 +1,189 @@ +using UnityEngine; +using System.Linq; +using UnityEngine.Rendering; + +[RequireComponent (typeof(PlayerMovement))] +public class WallRun : MonoBehaviour +{ + + public float wallMaxDistance = 1; + public float wallSpeedMultiplier = 1.2f; + public float minimumHeight = 1.2f; + public float maxAngleRoll = 20; + [Range(0.0f, 1.0f)] + public float normalizedAngleThreshold = 0.1f; + + public float jumpDuration = 1; + public float wallBouncing = 3; + public float cameraTransitionDuration = 1; + + public float wallGravityDownForce = 20f; + + [Space] + PlayerMovement playerMovementController; + + Vector3[] directions; + RaycastHit[] hits; + + bool isWallRunning = false; + Vector3 lastWallPosition; + Vector3 lastWallNormal; + float elapsedTimeSinceJump = 0; + float elapsedTimeSinceWallAttach = 0; + float elapsedTimeSinceWallDetatch = 0; + bool jumping; + + bool isPlayergrounded() => playerMovementController.isGrounded; + + public bool IsWallRunning() => isWallRunning; + + bool CanWallRun() + { + float verticalAxis = Input.GetAxisRaw("Vertical"); + + return !isPlayergrounded() && verticalAxis > 0 && VerticalCheck(); + } + + bool VerticalCheck() + { + return !Physics.Raycast(transform.position, Vector3.down, minimumHeight); + } + + + void Start() + { + playerMovementController = GetComponent(); + + directions = new Vector3[]{ + Vector3.right, + Vector3.right + Vector3.forward, + Vector3.forward, + Vector3.left + Vector3.forward, + Vector3.left + }; + } + + + public void WallRunRoutine() + { + isWallRunning = false; + + if(playerMovementController.GetJumpPressed()) + { + jumping = true; + } + + if(CanAttach()) + { + hits = new RaycastHit[directions.Length]; + + for(int i=0; i h.collider != null).OrderBy(h => h.distance).ToArray(); + if(hits.Length > 0) + { + if(hits[0].collider.tag == "WallRun") + { + OnWall(hits[0]); + lastWallPosition = hits[0].point; + lastWallNormal = hits[0].normal; + } + } + } + } + + if(isWallRunning) + { + elapsedTimeSinceWallDetatch = 0; + elapsedTimeSinceWallAttach += Time.deltaTime; + playerMovementController.AddPlayerVelocity((Vector3.down * wallGravityDownForce * Time.deltaTime)); + } + else + { + elapsedTimeSinceWallAttach = 0; + elapsedTimeSinceWallDetatch += Time.deltaTime; + } + } + + bool CanAttach() + { + if(jumping) + { + elapsedTimeSinceJump += Time.deltaTime; + if(elapsedTimeSinceJump > jumpDuration) + { + elapsedTimeSinceJump = 0; + jumping = false; + } + return false; + } + return true; + } + + void OnWall(RaycastHit hit){ + float d = Vector3.Dot(hit.normal, Vector3.up); + if(d >= -normalizedAngleThreshold && d <= normalizedAngleThreshold) + { + // Vector3 alongWall = Vector3.Cross(hit.normal, Vector3.up); + float vertical = Input.GetAxisRaw("Vertical"); + Vector3 alongWall = transform.TransformDirection(Vector3.forward); + + Debug.DrawRay(transform.position, alongWall.normalized * 10, Color.green); + Debug.DrawRay(transform.position, lastWallNormal * 10, Color.magenta); + + Vector3 moveToSet = alongWall * vertical * playerMovementController.PlayerSpeed() *Time.deltaTime;// * wallSpeedMultiplier; + moveToSet.y = 0; + + playerMovementController.SetPlayerVelocity(moveToSet); + Debug.Log("On Wall"); + isWallRunning = true; + } + } + + float CalculateSide() + { + if(isWallRunning) + { + Vector3 heading = lastWallPosition - transform.position; + Vector3 perp = Vector3.Cross(transform.forward, heading); + float dir = Vector3.Dot(perp, transform.up); + return dir; + } + return 0; + } + + public float GetCameraRoll() //Cause camera to roll when wall running - call to this is player movement + { + float dir = CalculateSide(); + float cameraAngle = playerMovementController.GetPlayerCamera().transform.eulerAngles.z; + float targetAngle = 0; + if(dir != 0) + { + targetAngle = Mathf.Sign(dir) * maxAngleRoll; + } + return Mathf.LerpAngle(cameraAngle, targetAngle, Mathf.Max(elapsedTimeSinceWallAttach, elapsedTimeSinceWallDetatch) / cameraTransitionDuration); + } + + public Vector3 GetWallJumpDirection() //Add call in jump where if we are wallrunning and jump, the jump vector is multiplied by this + { + if(isWallRunning) + { + return lastWallNormal * wallBouncing + Vector3.up; + } + return Vector3.zero; + } +} diff --git a/Assets/Scripts/PlayerScripts/WallRun.cs.meta b/Assets/Scripts/PlayerScripts/WallRun.cs.meta new file mode 100644 index 0000000..07b935d --- /dev/null +++ b/Assets/Scripts/PlayerScripts/WallRun.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 535009eaa735a4c4e95c6fc270e32741 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: