This script is on the character. When the character starts to move, his face turns towards the camera. This code needs to be redone so that the character always looks towards the camera, even if he is standing still.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TPM : MonoBehaviour
{
CharacterController controller;
public Transform cam;
public float speed = 6f;
public float turnSmoothTime = 0.1f;
float turnSmoothVelocity;
private void Start()
{
controller = GetComponent<CharacterController>();
}
private void Update()
{
float horizontal = Input.GetAxis("Horizontal");
float vertical = Input.GetAxis("Vertical");
Vector3 direction = new Vector3(horizontal, 0f, vertical).normalized;
if(direction.magnitude >= 0.1f)
{
float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + cam.eulerAngles.y;
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
transform.rotation = Quaternion.Euler(0f, angle, 0f);
Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
controller.Move(moveDir.normalized * speed * Time.deltaTime);
}
}
}
use transform.LookAt(Camera.main.transform.position) in your Update.
Here is a suitable solution I found
public Transform cam;
public float speed = 5f;
private void FixedUpdate()
{
transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.Euler(0f, cam.rotation.eulerAngles.y, 0f), speed * Time.deltaTime);
}
Related
Hello can you help to make the player jump
also how to make the player crouch?
this is my move script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement : MonoBehaviour
{
public CharacterController controller;
public Transform cam;
public float speed = 6f;
public float turnsmoothT = 0.1f;
float turnsmoothV;
void Update()
{
float horizontal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
Vector3 direction = new Vector3(horizontal, 0f, vertical).normalized;
if (direction.magnitude >= 0.1f)
{
float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + cam.eulerAngles.y;
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnsmoothV, turnsmoothT);
transform.rotation = Quaternion.Euler(0f, angle, 0f);
Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
controller.Move(moveDir.normalized * speed * Time.deltaTime);
}
}
}
..................................................................................................................................................................................................................................................................
See if this helps:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement : MonoBehaviour
{
public CharacterController controller;
public Transform cam;
public float speed = 6f;
public float turnsmoothT = 0.1f;
private float turnsmoothV;
private bool jumping = false;
private float moveDirectionY = 0;
private float gravity = 9.81f;
private void Update()
{
float horizontal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
Vector3 direction = new Vector3(horizontal, 0f, vertical).normalized;
Vector3 moveDir = Vector3.zero;
if (jumping && controller.isGrounded)
{
jumping = false;
}
if (Input.GetKeyDown(KeyCode.Space) && !jumping && controller.isGrounded)
{
moveDirectionY = 3f;
jumping = true;
}
if (direction.magnitude >= 0.1f)
{
float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + cam.eulerAngles.y;
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnsmoothV, turnsmoothT);
transform.rotation = Quaternion.Euler(0f, angle, 0f);
moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
}
moveDirectionY -= gravity * Time.deltaTime;
moveDir.y = moveDirectionY;
controller.Move(moveDir * speed * Time.deltaTime);
}
}
I made a simple movement system in Unity 3D, but I don't know how to make it so that I move in the direction my player is pointing in.
using UnityEngine;
public class PlayerControler : MonoBehaviour
{
CharacterController characterController;
public float MovementSpeed = 1f;
public float Gravity = 9.8f;
private float velocity = 0f;
void Start()
{
characterController = GetComponent<CharacterController>();
}
void Update()
{
float horizontal = Input.GetAxis("Horizontal") * MovementSpeed;
float vertical = Input.GetAxis("Vertical") * MovementSpeed;
characterController.Move((Vector3.right * horizontal + Vector3.forward * vertical) * Time.deltaTime);
if (characterController.isGrounded)
{
velocity = 0;
}
else
{
velocity -= Gravity * Time.deltaTime;
characterController.Move(new Vector3(0, velocity, 0));
}
}
}
This is the player controller.
using UnityEngine;
public class MouseControl : MonoBehaviour
{
public float horizontalSpeed = 1f;
public float verticalSpeed = 1f;
private float xRotation = 0.0f;
private float yRotation = 0.0f;
private Camera cam;
void Start()
{
cam = Camera.main;
}
void Update()
{
float mouseX = Input.GetAxis("Mouse X") * horizontalSpeed;
float mouseY = Input.GetAxis("Mouse Y") * verticalSpeed;
yRotation += mouseX;
xRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, -90f, 90f);
cam.transform.eulerAngles = new Vector3(xRotation, yRotation, 0.0f);
}
}
This is the code that makes my character face where my cursor is.
Edit: This is a First-Person 3D game. The player has a CharacterControler component on it, and the Main Camera is a child of the player. The second piece of code changes the direction that the camera is facing when the cursor is moved. The first script is the movement script, and utilises the CharacterController component of the player to move. I want to make to that instead of going in four static directions every time I press a movement key, I want the player to move in proportion to the direction that the camera is facing (on the X axis). E.g: If I am facing West and I press “W” to go forwards, I want the character to go West instead of North.
Instead of the global vectors Vector3.forward and Vector3.right in
characterController.Move((Vector3.right * horizontal + Vector3.forward * vertical) * Time.deltaTime);
rather use your local direction vectors Transform.forward and Transform.right
characterController.Move((transform.right * horizontal + transform.forward * vertical) * Time.deltaTime);
#derHugo was right, but I forgot to update the angles in the player movement script, so it always thought that I was rotated 0,0,0.
using UnityEngine;
public class PlayerControler : MonoBehaviour
{
Vector3 angles;
CharacterController characterController;
MouseControl mouseControl;
public float MovementSpeed = 1f;
public float Gravity = 9.8f;
private float velocity = 0f;
void Start()
{
characterController = GetComponent<CharacterController>();
mouseControl = GetComponent<MouseControl>();
}
void Update()
{
angles = new Vector3(mouseControl.xRotation, mouseControl.yRotation, 0f);
transform.eulerAngles = angles;
float horizontal = Input.GetAxis("Horizontal") * MovementSpeed;
float vertical = Input.GetAxis("Vertical") * MovementSpeed;
characterController.Move((transform.right * horizontal + transform.forward * vertical) * Time.deltaTime);
if (characterController.isGrounded)
{
velocity = 0;
}
else
{
velocity -= Gravity * Time.deltaTime;
characterController.Move(new Vector3(0, velocity, 0));
}
}
}
Updated code
Note: I had to made the X and Y rotation variables public.
[HideInInspector]public float xRotation = 0.0f;
[HideInInspector]public float yRotation = 0.0f;
I'm quite new to coding and making games. I created this script with the help of some YT tutorials and I was wondering how to make my character jump higher while holding doing the space bar. I tried different things but non worked properly. Here's my character code. Thanks!
using System;
using UnityEngine;
using UnityEngine.UI;
public class TPMovementScript : MonoBehaviour
{
public CharacterController controller;
public Transform cam;
public float speed = 6f;
public float jump = 10f;
public float gravity = -9.81f;
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;
public float jumpHeight = 3f;
Vector3 velocity;
bool isGrounded;
public float turnSmoothTime = 0.1f;
float turnSmoothVelocity;
// Update is called once per frame
void Update()
{
//Checks if player is grounded & resets velocity
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
if (isGrounded && velocity.y < 0)
{
velocity.y = -2f;
}
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
//Makes Player move Using WASD or upDownLeftRight
float horizontal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
Vector3 direction = new Vector3(horizontal, 0f, vertical).normalized.normalized;
if (isGrounded && Input.GetKey(KeyCode.Space))
{
velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
}
//Makes Character face direction and makes forward to camera position
if (direction.magnitude >= 0.1f)
{
float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + cam.eulerAngles.y;
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
transform.rotation = Quaternion.Euler(0f, angle, 0f);
Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
controller.Move(moveDir.normalized * speed * Time.deltaTime);
}
}
}
This looks like answer to your problem https://www.youtube.com/watch?v=j111eKN8sJw and code is similar.
I have two scripts one is the MouseHandler and the other is the SimpleMovement. rotating the camera works and moving works however when the camera turns the movement doesn't go in that direction. E.G i turn the camera 90 degrees to the right but the forward doesn't change. The forward doesn't go to where the camera is facing. Sorry if i'm just being stupid. Any help would be appreciated
MouseHandler script:
public class MouseHandler : MonoBehaviour
{
// horizontal rotation speed
public float horizontalSpeed = 1f;
// vertical rotation speed
public float verticalSpeed = 1f;
private float xRotation = 0.0f;
private float yRotation = 0.0f;
private Camera cam;
void Start()
{
cam = Camera.main;
}
void Update()
{
float mouseX = Input.GetAxis("Mouse X") * horizontalSpeed;
float mouseY = Input.GetAxis("Mouse Y") * verticalSpeed;
yRotation += mouseX;
xRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, -90, 90);
cam.transform.eulerAngles = new Vector3(xRotation, yRotation, 0.0f);
}
}
SimpleMovement Script:
public class SimpleMovement : MonoBehaviour
{
CharacterController characterController;
public float MovementSpeed = 1;
public float Gravity = 9.8f;
private float velocity = 0;
private void Start()
{
characterController = GetComponent<CharacterController>();
}
void Update()
{
// player movement - forward, backward, left, right
float horizontal = Input.GetAxis("Horizontal") * MovementSpeed;
float vertical = Input.GetAxis("Vertical") * MovementSpeed;
characterController.Move((Vector3.right * horizontal + Vector3.forward * vertical) * Time.deltaTime);
// Gravity
if (characterController.isGrounded)
{
velocity = 0;
}
else
{
velocity -= Gravity * Time.deltaTime;
characterController.Move(new Vector3(0, velocity, 0));
}
}
}
First, get a reference to the main cmaera and cache it, because you're going to be referencing it frequently, and simply using Camera.main is a bit expensive:
private Camera mainCam;
...
private void Start()
{
characterController = GetComponent<CharacterController>();
mainCam = Camera.main;
}
Then, use mainCam.transform.right and mainCam.transform.forward but with the y set to 0 and normalized instead of Vector3.right and Vector3.forward. This will make the movement be based on the rotation of the camera:
float horizontal = Input.GetAxis("Horizontal") * MovementSpeed;
float vertical = Input.GetAxis("Vertical") * MovementSpeed;
Vector3 camRightFlat = new Vector3(mainCam.transform.right.x, 0f,
mainCam.transform.right.z).normalized;
Vector3 camForwardFlat = new Vector3(mainCam.transform.forward.x, 0f,
mainCam.transform.forward.z).normalized;
characterController.Move(
(camRightFlat * horizontal + camForwardFlat * vertical) * Time.deltaTime);
Altogether:
public class SimpleMovement : MonoBehaviour
{
CharacterController characterController;
public float MovementSpeed = 1;
public float Gravity = 9.8f;
private float velocity = 0;
private Camera mainCam;
private void Start()
{
characterController = GetComponent<CharacterController>();
mainCam = Camera.main;
}
void Update()
{
// player movement - forward, backward, left, right
float horizontal = Input.GetAxis("Horizontal") * MovementSpeed;
float vertical = Input.GetAxis("Vertical") * MovementSpeed;
Vector3 camRightFlat = new Vector3(mainCam.transform.right.x, 0f,
mainCam.transform.right.z).normalized;
Vector3 camForwardFlat = new Vector3(mainCam.transform.forward.x, 0f,
mainCam.transform.forward.z).normalized;
characterController.Move((camRightFlat * horizontal + camForwardFlat * vertical)
* Time.deltaTime);
// Gravity
if (characterController.isGrounded)
{
velocity = 0;
}
else
{
velocity -= Gravity * Time.deltaTime;
characterController.Move(new Vector3(0, velocity, 0));
}
}
}
There is my script Rigidbody controller -
public float Speed = 5f;
public float JumpHeight = 2f;
public float GroundDistance = 0.2f;
public float DashDistance = 5f;
public LayerMask Ground;
private Rigidbody _body;
private Vector3 _inputs = Vector3.zero;
private bool _isGrounded = true;
private Transform _groundChecker;
void Start()
{
_body = GetComponent<Rigidbody>();
_groundChecker = transform.GetChild(0);
}
void Update()
{
_isGrounded = Physics.CheckSphere(_groundChecker.position, GroundDistance, Ground, QueryTriggerInteraction.Ignore);
_inputs = Vector3.zero;
_inputs.x = Input.GetAxis("Horizontal");
_inputs.z = Input.GetAxis("Vertical");
if (_inputs != Vector3.zero)
transform.forward = _inputs;
if (Input.GetButtonDown("Jump") && _isGrounded)
{
_body.AddForce(Vector3.up * Mathf.Sqrt(JumpHeight * -2f * Physics.gravity.y), ForceMode.VelocityChange);
}
if (Input.GetButtonDown("Sprint"))
{
Vector3 dashVelocity = Vector3.Scale(transform.forward, DashDistance * new Vector3((Mathf.Log(1f / (Time.deltaTime * _body.drag + 1)) / -Time.deltaTime), 0, (Mathf.Log(1f / (Time.deltaTime * _body.drag + 1)) / -Time.deltaTime)));
_body.AddForce(dashVelocity, ForceMode.VelocityChange);
}
}
void FixedUpdate()
{
_body.MovePosition(_body.position + _inputs * Speed * Time.fixedDeltaTime);
}
What the best way to make a turn on y in the direction of the camera ? That is,the player turns to the side where the mouse is turned? Is it in fixedUpdate or update?
This is the camera script:
public float Smoothness = 0.3F;
public Vector2 Sensitivity = new Vector2(4, 4);
public Vector2 LimitX = new Vector2(-70, 80);
private Vector2 NewCoord;
public Vector2 CurrentCoord;
private Vector2 vel;
public GameManager GameMangerS;
public Transform Target;
public float TransformSpeed;
public Animator CameraAnimator;
void Update()
{
NewCoord.x = Mathf.Clamp(NewCoord.x, LimitX.x, LimitX.y);
NewCoord.x -= Input.GetAxis("Mouse Y") * Sensitivity.x;
NewCoord.y += Input.GetAxis("Mouse X") * Sensitivity.y;
CurrentCoord.x = Mathf.SmoothDamp(CurrentCoord.x, NewCoord.x, ref vel.x, Smoothness / 2);
CurrentCoord.y = Mathf.SmoothDamp(CurrentCoord.y, NewCoord.y, ref vel.y, Smoothness / 2);
transform.rotation = Quaternion.Euler(CurrentCoord.x, CurrentCoord.y, 0);
}
And added this line to the controller script -
void FixedUpdate()
{
_body.MovePosition(_body.position + _inputs * Speed * Time.fixedDeltaTime);
transform.rotation = Quaternion.Euler(0, MainCamera.CurrentCoord.y, 0);
}
When I'm standing the player normally rotates, but when I start to move, all rotations are reset and the player is not moving.
Update
Simple Rotation can be achieved using transform.Rotate().
Example:
this.transform.Rotate(Vector3.up, 30);
This example is gonna rotate the transform by 30° around the Vector that points upwards.
LookAtMouse:
To make your object turn towards the mouse, you need the ScreenToWorldSpace() method from your camera. In order to convert the ScreenCoordinates into your WorldCoordinates.
Example:
Please note:
You have to set the camera instance! If you don't add that, you'll get a NullReferenceException.
This Snippets shall only show the steps needed to achieve the behavior you wish.
You will have to find out yourself how to integrate that lines of code into your code to make it work. Consider what Programmer told you in the comment when integrating that.
Vector3 mousePosition = Input.mousePosition; //get the screenSpaceMousePosition
Vector3 worldPosition = this.camera.ScreenToWorldPoint(mousePosition); //convert it into worldSpacePosition
Vector3 calculatedDirection = worldPosition - transform.position; //calucate the looking direction
calculatedDirection.y = 0;
Quaternion rotation = Quaternion.LookRotation(calculatedDirection);
transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime);