- Home /
Gravity controller is buggy
This is a controller I scripted:
using UnityEngine;
using System.Collections;
[RequireComponent (typeof (PlayerControllerHandler))]
public class PlayerController : MonoBehaviour {
public float gravity;
public float moveSpeed;
private Vector3 velocity;
private float currentGravity;
private PlayerControllerHandler pch;
void Start () {
pch = GetComponent <PlayerControllerHandler> ();
}
void Update () {
currentGravity = velocity.y;
velocity = Vector3.zero;
velocity.y = currentGravity;
if (Input.GetKey (KeyCode.W))
{
velocity += transform.forward;
}
else if (Input.GetKey (KeyCode.A))
{
velocity -= transform.right;
}
if (Input.GetKey (KeyCode.D))
{
velocity += transform.right;
}
else if (Input.GetKey (KeyCode.S))
{
velocity -= transform.forward;
}
velocity.y += gravity * Time.deltaTime;
pch.Move (velocity * Time.deltaTime);
}
}
And this is a controller handler:
using UnityEngine;
using System.Collections;
[RequireComponent (typeof (CapsuleCollider))]
public class PlayerControllerHandler : MonoBehaviour {
public LayerMask collisionMask;
private CapsuleCollider cc;
public int collisions;
void Start () {
cc = GetComponent <CapsuleCollider> ();
}
public void Move (Vector3 velocity) {
Collide (ref velocity);
transform.Translate (velocity);
}
void Collide (ref Vector3 velocity) {
RaycastHit hit;
Vector3 point1 = transform.position + Vector3.up * cc.height / 4;
Vector3 point2 = transform.position + Vector3.up * cc.height * 0.75f;
float rayDistance = Vector3.Distance (transform.position, transform.position + velocity);
if (Physics.CapsuleCast (point1, point2, cc.radius, velocity, out hit, rayDistance))
{
Debug.Log (hit.point.y);
if (Mathf.Abs (transform.position.x - hit.point.x) < Mathf.Abs (velocity.x))
{
collisions ++;
velocity.x = transform.position.x - hit.point.x;
}
if (Mathf.Abs (transform.position.y - hit.point.y) < Mathf.Abs (velocity.y))
{
collisions ++;
velocity.y = transform.position.y - hit.point.y;
}
if (Mathf.Abs (transform.position.z - hit.point.z) < Mathf.Abs (velocity.z))
{
collisions ++;
velocity.z = transform.position.z - hit.point.z;
}
}
}
}
Set the capsule collider to radius 1, height 4. y axis. And youll see he jittters higher and higher. Until hes floating.
I've been staring at a screen for hours now. I think I'll leave it to the community of Unity Answers to help me take this one.
Shot in the dark: It doesn't look like you are taking cc.center, nor cc.direction into account when computing point1 and point2. If either of these are not what you are assu$$anonymous$$g, that could be a problem.
@Glurth well, now I have this and it doesn't register until I'm below the ground.
using UnityEngine;
using System.Collections;
[RequireComponent (typeof (CapsuleCollider))]
public class PlayerControllerHandler : $$anonymous$$onoBehaviour {
public Layer$$anonymous$$ask collision$$anonymous$$ask;
private CapsuleCollider cc;
public int collisions;
void Start () {
cc = GetComponent <CapsuleCollider> ();
}
public void $$anonymous$$ove (Vector3 velocity) {
Collide (ref velocity);
transform.Translate (velocity);
}
void Collide (ref Vector3 velocity) {
RaycastHit hit;
Vector3 point1 = transform.position + cc.center + Vector3.down * cc.height / 4;
Vector3 point2 = transform.position + cc.center + Vector3.up * cc.height / 4;
Debug.Log (point1 + " " + point2);
float rayDistance = Vector3.Distance (transform.position, transform.position + velocity);
if (Physics.CapsuleCast (point1, point2, cc.radius, velocity, out hit, rayDistance))
{
if ($$anonymous$$athf.Abs (transform.position.x - hit.point.x) < $$anonymous$$athf.Abs (velocity.x))
{
collisions ++;
velocity.x = transform.position.x - hit.point.x;
}
if ($$anonymous$$athf.Abs (transform.position.y - hit.point.y) < $$anonymous$$athf.Abs (velocity.y))
{
collisions ++;
velocity.y = transform.position.y - hit.point.y;
}
if ($$anonymous$$athf.Abs (transform.position.z - hit.point.z) < $$anonymous$$athf.Abs (velocity.z))
{
collisions ++;
velocity.z = transform.position.z - hit.point.z;
}
}
}
}
Ah! You are also not taking transform.scale, nor rotation into account, for the points. (http://docs.unity3d.com/ScriptReference/Transform.TransformPoint.html)
Vector3 point1 = transform.TransformPoint( cc.center + Vector3.down * (cc.height -cc.radius) );
Side note: I see you take transform.position into account when computing the ray distance, though it is not actually needed there:
float rayDistance = Vector3.Distance (transform.position, transform.position + velocity);
is equivalent to
float rayDistance = Vector3.Distance (Vector3.zero, Vector3.zero + velocity);
is equivalent to
float rayDistance = velocity.magnitude;
I'm not sure what you meant, but What I want to do is predict where my character will be next frame, and if its gonna be in a wall, move right against the wall.