i've been developing a third person adventure game on Unity with a grappling hook and i found a problem that i don't understand and it's driving me mad. Basically, if the player character collides strong with another object it won't stop moving without my control. Can you help me? Here's a gameplay video (the bug starts on 00:20): https://www.youtube.com/watch?v=2XAw-nIMSvQ&feature=youtu.be
Here's a screenshot of the inspector of the player character and the object that i hooked.
Here's the character controller code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ThirdPersonCharacterControl : MonoBehaviour
{
public float Speed;
//
public Rigidbody rb;
//
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
PlayerMovement();
}
void PlayerMovement()
{
float hor = Input.GetAxis("Horizontal");
float ver = Input.GetAxis("Vertical");
Vector3 playerMovement = new Vector3(hor, 0f, ver) * Speed * Time.deltaTime;
transform.Translate(playerMovement, Space.Self);
//Debug.Log("Movimento");
}
///detetor de colisões
void OnCollisionEnter (Collision col)
{
if(col.gameObject.tag == "collidable")
{
Debug.Log("Tocou");
}
}
///
}
Here's the camera controller:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ThirdPersonCameraControl : MonoBehaviour
{
float rotationSpeed = 1;
public Transform Target, Player;
float mouseX, mouseY;
//aqui meto os obstructions (onde podes fazer grappling hook)
public Transform Obstruction1;
public Transform Obstruction2;
public Transform Obstruction3;
///
float zoomSpeed = 2f;
void Start()
{
Obstruction1 = Target;
Obstruction2 = Target;
Obstruction3 = Target;
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
}
private void LateUpdate()
{
CamControl();
// ViewObstructed();
}
void CamControl()
{
mouseX += Input.GetAxis("Mouse X") * rotationSpeed;
mouseY -= Input.GetAxis("Mouse Y") * rotationSpeed;
mouseY = Mathf.Clamp(mouseY, -35, 60);
transform.LookAt(Target);
if (Input.GetKey(KeyCode.LeftShift))
{
Target.rotation = Quaternion.Euler(mouseY, mouseX, 0);
}
else
{
Target.rotation = Quaternion.Euler(mouseY, mouseX, 0);
Player.rotation = Quaternion.Euler(0, mouseX, 0);
}
}
}
Here's the grappling hook code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GrapplingHook : MonoBehaviour
{
public GameObject hook;
public GameObject hookHolder;
public float hookTravelSpeed;
public float playerTravelSpeed;
public bool jumping;
public static bool fired;
public bool hooked;
public GameObject hookedObj1;
public float maxDistance;
private float currentDistance;
public bool grounded;
public Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
//firing the hook
if (Input.GetMouseButtonDown(1)/*Input.GetKeyDown(KeyCode.E)*/ && fired == false)
{
fired = true;
}
if (fired)
{
LineRenderer rope = hook.GetComponent<LineRenderer>();
rope.SetVertexCount(2);
rope.SetPosition(0, hookHolder.transform.position);
rope.SetPosition(1, hook.transform.position);
}
if (fired == true && hooked == false)
{
hook.transform.Translate(Vector3.forward * Time.deltaTime * hookTravelSpeed);
currentDistance = Vector3.Distance(transform.position, hook.transform.position);
if (currentDistance >= maxDistance)
{
ReturnHook();
}
}
if (hooked == true && fired == true)
{
hook.transform.parent = hookedObj1.transform;
transform.position = Vector3.MoveTowards(transform.position,
hook.transform.position, Time.deltaTime * playerTravelSpeed);
float distanceToHook = Vector3.Distance(transform.position, hook.transform.position);
this.GetComponent<Rigidbody>().useGravity = false;
if (distanceToHook < 1)
{
if (grounded == false)
{
this.transform.Translate(Vector3.forward * Time.deltaTime * 13f);
this.transform.Translate(Vector3.up * Time.deltaTime * 18f);
}
StartCoroutine("Climb");
}
}
else
{
hook.transform.parent = hookHolder.transform;
this.GetComponent<Rigidbody>().useGravity = true;
}
CheckIfGround();
PlayerJump();
}
IEnumerator Climb()
{
yield return new WaitForSeconds(0.1f);
rb.AddForce(new Vector3(0, 3, 0), ForceMode.Impulse);
ReturnHook();
}
void ReturnHook()
{
hook.transform.rotation = hookHolder.transform.rotation;
hook.transform.position = hookHolder.transform.position;
fired = false;
hooked = false;
LineRenderer rope = hook.GetComponent<LineRenderer>();
rope.SetVertexCount(0);
}
public void CheckIfGround()
{
RaycastHit hit;
float distance = 1.1f;
Vector3 dir = new Vector3(0, -1, 0);
if (rb.velocity.y <= 0.1 && Physics.Raycast(transform.position, dir, out hit, distance))
{
grounded = true;
jumping = false;
//Debug.Log("Grounded");
}
else
{
grounded = false;
}
}
void PlayerJump()
{
if (Input.GetKeyDown(KeyCode.Space) && grounded == true)
{
rb.AddForce(new Vector3(0, 20, 0), ForceMode.Impulse);
jumping = true;
//print("jumping");
}
else if (Input.GetKey(KeyCode.Space) && grounded == false && rb.velocity.y < -1)
{
this.GetComponent<Rigidbody>().useGravity = false;
}
}
}
And the hook detector:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HookDetector : MonoBehaviour
{
public GameObject player;
void OnTriggerEnter(Collider other)
{
if(other.tag == "Hookable")
{
player.GetComponent<GrapplingHook>().hooked = true;
player.GetComponent<GrapplingHook>().hookedObj1 = other.gameObject;
//Debug.Log("Tocou");
}
}
}