Ok, let’s see if I can make this make sense…
So in a game I’m making, I’m trying to implement a wall jump mechanic using OnTrigger. It currently works, kind of, but it’s a bit janky. What I want my code to do is in OnTriggerEnter, I want it to detect where the wall is in relation to the player (whether it’s in front of you, behind you, to your right, etc.), and when you jump, it sends the player away from that wall. I currently have no idea how to code this in, so some help would be appreciated.
Here’s my code in case you need it:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
[Header("Movement")]
public bool isMoving;
public bool isWallRunning;
public float moveSpeed;
public float groundDrag;
public float jumpForce;
public float wallJumpForce;
public float dashForce;
public float jumpCooldown;
public float dashCooldown;
public float airMultiplier;
public bool readyToJump;
public bool readyToDash;
[Header("Keybinds")]
public KeyCode jumpKey = KeyCode.Space;
public KeyCode dashKey = KeyCode.Mouse1;
[Header("Ground Check")]
public bool grounded;
[Header("Wall Check")]
public bool clingToWall;
[Header("Rope Check")]
public bool grabRope;
public Transform orientation;
public Transform playerObj;
float horizontalInput;
float verticalInput;
Vector3 moveDirection;
Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
rb.freezeRotation = true;
}
void Update()
{
MyInput();
SpeedControl();
if (rb.velocity.magnitude > 0)
{
isMoving = true;
}
else
{
isMoving = false;
}
if(grounded || clingToWall)
{
rb.drag = groundDrag;
}
else
{
rb.drag = 0;
}
if(clingToWall || grabRope)
{
rb.useGravity = false;
}
else
{
rb.useGravity = true;
}
if (clingToWall && !isMoving)
{
clingToWall = false;
}
}
private void FixedUpdate()
{
MovePlayer();
}
private void MyInput()
{
horizontalInput = Input.GetAxisRaw("Horizontal");
verticalInput = Input.GetAxisRaw("Vertical");
if(Input.GetKeyDown(jumpKey) && readyToJump && grounded)
{
readyToJump = false;
Jump();
Invoke(nameof(ResetJump), jumpCooldown);
}
if(Input.GetKeyDown(jumpKey) && readyToJump && grabRope)
{
readyToJump = false;
Jump();
Invoke(nameof(ResetJump), jumpCooldown);
}
if(Input.GetKeyDown(jumpKey) && readyToJump && clingToWall)
{
readyToJump = false;
WallJump();
Invoke(nameof(ResetJump), jumpCooldown);
}
if(Input.GetKeyDown(dashKey) && readyToDash)
{
readyToDash = false;
Dash();
Invoke(nameof(ResetDash), dashCooldown);
}
}
private void MovePlayer()
{
moveDirection = orientation.forward * verticalInput + orientation.right * horizontalInput;
if (grounded)
{
rb.AddForce(moveDirection.normalized * moveSpeed * 10f, ForceMode.Force);
}
else if(!grounded)
{
rb.AddForce(moveDirection.normalized * moveSpeed * 10f * airMultiplier, ForceMode.Force);
}
}
private void SpeedControl()
{
Vector3 flatVel = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
if(flatVel.magnitude > moveSpeed)
{
Vector3 limitedVel = flatVel.normalized * moveSpeed;
rb.velocity = new Vector3(limitedVel.x, rb.velocity.y, limitedVel.z);
}
}
private void Jump()
{
rb.velocity = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
rb.AddForce(transform.up * jumpForce, ForceMode.Impulse);
}
private void WallJump()
{
rb.velocity = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
rb.AddForce(playerObj.forward * -1f * wallJumpForce + transform.up * jumpForce, ForceMode.Impulse);
}
private void Dash()
{
rb.velocity = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
if (grounded)
{
rb.AddForce(moveDirection.normalized * moveSpeed * 10f * dashForce, ForceMode.Impulse);
}
else if(!grounded)
{
rb.AddForce(moveDirection.normalized * moveSpeed * 10f * airMultiplier * dashForce, ForceMode.Impulse);
}
}
private void ResetJump()
{
readyToJump = true;
}
private void ResetDash()
{
readyToDash = true;
}
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Ground"))
{
grounded = true;
}
if (other.CompareTag("InteractWall") && isMoving && !grounded)
{
clingToWall = true;
}
if ((other.CompareTag("Rope") && !clingToWall))
{
grabRope = true;
rb.velocity = Vector3.zero;
}
}
private void OnTriggerExit(Collider other)
{
if (other.CompareTag("Ground"))
{
grounded = false;
}
if (other.CompareTag("InteractWall") || !isMoving)
{
clingToWall = false;
}
if (other.CompareTag("Rope"))
{
grabRope = false;
}
}
}