Question by
mematfmm · Jul 08, 2019 at 03:22 PM ·
movementmovement script
achieveing half-life like surfing
hello fellas. i'm trying to achieve surfing in my game. i already have a movement script that emulates half-life like bunnyhopping but the only problem with it is that, when i'm on a slope that is more than 45 degrees steep i don't slide off, i just awkwardly sit there. i don't know where to start with this, so pretty much anything is welcome.
my current movement script (uses a character controller, not a rigidbody):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// class used for handling localplayer movement.
/// TODO: source-engine like command system (check c_usercmd)
/// </summary>
public class local_controller : MonoBehaviour {
Transform m_camera_transform;
CharacterController m_controller;
public float m_f_mouse_sensitivity_x = 5f;
public float m_f_mouse_sensitivity_y = 5f;
public float m_f_jump_speed = 8f;
public float m_f_gravity = 20f;
public float m_f_camera_y_offset = 0.8f;
public float m_f_friction = 8f;
public float m_f_ground_acceleration = 100f;
public float m_f_ground_max_velocity = 8f;
public float m_f_air_acceleration = 110f;
public float m_f_air_max_velocity = 30f;
public float m_f_air_control = 2f;
float m_yaw = 0.022f;
float m_pitch = 0.022f;
float m_rotation_x;
float m_rotation_y;
bool m_is_jumping;
Vector3 m_camera_offset_vector;
Vector3 m_move_direction = Vector3.zero;
Vector3 m_move_direction_temp = Vector3.zero;
void Start() {
m_camera_transform = gameObject.GetComponentInChildren<Camera>().transform;
m_camera_offset_vector = new Vector3(0, m_f_camera_y_offset, 0);
m_camera_transform.position = transform.position + m_camera_offset_vector;
m_controller = gameObject.GetComponent<CharacterController>();
}
void FixedUpdate() {
// don't update player movement every single frame, might cause problems on higher framerates
m_controller.Move(m_move_direction * Time.fixedDeltaTime);
}
void Update() {
if (Cursor.lockState != CursorLockMode.Locked && Input.GetButtonDown("Fire1")) {
Cursor.lockState = CursorLockMode.Locked;
}
// get mouse input
m_rotation_y += Input.GetAxisRaw("Mouse X") * m_f_mouse_sensitivity_x * m_yaw;
m_rotation_x -= Input.GetAxisRaw("Mouse Y") * m_f_mouse_sensitivity_y * m_pitch;
// clamp eyeangles
if (m_rotation_x < -90)
m_rotation_x = -90;
else if (m_rotation_x > 90)
m_rotation_x = 90;
if (m_rotation_y < -360 || m_rotation_y > 360)
m_rotation_y = m_rotation_y % 360;
this.transform.rotation = Quaternion.Euler(0, m_rotation_y, 0);
m_camera_transform.rotation = Quaternion.Euler(m_rotation_x, m_rotation_y, 0);
// more input stuff
float input_x = Input.GetAxisRaw("Horizontal");
float input_y = Input.GetAxisRaw("Vertical");
m_move_direction = new Vector3(input_x, 0, input_y).normalized;
m_move_direction = transform.TransformDirection(m_move_direction);
// handle player related physics / movement
if (!m_controller.isGrounded || m_is_jumping)
m_move_direction = move_air(m_move_direction, m_controller.velocity);
else if (m_controller.isGrounded && !m_is_jumping)
m_move_direction = move_ground(m_move_direction, m_controller.velocity);
// autojump / bunnyhopping
if (m_controller.isGrounded)
m_is_jumping = false;
if (Input.GetButton("Jump") && m_controller.isGrounded) {
m_is_jumping = true;
m_move_direction.y = m_f_jump_speed;
}
m_move_direction.y -= m_f_gravity * Time.deltaTime;
}
private Vector3 accelerate(Vector3 accelerate_direction, Vector3 previous_velocity, float accelerate, float max_velocity) {
float projVel = Vector3.Dot(previous_velocity, accelerate_direction);
float accelVel = accelerate * Time.fixedDeltaTime;
if (projVel + accelVel > max_velocity)
accelVel = max_velocity - projVel;
return previous_velocity + accelerate_direction * accelVel;
}
private Vector3 air_accelerate(Vector3 wished_direction, Vector3 previous_velocity, float accelerate, float max_velocity) {
if (wished_direction.magnitude == 0)
return previous_velocity;
float proj_velocity = Vector3.Dot(previous_velocity, wished_direction);
float accel_velocity = accelerate * Time.fixedDeltaTime;
if (proj_velocity < 0) {
previous_velocity += wished_direction * accel_velocity;
float y_speed = previous_velocity.y;
previous_velocity.y = 0;
float speed = previous_velocity.magnitude;
previous_velocity.Normalize();
proj_velocity = Vector3.Dot(previous_velocity, wished_direction);
float k = 32;
k *= m_f_air_control * proj_velocity * proj_velocity * Time.deltaTime;
if (speed > max_velocity)
speed *= max_velocity / speed;
previous_velocity.x = previous_velocity.x * speed + wished_direction.x * k;
previous_velocity.y = previous_velocity.y * speed + wished_direction.y * k;
previous_velocity.z = previous_velocity.z * speed + wished_direction.z * k;
previous_velocity.Normalize();
previous_velocity.x *= speed;
previous_velocity.y = y_speed;
previous_velocity.z *= speed;
} else if (accel_velocity >= 0)
if (Mathf.Sqrt(Mathf.Pow(previous_velocity.x, 2) + Mathf.Pow(previous_velocity.z, 2)) < 2f)
previous_velocity += wished_direction * 2 * Time.fixedDeltaTime;
return previous_velocity;
}
private Vector3 move_ground(Vector3 accel_direction, Vector3 previous_velocity) {
float speed = previous_velocity.magnitude;
if (speed != 0 && m_controller.isGrounded) {
float drop = speed * m_f_friction * Time.fixedDeltaTime;
previous_velocity *= Mathf.Max(speed - drop, 0) / speed;
}
return accelerate(accel_direction, previous_velocity, m_f_ground_acceleration, m_f_ground_max_velocity);
}
private Vector3 move_air(Vector3 accel_direction, Vector3 previous_velocity) {
return air_accelerate(accel_direction, previous_velocity, m_f_air_acceleration, m_f_air_max_velocity);
}
private void OnGUI() {
GUI.Label(new Rect(new Vector2(5, 5), new Vector2(Screen.width - 5, 100)), "m_speed: " + m_controller.velocity.magnitude * 36f + "ups"); // for goldsrc / source-like unit measurements
GUI.Label(new Rect(new Vector2(5, 15), new Vector2(Screen.width - 5, 100)), "m_is_jumping: " + m_is_jumping);
}
}
regards
Comment