Climbing wall Script?
So im making a 3D game and i want it to have it so when ever the player bumps into the wall he will try to climb it but i do not know how to program it. I want to have it in C# and im using the original asset for FPS view. Any help?
Answer by Ejpj123 · Apr 11, 2016 at 11:13 PM
Try this :
using UnityEngine;
using System.Collections;
public class MYCLASSNAME : MonoBehaviour {
Transform chController;
bool inside = false;
float heightFactor = 3.2f;
private FPSInputController FPSInput;
void Start (){
FPSInput = GetComponent<FPSInputController>();
}
void OnTriggerEnter ( Collider Col ){
if(Col.gameObject.tag == "Ladder")
{
FPSInput.enabled = false;
inside = !inside;
}
}
void OnTriggerExit ( Collider Col ){
if(Col.gameObject.tag == "Ladder")
{
FPSInput.enabled = true;
inside = !inside;
}
}
void Update (){
if(inside == true && Input.GetKey("w"))
{
chController.transform.position += Vector3.up / heightFactor;
}
}
[RPC]
void Test (){}
}
Answer by GEOBA · Apr 11, 2016 at 11:27 PM
You would have to use Physics.CheckSphere or Physics.CheckBox or you can use a trigger to check if the player is near a wall. Then you do a Raycast from the player's position with the player's forward vector to check if the player is facing the wall. If the player is near a wall and is facing the wall then the player can climb the wall. Also don't forget to use a layermask to make sure only climbable object are detected.
Try this:
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(CapsuleCollider))]
public class ClimbScript : MonoBehaviour
{
public float WalkSpeed = 5f;
public float ClimbSpeed = 3f;
public LayerMask wallMask;
bool climbing;
Vector3 wallPoint;
Vector3 wallNormal;
Rigidbody body;
CapsuleCollider coll;
// Use this for initialization
void Start ()
{
body = GetComponent<Rigidbody>();
coll = GetComponent<CapsuleCollider>();
}
void FixedUpdate ()
{
if (NearWall())
{
if (FacingWall())
{
// if player presses the climb button
if (Input.GetKeyUp(KeyCode.C))
{
climbing = !climbing;
}
}
else
{
climbing = false;
}
}
else
{
climbing = false;
}
if (climbing)
{
ClimbWall();
}
else
{
Walk();
}
}
void Walk()
{
body.useGravity = true;
var v = Input.GetAxis("Vertical");
var h = Input.GetAxis("Horizontal");
var move = transform.forward * v + transform.right * h;
ApplyMove(move, WalkSpeed);
}
bool NearWall()
{
return Physics.CheckSphere(transform.position, 3f, wallMask);
}
bool FacingWall()
{
RaycastHit hit;
var facingWall = Physics.Raycast(transform.position, transform.forward, out hit, coll.radius + 1f, wallMask);
wallPoint = hit.point;
wallNormal = hit.normal;
return facingWall;
}
void ClimbWall()
{
body.useGravity = false;
GrabWall();
var v = Input.GetAxis("Vertical");
var h = Input.GetAxis("Horizontal");
var move = transform.up * v + transform.right * h;
ApplyMove(move, ClimbSpeed);
}
void GrabWall()
{
var newPosition = wallPoint + wallNormal * (coll.radius - 0.1f);
transform.position = Vector3.Lerp(transform.position, newPosition, 10 * Time.deltaTime);
if (wallNormal == Vector3.zero)
return;
transform.rotation = Quaternion.LookRotation(-wallNormal);
}
void ApplyMove(Vector3 move, float speed)
{
body.MovePosition(transform.position + move * speed * Time.deltaTime);
}
}
Thanks for sharing this script. This will go a long ways of helping a person I know.
Answer by drjayb20 · Jan 02, 2020 at 12:41 PM
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class WallClimb : MonoBehaviour { Ray ray; public float range = 1f; public float climbspeed = 5f; public float sticktowallforce = 5f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
RaycastHit hit;
if (Physics.Raycast(transform.position, transform.forward, out hit, range))
{
if (hit.transform.tag == "Wall")
{
if (Input.GetKey(KeyCode.Space))
{
transform.position += transform.forward * Time.deltaTime * sticktowallforce;
transform.position += transform.up * Time.deltaTime * climbspeed;
}
}
}
}
}
Hello drjayb20,
I tried using this script in my own game. But it did not work. I did exactly the same you did.
And now i added some gravity to it, and now it works. ( It does not work, how it suppose to be work. But it works :p )
This here is my script i used, i dont know what i did wrong. I added gravity to it, that is the only thing how it works right now
public float climbSpeed = 5f;
public float sticktowall = 1f;
public float range = 2f;
public void WallClimbing()
{
RaycastHit hit;
if (Physics.Raycast(transform.position, transform.forward, out hit, range))
{
if (hit.transform.tag == "WallClimbing")
{
gravity = 1f;
if (Input.GetKey(KeyCode.Space))
{
transform.position += transform.forward * Time.deltaTime * sticktowall;
transform.position += transform.up * Time.deltaTime * climbSpeed;
}
}
}
else
{
gravity = -7.81f;
}
}
Your answer
Follow this Question
Related Questions
Animation problem? 0 Answers
My player doesn't take fall damage ... please help 0 Answers
How to copy and paste animation events from one clip to another if those clips are included in FBXs? 1 Answer
How can I add an article to a noun in this C# code? 0 Answers
How to use hold/tap interactions in new Input System 0 Answers