Unity Make Hands Move with weapon - c#

I have a unity scene with a character holding a weapon. The weapon is a child of the camera and so moves with the camera allowing the player to aim the weapon. My issue is that the 3d model of the character has hands which i wish to be holding on to the weapon. Initially, to get past this issue, I used IK's to place the hands on the gun, this worked but didn't allow me to aim the gun as it would be fixed to the hands. How would I go about keeping the hands attached to the weapon whilst still being able to aim?
The player look script is attached for refrence:
public float sensitivityX = 5.0f;
public float sensitivityY = 5.0f;
public int Limits = 80;
public Transform playerBody;
float xRotation = 0f;
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
}
void Update()
{
float mouseX = Input.GetAxis("Mouse X") * sensitivityX * Time.deltaTime;
float mouseY = Input.GetAxis("Mouse Y") * sensitivityY * Time.deltaTime;
xRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, (Limits * -1), Limits);
transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
playerBody.Rotate(Vector3.up * mouseX);
}
If anymore information is needed please let me know, thank you.

FIX:
Parent gun to hand, use animation rigging IK's to follow a target (I used multi aim constraints), do this for both the hand and the spine. Set the source object as a sphere, either disable it from being visible in the camera or just make it very small, then make it a child of the camera, place it at X=0, Y=0 and Z=>0.

Related

Why is my character flying off randomly Unity3D?

I'm making a third person game and when I try to makie the character (cube) face the way the players mouse is pointing my character just goes flying off even though I didn't use W, A, S or D?
public class FollowPlayer : MonoBehaviour
{
public Transform player;
public Vector3 CamPosition;
public Transform PlayerBody;
public float MouseSensitivity = 100f;
// 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;
PlayerBody.Rotate(Vector3.up * MouseX);
transform.position = player.position + CamPosition;
}
}
Did you attach it to the player or the cam?
See if you have a rigidbody attached to the player, it may be buggy due to the way they work in relation with transforms.
Try to mark the line that rotates the player. I believe it's somewhere else that causes the problem because there is nothing in there that moves the player.
Reply me if you found anything that affects the movement.

Unity - instantiating an sphere makes camera move abnormally fast in one frame

I was trying to make a test game in 3D Unity. In the game enemy throw rock and you try to escape. But every time it instantiates a sphere while i am moving my camera(it is tps) it suddenly moves like five times faster in one frame. When i am rotating camera from downwards to upwards at normal speed it suddenly start looking to the sky. I dont get it. Here is the instantiate code:
IEnumerator throwRock()
{
if (IsRockThrowable)
{
IsRockThrowable = false;
GameObject rockk = Instantiate(rock, transform.position, transform.rotation) as GameObject;
rockk.GetComponent<Rigidbody>().AddForce(transform.forward * 100, ForceMode.Impulse);
yield return new WaitForSeconds(2.5f);
IsRockThrowable = true;
}
}
And here is the camera movement code:
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);
}
Can you explain why it happens? Thanks for your attention

Rotating towards a final rotation challenge

Consider this working script, that handles a FPS camera movement:
using UnityEngine;
public class CameraHandler : MonoBehaviour {
public Transform target;
float dragSpeed = 10f;
float lookAtSensitivity = 200f;
float xRot;
Transform parentGO;
private void Start() {
parentGO = transform.parent;
}
void goToPivot(Transform pivot) {
parentGO.position = Vector3.Lerp(transform.position, pivot.position, 0.05f);
transform.rotation = Quaternion.Lerp(transform.rotation, pivot.rotation, 0.05f);
}
void resetCamRot() {
xRot = 0;
float yRot = transform.localEulerAngles.y;
parentGO.transform.eulerAngles += new Vector3(0, yRot, 0);
transform.localEulerAngles -= new Vector3(0, yRot, 0);
}
void LateUpdate() {
if (Input.GetKey(KeyCode.Mouse1)) {
float touchX = Input.GetAxis("Mouse X") * lookAtSensitivity * Time.deltaTime;
float touchY = Input.GetAxis("Mouse Y") * lookAtSensitivity * Time.deltaTime;
xRot -= touchY;
xRot = Mathf.Clamp(xRot, -90f, 90f);
transform.localRotation = Quaternion.Euler(xRot, 0f, 0f);
parentGO.transform.Rotate(Vector3.up * touchX);
}
if (Input.GetKey(KeyCode.Space)) {
goToPivot(target);
}
if (Input.GetKeyUp(KeyCode.Space)) {
resetCamRot();
}
}
}
Check how the rotations take place in different gameobjects in their respective axis, so that each of rotations are kept independent and everything works.
transform.localRotation = Quaternion.Euler(xRot, 0f, 0f); //camera GO only rotates in local x
parentGO.transform.Rotate(Vector3.up * touchX); //parent GO only rotates in global y
Problem comes when I need to "force" the camera look a certain direction without the inputs, to the FPS movement rules break, and for example the camera gameobject rotates also in the Y xis. That is why I need to call the resetCamRot() method, and traspass the local rotation from the camera object to the parent so that the situation meets the the FPS movement requirements (no local Y axis rotation).
Without calling the resetCamRot() method, when the FPS movement starts on right mouse button click, the camera abruptly changes to the direction it was facing before "forcing" it with goToPivot that sets the position and the rotation.(Just commentinf the resetCamRot method out)
Although resetCamRot() does the work it feels a bit hacky, so is there another way to set the camera to a forced rotation maintaining the local rotation of the child object (where the camera is) to 0?
I thought of decomposing the next step rotation given by Quaternion.Lerp(transform.rotation, pivot.rotation, 0.05f); in the goToPivot() method in each of their respective axis and gameObjects as its done when the rotation is set from the input, to have a clean local Y rot in he camera gameobject each step. Seems to be the over-complicated thing in this case, but was not able to figure that out.
I you wish to try the script out for the challenge just need to add a parent gameobject to the camera and the attach the target in the editor.
This will make the camera look in the direction, the parent transform look in the direction, only flattened, and finally update the internal state (xRot) in accordance with the difference between the two:
void LookTowards(Vector3 direction) {
Vector3 flattened = direction;
flattened.y = 0f;
parentGo.rotation = Quaternion.LookRotation(flattened);
transform.rotation = Quaternion.LookRotation(direction);
xRot = Vector3.SignedAngle(flattened, direction, parentGo.right);
}

Restrict gameobject inside a radius around my player

I need to restrict my Players hand inside a radius around the character.
The game is 2D and the hand movement is basically exactly the same as: Madness Interactive (https://www.newgrounds.com/portal/view/118826)
[SerializeField] private float speed = 2f;
[SerializeField] private GameObject radiusCenter;
[SerializeField] private float radius = 0.5f;
void Start()
{
Cursor.visible = false;
}
void Update()
{
Vector3 playerPos = radiusCenter.transform.position;
Vector3 playerToHand = this.transform.position - playerPos;
var moveDirection = new Vector3(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"), 0);
float DistanceToRadius = Vector3.Distance(playerPos, playerToHand);
transform.position += moveDirection * speed * Time.deltaTime;
float angle = Mathf.Atan2(playerToHand.y, playerToHand.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
}
I cant figure out the way to keep my players hand inside a set radius around my player, see pictures below for further explanation:
I thought maybe I could get a float value from playerPos and playerToHand and create a IF-statement that restricts the hand from going outside the set radius float, but I didnt get it to work...
EDIT 1: The hand is a child of my player. I use a gameObject in the center of my player as radiusCenter which my hand rotates around.
One very simple way to check if the hand is too far away is to use this line of code:
<movement code here>
if (Vector3.distance(playerPos, transform.position) > radius)
{
transform.localPosition = transform.localPosition.normalized * radius;
{
This will make it so if the hand will be outside the circle after the move, it will just put the hand on the circle.

Unity camera flicks across screen, first person

Hello I am new to UNITY I have written some code for a first person camera however sometimes when I am looking around it will flick what way the camera is facing. This is my code
public float mouseSensitivity = 200f;
public Transform playerBody;
float yRotation = 0f;
// Start is called before the first frame update
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
// 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;
yRotation -= mouseY;
yRotation = Mathf.Clamp(yRotation, -90f, 90f);
transform.localRotation = Quaternion.Euler(yRotation, 0f, 0f);
playerBody.Rotate(Vector3.up * mouseX);
}
I have a video to show my issue as well https://youtu.be/nMopJzNyYr4 for is the question is not clear.
I have a capsule as my parent it is the players actual body and then my camera is a child to the playerBody ( my capsule )
Try it without the deltaTime multiplication. GetAxis on a mouse axis gives you a difference in mouse position, which should not be multiplied by deltaTime or any other time delta unless you are interested in a measurement of Absement which you probably are not!!
You are more interested in a distance measurement, so you can just use
float mouseABC = Input.GetAxis("Mouse ABC") * mouseSensitivity;.
Alternatively, if you were to want the speed of the mouse movement, you would actually rather divide by time.deltaTime such as float mouseHorizontalVelocity = Input.GetAxis("Mouse X") * mouseSensitivity / Time.deltaTime;.

Categories

Resources