How can I fix the arm movement with the camera.

Trying to make a third person shooter and the goal right now is to get the arm (which a cylinder) to aim up and down. Right now, when the game starts, the cylinder position resets vertically but does aim with the camera but it offset really weird. Can someone please help me fix this? Im new to unity and am doing my best to learn

//Code for the arm

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

public class Arm : MonoBehaviour
{
public float mouseSensitivity = 100f;

public Transform arm;

float xRotation = 0f;

// Start is called before the first frame update
void Start()
{
    //Cursor.lockState = CursorLockMode.Locked;
    arm.transform.eulerAngles = new Vector3(arm.transform.eulerAngles.x, arm.transform.eulerAngles.y, arm.transform.eulerAngles.z);
}

// Update is called once per frame
void Update()
{
    float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
    float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;

    xRotation -= mouseY;
    xRotation = Mathf.Clamp(xRotation, -90f, 90f);

    transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
    arm.Rotate(Vector3.up * mouseX);
}

}

//Code for the Camera

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

public class MouseLook : MonoBehaviour
{

public float mouseSensitivity = 100f;

public Transform playerBody;

float xRotation = 0f;

// Start is called before the first frame update
void Start()
{
    Cursor.lockState = CursorLockMode.Locked;
}

// Update is called once per frame
void Update()
{
    float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
    float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;

    xRotation -= mouseY;
    xRotation = Mathf.Clamp(xRotation, -90f, 90f);

    transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
    playerBody.Rotate(Vector3.up * mouseX);
}

}

// Code for the player movement

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

public class PlayerMovement : MonoBehaviour
{

CharacterController characterController;

public float speed = 3.0f;
public float jumpSpeed = 8.0f;
public float gravity = 20.0f;

public float shootSpeed = 20;

private Vector3 moveDirection = Vector3.zero;

public GameObject laserPrefab;
public GameObject firePoint;

// Start is called before the first frame update
void Start()
{
    transform.position = new Vector3(-5, 1, -10);
    characterController = GetComponent<CharacterController>();
}

// Update is called once per frame
void Update()
{

    if (characterController.isGrounded)
    {
        // We are grounded, so recalculate
        // move direction directly from axes

        moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0.0f, Input.GetAxis("Vertical"));
        moveDirection *= speed;

        if (Input.GetButton("Jump"))
        {
            moveDirection.y = jumpSpeed;
        }
    }

    if (Input.GetMouseButtonDown(0))
    {
        Shoot();
    }

        // Player moves forward in direction of camera
        Vector3 move = transform.right * moveDirection.x + transform.forward * moveDirection.z;
    characterController.Move(move * speed * Time.deltaTime);

    // Apply gravity. Gravity is multiplied by deltaTime twice (once here, and once below
    // when the moveDirection is multiplied by deltaTime). This is because gravity should be applied
    // as an acceleration (ms^-2)
    moveDirection.y -= gravity * Time.deltaTime;

    // Move the controller
    characterController.Move(moveDirection * Time.deltaTime);
}

// Action to shoot
void Shoot()
{
    GameObject laser = Instantiate(laserPrefab, firePoint.transform.position, firePoint.transform.rotation);
    Rigidbody rb = laser.GetComponent<Rigidbody>();
    rb.AddForce(transform.forward * shootSpeed, ForceMode.Impulse);
}

}

Hi @TimidestShadow

First off your code in Start() is redundant:

arm.transform.eulerAngles = new Vector3(arm.transform.eulerAngles.x, arm.transform.eulerAngles.y, arm.transform.eulerAngles.z);

So I skimmed through your post and what I think is causing your offset is the fact that you’re using Transform.localRotation

If your cylinder has a parent (probably the character object/model) then localRotation will rotate it in local space relative to the parent. Instead of world space.


Give it a shot with Transform.rotation instead, and you shouldn’t have any offset then.

void Update()
 {
     float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
     float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;
     xRotation -= mouseY;
     xRotation = Mathf.Clamp(xRotation, -90f, 90f);
     transform.rotation = Quaternion.Euler(xRotation, 0f, 0f);
     arm.Rotate(Vector3.up * mouseX);
 
}

If this doesn’t fix your issue try taking a screenshot of the offset if you can, that’d help single it out.

Gluck!