Rotate the turret and muzzle of the tank - c#

It is necessary to rotate the turret and muzzle so that the sight is always directed to the center of the screen. I have a camera that can be rotated separately, and the turret and muzzle should follow it slowly, like in the world of tanks.
I have this code. The tower does not keep up with the camera and stops where I took the camera.
public class Tower : MonoBehaviour
{
public Transform Towr;
public Transform Cannon;
public float TowerSpeed;
public float CannonSpeed;
float TowerAngle;
float CannonAngle;
private void Update()
{
RotateTower();
RotateCannon();
}
void RotateTower()
{
TowerAngle += Input.GetAxis("Mouse X") * TowerSpeed * Time.deltaTime;
TowerAngle = Mathf.Clamp(TowerAngle, -90, 90);
Towr.localRotation = Quaternion.AngleAxis(TowerAngle, Vector3.up);
}
void RotateCannon()
{
CannonAngle += Input.GetAxis("Mouse Y") * CannonSpeed * -Time.deltaTime;
CannonAngle = Mathf.Clamp(CannonAngle, -2, 2);
Cannon.localRotation = Quaternion.AngleAxis(CannonAngle, Vector3.right);
}
}

I already found a solution how to rotate the tower behind the camera along the "Y" axis
public Transform cam;
public float speed = 50f;
private void FixedUpdate()
{
transform.localRotation = Quaternion.RotateTowards(transform.localRotation, Quaternion.Euler(0, cam.eulerAngles.y , 0), speed * Time.deltaTime);
}

Related

how do i Rotate and move 3rd person character at Unity

I want to rotate my player for where my mouse is pointing and move the player with "WASD" keys.
I'm actually succesfully rotating my player and moving it, but it doesn't move right depending where my mouse is pointing.. the player just move everytime to the same position.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public int playerSpeed = 5;
public float sensitivity = 5.0f;
public bool blockMouse = true;
private float mouseX;
void Start(){
BlockMouse();
}
void Update() {
Move();
Rotate();
}
void Move()
{
Vector3 movement = new Vector3 (Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
transform.position += movement * playerSpeed * Time.deltaTime;
if(Input.GetKeyDown(KeyCode.LeftShift)) {
playerSpeed=10;
} else if(Input.GetKeyUp(KeyCode.LeftShift)) {
playerSpeed=5;
}
}
void Rotate() {
mouseX += Input.GetAxis("Mouse X") * sensitivity;
transform.eulerAngles = new Vector3(0, mouseX, 0);
}
void BlockMouse() {
if (!blockMouse) {
return;
}
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
}
}
``
Assuming the rotation is working as you said
transform.position += movement * playerSpeed * Time.deltaTime;
by doing this you change the objects world space absolute position, not taking any rotation into account.
Now there are probably a lot of ways how do rather do this
You could simply take the rotation into account
transform.position += transform.rotation * movement * playerSpeed * Time.deltaTime;
This simply stays in world space but rotates your world space vector accordingly
You could rather use Translate
transform.Translate(movement * playerSpeed * Time.deltaTime);
which basically does the same, takes orientation into account but is not affected by scaling

How to make the player walk in the direction it is pointing?

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;

Unity: How to move object in direction camera is facing

I'm using Unity and trying to move my player object in a direction relative to where the camera is facing. The camera is currently able to rotate/orbit around the player object by using the mouse, however, it only moves in directions relative to the world, not the camera. In essence, I'm trying to replicate what the game Absolver does. There's a good clip in this youtube video at around 4:30 showing the camera/player movement: https://www.youtube.com/watch?v=_lBqCTeJwYw&t=1199s.
I've looked at youtube videos, unity answers and scripting manuals dealing with joysticks, quaternions, and Euler values, but I just can't seem to find a solution that fits my particular problem. Any help would be absolutely great. Thanks in advance!
Camera Rotation Code:
using UnityEngine;
public class FollowPlayer : MonoBehaviour
{
private const float Y_ANGLE_MIN = 0f;
private const float Y_ANGLE_MAX = 85f;
public Transform lookAt;
public Transform camTransform;
private Camera cam;
private float distance = 10f;
private float currentX = 0f;
private float currentY = 0f;
private float sensitivityX = 5f;
private float sensitivityY = 5f;
private void Start()
{
camTransform = transform;
cam = Camera.main;
}
private void Update()
{
currentX += Input.GetAxis("Mouse X") * sensitivityX;
currentY -= Input.GetAxis("Mouse Y") * sensitivityY;
currentY = Mathf.Clamp(currentY, Y_ANGLE_MIN, Y_ANGLE_MAX);
}
private void LateUpdate()
{
Vector3 dir = new Vector3(0, 0, -distance);
Quaternion rotation = Quaternion.Euler(currentY, currentX, 0);
camTransform.position = lookAt.position + rotation * dir;
camTransform.LookAt(lookAt.position);
}
}
Player Movement Code:
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public Rigidbody rb;
public Camera cam;
public float movementForce = 500f;
// Update is called once per frame
void FixedUpdate()
{
if (Input.GetKey("w"))
{
rb.AddForce(0, 0, movementForce * Time.deltaTime, ForceMode.VelocityChange);
}
if (Input.GetKey("a"))
{
rb.AddForce(-movementForce * Time.deltaTime, 0, 0, ForceMode.VelocityChange);
}
if (Input.GetKey("s"))
{
rb.AddForce(0, 0, -movementForce * Time.deltaTime, ForceMode.VelocityChange);
}
if (Input.GetKey("d"))
{
rb.AddForce(movementForce * Time.deltaTime, 0, 0, ForceMode.VelocityChange);
}
if (rb.position.y < -1f)
{
FindObjectOfType<GameManager>().EndGame();
}
}
}
You want to use the transform.forward property of your camera.
Something like this:
rb.AddForce(cam.transform.forward * movementForce * Time.deltaTime, ForceMode.VelocityChange);
You also have at your disposal:
transform.left
transform.right
There is an example of exactly this on the AddForce docs.

First Person Controller camera rotation doesn't work

I'm looking for some c# script on unity to update first person controller
camera rotation transform. More specificly, I'm running an animation, and by the end of animation, I set "movie camera transform" on fps camera transform, how to show the code. For position variable, everything is ok. However, rotation variable doesn't work well.
The variable get the transform rotation right (the same movie camera transform), but I can't see the change on scene. The "first person controller rotation transform"
always get the last rotation coordinate that happened.
I already tested many rotation functions, like Rotate(Vector3), rotation, localRotation, eulerAngles, localEulerAngles....
Vector3 pos, roteuler;
public Camera fpscam, movie;
void getPosRot(){
roteuler = movie.transform.eulerAngles;
pos = movie.transform.position;
}
void Update(){
fps.transform.position = pos;
fps.transform.eulerAngles = roteuler;
}
Here is the camera part of my FPS script:
public class PlayerController : MonoBehaviour
{
float RotateX;
float RotateY;
public GameObject Camera;
public float RotationSpeed = 3.0f;
public float MaxYAxis = 60.0f;
public float MinYAxis = -48.0f;
private void Start()
{
}
void Update()
{
Rotation();
}
void Rotation()
{
RotateX += Input.GetAxis("Mouse X") * RotationSpeed;
RotateY += Input.GetAxis("Mouse Y") * RotationSpeed;
RotateY = Mathf.Clamp(RotateY, MinYAxis, MaxYAxis);
Camera.transform.localRotation = Quaternion.Euler(-RotateY, 0f, 0f);
transform.rotation = Quaternion.Euler(0f, RotateX, 0f);
}
}

3d mouse aim camera 3rd person vertical C#

I'm trying to make mouse aim camera that rotate my Player horizontally and vertically, look at Player and keep constant distance.
In that version it works fine but I can't make it horizontal also.
Each version camera freezes and I rotate my player itself or so.
I'm new to programming so I it's propably easy task with proper target.transform.eulerAngles.y assigning also to vertical but I cannot do it.
public class MouseAimCamera : MonoBehaviour {
public GameObject target;
public float rotateSpeed = 5;
Vector3 offset;
void Start() {
offset = target.transform.position - transform.position;
}
void LateUpdate() {
float horizontal = Input.GetAxis("Mouse X") * rotateSpeed;
target.transform.Rotate(0, horizontal, 0);
float desiredAngle = target.transform.eulerAngles.y;
Quaternion rotation = Quaternion.Euler(0, desiredAngle, 0);
transform.position = target.transform.position - (rotation * offset);
transform.LookAt(target.transform);
}
}
I'd be glad if any of you can help me.
This will rotate in world space, which will probably feel wrong at some angles since the camera is not always oriented straight up.
public class MouseAimCamera : MonoBehaviour {
public GameObject target;
public float rotateSpeed = 5;
void Start() {
transform.parent = target.transform;
transform.LookAt(target.transform);
}
void LateUpdate() {
float horizontal = Input.GetAxis("Mouse X") * rotateSpeed;
float vertical = Input.GetAxis("Mouse Y") * rotateSpeed;
target.transform.RotateAround(target.transform.position, Vector3.up, horizontal);
target.transform.RotateAround(target.transform.position, Vector3.left, vertical);
}
}
This will rotate in local space, and might feel more natural depending on what you're trying to build. This is close to your original solution, so i'm guessing it's not what you want.
public class MouseAimCamera : MonoBehaviour {
public GameObject target;
public float rotateSpeed = 5;
void Start() {
transform.parent = target.transform;
transform.LookAt(target.transform);
}
void LateUpdate() {
float horizontal = Input.GetAxis("Mouse X") * rotateSpeed;
float vertical = Input.GetAxis("Mouse Y") * rotateSpeed;
target.transform.Rotate(vertical, horizontal, 0);
}
}

Categories