Wednesday, November 6, 2019

Player Controllable Physics Ball

Just two scripts for now without proper explanation, but they should work as long as you have a sphere with sphere collider and rigidbody, add those scripts to it and point first one's head property to your camera :3
using UnityEngine;
 
public class BallPlayerController : MonoBehaviour
{
 public Transform head;
 
 public float movementTorque = 6.0F;
 
 private Rigidbody rb;
 
 private float pitch;
 private float yaw;
 
 // Use this for initialization
 void Start()
 {
  rb = GetComponent<Rigidbody>();
  head.parent = null;
 }
 
 // Update physics
 void FixedUpdate()
 {
  //Add torque to rotate ball in the direction we are looking
  rb.AddTorque(-head.forward * Input.GetAxis("Horizontal"* movementTorque);
  rb.AddTorque(head.right * Input.GetAxis("Vertical"* movementTorque);
 }
 
 // Update is called once per frame
 void Update()
 {
  //Rotate head around and make it follow the player
  yaw += Input.GetAxis("Mouse X") * 10;
  pitch = Mathf.Clamp(pitch - Input.GetAxis("Mouse Y") * 5, -70, 70);
  head.rotation = Quaternion.Euler(pitch, yaw, 0);
  head.transform.position = transform.position - head.forward * 5 + Vector3.up * 1;
 }
}
using UnityEngine;
 
public class PhysicsJump : MonoBehaviour
{
 public float jumpForce = 5;
 
 public bool grounded;
 
 private bool jump = false;
 
 private Rigidbody rb;
 
 void Start()
 {
  rb = GetComponent<Rigidbody>();
 }
 
 private void Update()
 {
  jump = Input.GetButtonDown("Jump");
 }
 
 void FixedUpdate()
 {
  if (rb.IsSleeping())
   grounded = true;
 
  if (grounded)
  {
   if (jump)
   {
    rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
   }
  }
  jump = false;
  grounded = false;
 }
 
 private void OnCollisionStay(Collision collision)
 {
  for (int i = 0; i < collision.contactCount; i++)
  {
   var cp = collision.GetContact(i);
   if (cp.normal.y > 0)
   {
    grounded = true;
   }
  }
 }
}

Thursday, May 9, 2019

First Person Controller

Let's make simple first person controller, that will let us move around level in first person mode. Start by making empty game object and call it FirstPersonConttroller, then add character controller component to it. This will represent body of our character, but we still need head so we can see anything. Your scene should already have camera, drag it on top of your newly created FirstPersonController in Hierarchy tab (on the left) so it will become child of it. Then, position it so it's in the center and a bit above (where head should be). When you are done, it should look like on this picture:
Next, create new script and add it to your FirstPersonController

using UnityEngine;
 
public class FirstPersonController : MonoBehaviour
{
    public Transform head;
 
    private CharacterController cc;
 
    private float pitch;
    private float yaw;
 
    public float speed = 6.0F;
    public float jumpSpeed = 8.0F;
    public float gravity = 20.0F;
 
    private Vector3 moveDirection = Vector3.zero;
 
    // Use this for initialization
    void Start()
    {
        //Initialize various usefull things
        cc = GetComponent<CharacterController>();
        pitch = head.transform.localEulerAngles.x;
        yaw = transform.localEulerAngles.y;
 
        //Let's hide lock cursor so its not going outside the window
        Cursor.visible = false;
        Cursor.lockState = CursorLockMode.Locked;
    }
 
    // Update is called once per frame
    void Update()
    {
        if (cc.isGrounded)
        {
            // If we are touching the ground, calculate movement and jumping
            moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
            moveDirection = transform.TransformDirection(moveDirection);
            moveDirection *= speed;
            if (Input.GetButton("Jump"))
                moveDirection.y = jumpSpeed;
        }
 
        // Always apply gravity
        moveDirection.y -= gravity * Time.deltaTime;
 
        //Move our character
        cc.Move(moveDirection * Time.deltaTime);
 
        //We rotate whole body when looking around
        yaw += Input.GetAxis("Mouse X") * 10;
        transform.localRotation = Quaternion.Euler(0, yaw, 0);
 
        //But only rotate head when looking up and down
        pitch = Mathf.Clamp(pitch - Input.GetAxis("Mouse Y") * 5, -70, 70);
        head.localRotation = Quaternion.Euler(pitch, 0, 0);
    }
}

Next, we have to show our FirstPersonController script where our head is. With FirstPersonController oject selected, drag your head (Main Camera) into 'Head' property of your script, as in following picture.
Congratulations, you now have fully working first person player controller. Add some geometry to your level and test it!