0
\$\begingroup\$

The fpscontroller is moving around using wsad and I can move the mouse and looking around, That's all fine.

The problem is with the doors. When you getting close to a door it will trigger and will open automatic. At this point the player the fpscontroller is stopping and I need to jump to move through.

I tried to change the player height a bit even it's scaling but it didn't help much.

Screenshot of the player2 in the Hierarchy and it's Inspector:

Player2 (FPSController

The MouseCursorState script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MouseCursorState : UnityEngine.MonoBehaviour
{
    void Start ()
    {
        Cursor.visible = false;
}

The MouseLook script:

using UnityEngine;
using System.Collections;

/// MouseLook rotates the transform based on the mouse delta.
/// Minimum and Maximum values can be used to constrain the possible rotation

/// To make an FPS style character:
/// - Create a capsule.
/// - Add the MouseLook script to the capsule.
///   -> Set the mouse look to use LookX. (You want to only turn character but not tilt it)
/// - Add FPSInputController script to the capsule
///   -> A CharacterMotor and a CharacterController component will be automatically added.

/// - Create a camera. Make the camera a child of the capsule. Reset it's transform.
/// - Add a MouseLook script to the camera.
///   -> Set the mouse look to use LookY. (You want the camera to tilt up and down like a head. The character already turns.)
[AddComponentMenu("Camera-Control/Mouse Look")]
public class MouseLook : MonoBehaviour {

    public enum RotationAxes { MouseXAndY = 0, MouseX = 1, MouseY = 2 }
    public RotationAxes axes = RotationAxes.MouseXAndY;
    private float sensitivityX = 5f;
    private float sensitivityY = 5f;

    private float minimumX = 0f;
    private float maximumX = 360f;

    private float minimumY = -30f;
    private float maximumY = 45f;

    private float rotationY = 0f;

    void Update ()
    {
        if (axes == RotationAxes.MouseXAndY)
        {
            float rotationX = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * sensitivityX;

            rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
            rotationY = Mathf.Clamp (rotationY, minimumY, maximumY);

            transform.localEulerAngles = new Vector3(-rotationY, rotationX, 0);
        }
        else if (axes == RotationAxes.MouseX)
        {
            transform.Rotate(0, Input.GetAxis("Mouse X") * sensitivityX, 0);
        }
        else
        {
            rotationY += Input.GetAxis("Mouse Y") * sensitivityY;
            rotationY = Mathf.Clamp (rotationY, minimumY, maximumY);

            transform.localEulerAngles = new Vector3(-rotationY, transform.localEulerAngles.y, 0);
        }
    }

    void Start ()
    {
        // Make the rigid body not change rotation
        if (GetComponent<Rigidbody>())
            GetComponent<Rigidbody>().freezeRotation = true;
    }
}

And the PlayerController script:

using UnityEngine;
using System.Collections;

[RequireComponent (typeof (Rigidbody))]
[RequireComponent (typeof (BoxCollider))]

public class PlayerController : MonoBehaviour {

    public float walkSpeed = 6;
    public float runSpeed = 10;
    public float strafeSpeed = 5;
    public float gravity = 20;
    public float jumpHeight = 2;
    public bool canJump = true;
    private bool isRunning = false;
    private bool isGrounded = false;

    public bool IsRunning
    {
        get { return isRunning; }
    }

    void Awake () {
        GetComponent<Rigidbody>().freezeRotation = true;
        GetComponent<Rigidbody>().useGravity = false;
    }

    void FixedUpdate () {
        // get correct speed
        float forwardAndBackSpeed = walkSpeed;

        // if running, set run speed
        if (isRunning) {
            forwardAndBackSpeed = runSpeed;
        }

        // calculate how fast it should be moving
        Vector3 targetVelocity = new Vector3(Input.GetAxis("Horizontal") * strafeSpeed, 0, Input.GetAxis("Vertical") * forwardAndBackSpeed);
        targetVelocity = transform.TransformDirection(targetVelocity);

        // apply a force that attempts to reach our target velocity
        Vector3 velocity = GetComponent<Rigidbody>().velocity;
        Vector3 velocityChange = (targetVelocity - velocity);
        velocityChange.y = 0;
        GetComponent<Rigidbody>().AddForce(velocityChange, ForceMode.VelocityChange);

        // jump
        if (canJump && isGrounded && Input.GetButton("Jump")) {
            GetComponent<Rigidbody>().velocity = new Vector3(velocity.x, Mathf.Sqrt(2 * jumpHeight * gravity), velocity.z);
            isGrounded = false;
        }

        // apply gravity
        GetComponent<Rigidbody>().AddForce(new Vector3 (0, -gravity * GetComponent<Rigidbody>().mass, 0));
    }

    void Update() {
        // check if the player is touching a surface below them
        checkGrounded();

        // check if the player is running
        if (isGrounded && Input.GetButtonDown("Sprint")) {
            isRunning = true;
        }

        // check if the player stops running
        if (Input.GetButtonUp("Sprint")) {
            isRunning = false;
        }
    }

    void checkGrounded() {
        /* ==============
         * REMEMBER
         * ==============
         * If you change the size of the prefab, you may have
         * to change the length of the ray to ensure it hits
         * the ground.
         * 
         * All obstacles/walls/floors must have rigidbodies
         * attached to them. If not, Unity physics may get
         * confused and the player can jump really high
         * when in a corner between 2 walls for example.
         */
        float rayLength = 0.7f;
        RaycastHit hit;
        Ray ray = new Ray(transform.position, -transform.up);
        //Debug.DrawRay(ray.origin, ray.direction * rayLength);
        // if there is something directly below the player
        if (Physics.Raycast(ray, out hit, rayLength)) {
            isGrounded = true;
        }
    }


}

The player2 body child is just a Cube: This screenshot showing the player2 and the navi:

Player2 (FPSController)

The mouse look script is also attached to the camera parent child but the Axes is set to Mouse Y

The camera child is just a Main Camera.

The NAVI have a script attached to it and a rigidbody component and a Camera: Screenshot of the NAVI Inspector:

NAVI Inspector

Everything is moving smooth and I can look around with the mouse. The problem is when a door is opened the player can't move through. Sometimes or in most of the door I need to make jump to go through.

I don't think that the problem is with the doors. If I change the player2 height or scale sometimes it's working better.

I was thinking about buying a fp controller but not sure what is the best one and I don't need something special for now. Just a smooth moving look around fpcontroller no need even to jump. The only problem so far is with the doors.

UPDATE:

The doors. The doors parent have a script attached that open/close the door automatic by playing animation: It's called DoorVert:

I changed in the Door Vert script in the Inspector the value of Translate Value to 4 this is the only change I tried.

using UnityEngine;
using System.Collections;

public class DoorVert : UnityEngine.MonoBehaviour {

    public float translateValue;
    public float easeTime;
    public OTween.EaseType ease;
    public float waitTime;
    public Light[] lt;
    public UnityEngine.Renderer[] renderers;
    public bool doorLocked = false;
    public bool locked = false;

    private Vector3 StartlocalPos;
    private Vector3 endlocalPos;


    private void Start(){
        StartlocalPos = transform.localPosition;    
        gameObject.isStatic = false;

        if (doorLocked == true)
        {
            for (int i = 0; i < lt.Length; i++)
            {
                lt[i].color = Color.red;
                renderers[i].material.color = Color.red;
            }
        }
    }

    public void OpenDoor(){
        if (doorLocked == false)
        {
            OTween.ValueTo(gameObject, ease, 0.0f, -translateValue, easeTime, 0.0f, "StartOpen", "UpdateOpenDoor", "EndOpen");
            GetComponent<AudioSource>().Play();
        }
    }

    private void UpdateOpenDoor(float f){
        if (doorLocked == false)
        {
            Vector3 pos = transform.TransformDirection(new Vector3(0, 1, 0));
            transform.localPosition = StartlocalPos + pos * f;
        }

    }

    private void UpdateCloseDoor(float f){
        if (doorLocked == false)
        {
            Vector3 pos = transform.TransformDirection(new Vector3(0, -f, 0));
            transform.localPosition = endlocalPos - pos;
        }

    }

    private void EndOpen(){
        if (doorLocked == false)
        {
            endlocalPos = transform.localPosition;
            StartCoroutine(WaitToClose());
        }
    }

    private IEnumerator WaitToClose(){

        yield return new WaitForSeconds(waitTime);
        OTween.ValueTo( gameObject,ease,0.0f,translateValue,easeTime,0.0f,"StartClose","UpdateCloseDoor","EndClose");
        GetComponent<AudioSource>().Play();
    }

    private void Update()
    {
        if (locked == true)
        {
            doorLocked = true;
            for (int i = 0; i < lt.Length; i++)
            {
                lt[i].color = Color.red;
                renderers[i].material.color = Color.red;
            }
        }
        else
        {
            doorLocked = false;
            for (int i = 0; i < lt.Length; i++)
            {
                lt[i].color = Color.green;
                renderers[i].material.color = Color.green;
            }
        }
    }
}

This is a screenshot of a door parent:

Door Parent

Each door have a child. The child have a box collider:

Door Child

\$\endgroup\$
  • 1
    \$\begingroup\$ How is the door opened? Do you hide it? Do you play an animation? Please show a door in scene view preferably without all those camera and light gizmos, and its inspector settings. You should check that the door has its own collider (not the same one as the wall it’s on) and that it’s moved along with the door, or disabled, when the door is opened \$\endgroup\$ – Leon May 20 '18 at 4:31
  • \$\begingroup\$ @Leon I edited my question with an Update about the doors added the script that attached to each door that open/close the doors. And screenshots. Each door have a child and this child have a box collider. And the script that open/close the door is attached to the parent. \$\endgroup\$ – Benzi Avrumi May 20 '18 at 6:11
  • 2
    \$\begingroup\$ Checking again your comments about the player 2 and having to jump to move through the door makes me think there is something like a small step or maybe a misalignment on the floor. A capsule collider instead of the box collider would make it easier to navigate a floor that is not perfectly flat. When it finds the step it will “creep up” past it instead of just being blocked by it (which is what a box collider would do) \$\endgroup\$ – Leon May 20 '18 at 6:53
  • \$\begingroup\$ @Leon I'm trying to testing it now but can't I'm facing another problem. \$\endgroup\$ – Benzi Avrumi May 20 '18 at 21:27
  • \$\begingroup\$ Yes, capsule collider seems to be what the player needs. \$\endgroup\$ – Nikaas May 21 '18 at 4:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.