Reputation: 11319
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;
}
}
The controller script:
using UnityEngine;
using System.Collections;
//[RequireComponent (typeof (Rigidbody))]
//[RequireComponent (typeof (BoxCollider))]
public class PlayerController : MonoBehaviour {
private void Update()
{
var x = Input.GetAxis("Horizontal") * Time.deltaTime * 150.0f;
var z = Input.GetAxis("Vertical") * Time.deltaTime * 3.0f;
transform.Rotate(0, x, 0);
transform.Translate(0, 0, z);
}
}
When I use the mouse for example to look to the floor and move forward the player it will move through the floor.
I'm using box collider and I also tried to add a mesh collider but it didn't help so far.
The NAVI have a Rigidbody component attached to it. I also had a Rigidbody attached to the Player and then he didn't walk through the floor but then the Rigidbody did problems with the doors. The doors opened/closed fast and many times with the Rigidbody.
Upvotes: 0
Views: 1532
Reputation: 125265
To prevent two colliders from going through one another, you will have two options:
1.Use raycast to detect walls then manually adjust the position of the object or stop moving the player.
2.Use Rigidbody to automatically handle the collision then use Rigidbody.MovePosition
and Rigidbody.MoveRotation
to move and rotate the object instead of the transform.Translate
and transform.Rotate
used in your current code.
I prefer #2 since it's easier to code and more reliable. Just attach Rigidbody
and a collider to the player. Also attach collider to the walls and floors. The code below should move the player and it will not go through the walls.
public bool useWorldSpace;
public Rigidbody rb;
public float speed = 18;
public void Update()
{
float h = Input.GetAxisRaw("Horizontal");
float v = Input.GetAxisRaw("Vertical");
//Movement
Vector3 tempVect = new Vector3(0, 0, v);
tempVect = tempVect.normalized * speed * Time.deltaTime;
if (useWorldSpace)
tempVect = transform.position + tempVect;
else
tempVect = transform.position + transform.TransformDirection(tempVect);
rb.MovePosition(tempVect);
//Rotation
Vector3 angle = new Vector3(0, 100, 0);
Quaternion deltaRot = Quaternion.Euler(angle * h * Time.deltaTime);
rb.MoveRotation(rb.rotation * deltaRot);
}
Upvotes: 3