Aim Assist in Unity? - c#

Well, I'm working on something, but I'm stuck right now. as Title says it's about an "aim assist" for a shooting game. I move my camera using pitch-yaw updated every frame. like this:
void Update()
{
float pitch -= Input.GetAxis("Mouse Y") * sensivity;
float yaw += Input.GetAxis("Mouse X") * sensivity;
Vector2 rot = new Vector2(pitch, yaw);
cam.tranform.eulerAngles = rot;
}
And my AimAssit() method look like this:
void AimAssist(float weaponRange)
{
RaycastHit hit;
if (Physics.SphereCast(cam.transform.position, radiusDetection, cam.transform.forward, out hit, weaponRange, 1 << LayerMask.NameToLayer("Shootable"))
{
GameObject aimTo = hit.transform.gameObject;
Vector3 direction = aimTo.transform.position - cam.transform.position;
cam.transform.rotation = Quaternion.Slerp(cam.transform.rotation, Quaternion.LookRotation(direction), .1f);
}
}
So, The problem is they don't work together, it's a mess. I know one of these work with degrees and the other one use angles, it's confusing. In other words, what I need is snap the crosshair in the head and still move fine with mouse. Thanks in advance.
BTW, I made this, but it was useless:
Vector2 aim = new Vector2(Quaternion.LookRotation(direction).eulerAngles.x, Quaternion.LookRotation(direction).eulerAngles.y);
CamTransform().eulerAngles = currentRotation + (Vector2)aim;
To be clear "direction" is the same from AimAssist().

Related

Character randomly rotating on the X and Z axes even thought Rigidbody constraints are enabled

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
class FirstPersonCamera : MonoBehaviour
{
public float mouseSensitivity = 100f;
public Transform playerTransform;
public Transform weaponTransform;
private float xRotation = 0;
void Start()
{
UnityEngine.Cursor.lockState = CursorLockMode.Locked; //Hides the cursor and locks it to the center
}
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, -90, 90);
transform.localRotation = Quaternion.Euler(xRotation, 0, 0);
weaponTransform.localRotation = Quaternion.Euler(xRotation, 0, 0);
playerTransform.Rotate(new Vector3(0.0f, mouseX, 0.0f));
//playerTransform.gameObject.GetComponent<Rigidbody>().MoveRotation(Quaternion.Euler(0.0f,mouseX,0.0f));
if (Input.GetKeyDown(KeyCode.Escape))
{
UnityEngine.Cursor.lockState = CursorLockMode.None;
}
}
}
This is what I'm using for player looking (mouse controls) and this keeps happening:
even though I have rigidbody X and Z rotations locked. The issue mainly seems to arise when using keyboard controls and mouse together. Here is the playerMove code as well: https://codeshare.io/wnzrYj . It shouldn't be doing anything with rotation.
I've tried removing the playerTransform.Rotate and the issue seems to disappear. I've also tried rotating the gameObject via the rigidbody but that doesn't seem to rotate the body at all.
You're causing the rotations yourself. You've added the xRotation, which will affect the pitch, but then you use Transform.Rotate, which works locally. That means that when pitched, your Rotate is no longer around the world's Y axis, but rather around the object's pitched Y-axis, adding rotation to axes you don't want.
The easiest way to solve this is to build your hierarchy properly to make sure that the rotations are applied in the order you want. I usually go with something like:
Root -> YawPivot -> Body -> PitchPivot -> Head/Camera
The Root object would have the translations (offsets/movement) applied to it. The YawPivot is only rotated around the Y axis. And the PitchPivot is only rotated around the X axis (and is usually located around the neck or head area).

Smoothing player movement and speed

I know this question is already asked a few times, but didn't find it in the way of my code.
In the movement of my playerObject I consider the direction the Camera is looking to atm.
What I want to do is to slow down the speed of the movement, but it doesn't work with the walkSpeed I use.
I also want to smooth the movement (start and end).
public void UpdateMovement()
{
Vector2 targetDir = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical")); //In targetDir the direction the Player wants to move to is saved -> player presses W means forward
// targetDir = Vector2.ClampMagnitude(targetDir, 1);
Vector3 camForward = cam.forward; //camForward saves the direction, the cam is looking actually
Vector3 camRight = cam.right; //camRight saves the actual right side of the cam
camForward.y = 0.0f; //y=0 because we don't want to fly or go into the ground
camRight.y = 0.0f;
camForward = camForward.normalized;
camRight = camRight.normalized;
transform.position += (camForward * targetDir.y + camRight * targetDir.x) * walkSpeed * Time.deltaTime;
I'm not sure exactly about what the context of what you're trying to do here is, but I think you're looking for Vector2.Lerp().
The way you use it is to first calculate a target position as a Vector. So,
Vector2 target = new Vector2(targetX, targetY)
I'll let you figure out what targetX and targetY are, based on wherever you're trying to move the thing you're moving.
Then you would come up with the speed, which is what you're pretty much already doing. Like so:
float speed = walkSpeed * Time.deltatime;
Finally, instead of setting the position directly, you use the Lerp function instead.
transform.position = Vector2.Lerp(transform.position, target, speed);
I didn't test any of this, and just wrote it on the fly, but I'm pretty sure this is what you're looking for.
I wrote a script you can try to create a cube, I'm sorry because I'm also a unity3d newbie, but I hope it helps you
private Transform player;
Vector3 toposition;//interpolation
void Start(){
player = this.transform;
toposition = new Vector3(0,5,0);
}
// Start is called before the first frame update
void Update(){
if(Input.GetKey(KeyCode.W)){
UpdateMovement();
}
}
public void UpdateMovement(){
player.transform.position = Vector3.Lerp(transform.position, toposition, Time.deltaTime * 5f);
}

How to rotate an object along all 3 axes with finger swipe?

I'm working on a simple AR Vuforia application. How can I implement the rotation of an object along all three axes with one finger swipe?
The code I'm currently using has one bug: the rotation of the object depends on its local axes. For example, if I look at the object from the front, everything works as it should, but if I look at the object from the back side, the finger swipe upwards makes it rotate downwards and vice versa.
Here is this script:
public float rotSpeed = 30f;
void OnMouseDrag()
{
float rotX = Input.GetAxis("Mouse X")*rotSpeed*Mathf.Deg2Rad;
float rotY = Input.GetAxis("Mouse Y")*rotSpeed*Mathf.Deg2Rad;
transform.Rotate(Vector3.up, -rotX);
transform.Rotate(Vector3.right, -rotY);
}
This is not what I need, how can I rotate the object according to the finger swipe direction regardless of the angle from which I look at it?
Update
A simple non-AR example, which may help you understand what I need is an iOS game "Space Frontier 2". After a successful launch of the rocket, it lands on the planet and you can rotate the planet with your finger swipe.
Here is the video demo: https://youtu.be/OiNPP1WNIAI
This works nice regardless of your object's rotation, and regardless of your camera position relative to the object:
public float rotSpeed = 30f;
void OnMouseDrag()
{
float rotX = Input.GetAxis("Mouse X") * rotSpeed;
float rotY = Input.GetAxis("Mouse Y") * rotSpeed;
Camera camera = Camera.main;
Vector3 right = Vector3.Cross(camera.transform.up, transform.position - camera.transform.position);
Vector3 up = Vector3.Cross(transform.position - camera.transform.position, right);
transform.rotation = Quaternion.AngleAxis(-rotX, up) * transform.rotation;
transform.rotation = Quaternion.AngleAxis(rotY, right) * transform.rotation;
}
Make sure your camera has the "MainCamera" tag, or assign the camera externally if necessary.
I do not have the exact code with me right now.
But if you did not update your point of view coordinates, this should be the expected result.
Consider a real ball with 2 colors, blue and red, separated vertically.
When you are in front of it, seeing only the blue side, stroking it up will make the blue side go up and the red side appear from the bottom.
Now move behind it, seeing only the red side, and stroke it up again.
The blue face will go down and appear from the bottom.
Unity applies physics to virtual objects the same way we interact with real objects.
So you need to consider your camera position with the object orientation when you apply movements to it.
You need to apply a transformation matrix to your movement based on your camera location related to the object origin orientation.
I hope this is clear enough to put you on tracks to fix it.
I think you have to somehow clamp the rotation to have the desired behaviour. I wrote a script recently to do just that. I did a little modification though.
public float rotSpeed = 30f;
float ClampAngle(float _angle, float _min, float _max)
{
if (_angle < 0f) _angle = 360 + _angle;
if (_angle > 180f) Mathf.Max(_angle, 360 + _min);
return Mathf.Min(_angle, _max);
}
USAGE:
void RotateGameObject()
{
float h = Input.GetTouch(0).deltaPosition.x * Time.deltaTime * rotSpeed*Mathf.Deg2Rad;
float v = Input.GetTouch(0).deltaPosition.y * Time.deltaTime * rotSpeed*Mathf.Deg2Rad;
Vector3 rot = transform.rotation.eulerAngles + new Vector3(-v, h, 0f);
//Change the y & z values to match your expected behaviour.
rot.x = ClampAngle(rot.x, -5f, 20f);
//Clamp rotation on the y-axis
rot.y = ClampAngle(rot.y, -20f, 20f);
transform.eulerAngles = rot;
}
See if that works and of course, try to play with the values.

Unity 5 Head rotation in c#

i am trying to make a realistic player controller in my game. the camera is not actually being moved. its parented to the rigged head. i want to move the rigged head so the camera moves with it. i am having trouble. i have tried many different things. they all come out weird. what i mean by that is it like curves to look down and its controls are flipped i have tried this code:
public float horizontalSpeed = 2.0F;
public float verticalSpeed = 2.0F;
void Update()
{
float h = horizontalSpeed * Input.GetAxis("Mouse X");
float v = verticalSpeed * Input.GetAxis("Mouse Y");
transform.Rotate(h, v, 0);
}
thanks for your help!

Camera shaking on rotating player while crouching in unity

I am having a problem with the camera following the player. When the player moves, the camera shakes and this effect is more noticeable when the player is in the crouched position. I am using root motion for the player with animations by mixamo.
Player Script:
Transform cameraT;
void Start () {
cameraT = Camera.main.transform;
}
void FixedUpdate ()
{
float sideMotion = Input.GetAxis("SideMotion");
float straightMotion= Input.GetAxis("StraightMotion");
if (Mathf.Abs(sideMotion) > 0 || Mathf.Abs(straightMotion) > 0)
{
transform.eulerAngles = new Vector3(transform.eulerAngles.x,
cameraT.eulerAngles.y);
}
}
Camera Script:
public float distanceFromPlayer=2f;
public float mouseSensitivity=6;
public Transform player;
public Vector2 pitchConstraint= new Vector2(-30,80);
Vector3 rotationSmoothVelocity;
Vector3 currentRotation;
public float rotationSmoothTime = 0.2f;
float yaw; //Rotation around the vertical axis is called yaw
float pitch; //Rotation around the side-to-side axis is called pitch
private void LateUpdate()
{
yaw += Input.GetAxis("Mouse X") * mouseSensitivity;
pitch -= Input.GetAxis("Mouse Y") * mouseSensitivity;
pitch = Mathf.Clamp(pitch, pitchConstraint.x, pitchConstraint.y);
currentRotation = Vector3.SmoothDamp
(currentRotation, new Vector3(pitch, yaw), ref rotationSmoothVelocity, rotationSmoothTime);
transform.eulerAngles = currentRotation;
transform.position = player.position - transform.forward * distanceFromPlayer;
}
For public transform I just added an empty game object to player chest level and parented it to the player. I got the rotating camera smoothly trick from an online tutorial but that exact thing won't work on player rotation though.
A character controller is attached to player without any rigidbody or collider.
You are going to want to use Lerp on the camera in order to smooth its motion from one position to another. The Scripting API has a good example of Vector3.Lerp.
So in your case, you could add a public variable for smoothing position as well. Something like positionSmoothTime. Then make a "Desired Position" variable, we'll call it destPosition.
Vector3 destPosition = player.position - transform.forward * distanceFromPlayer;
transform.position = Vector3.Lerp(transform.position, destPosition, positionSmoothTime);
This should effectively smooth it to where the stuttering should go away. Another thing that will help that someone else mentioned is using a part of the body that moves less (Like the head) as the target. This combined with the Lerp function will give you a smooth camera movement.
Another large help would be to move things into the Update() function. The reason being is FixedUpdate() doesn't get called every frame. So you could potentially get stutter as a result. If you move everything into Update() it will update every frame and help smooth things out. If you do this though you will need to multiply all movement by Time.deltaTime as shown in the example below.
Vector3 destPosition = (player.position - transform.forward * distanceFromPlayer) * Time.deltaTime;
For more examples, check the links to each function to see Unity's documentation on it. It has examples of everything I've shown here.

Categories

Resources