public GameObject player;
public Rigidbody rb;
private Vector3 offset;
public Vector3 minCamAngle;
public Vector3 maxCamAngle;
void Start()
{
rb = player.GetComponent<Rigidbody>();
offset = transform.position - player.transform.position;
}
// Update is called once per frame
void LateUpdate()
{
Quaternion desiredRotation = Quaternion.LookRotation(new Vector3(Mathf.Clamp(rb.velocity.x, minCamAngle.x, maxCamAngle.x), Mathf.Clamp(rb.velocity.y, minCamAngle.y, maxCamAngle.y), Mathf.Clamp(rb.velocity.z, minCamAngle.z, maxCamAngle.z)));
transform.rotation = Quaternion.Slerp(transform.rotation, desiredRotation, Time.deltaTime);
transform.position = player.transform.position + offset;
}
This is the code i'm using to rotate the camera based on the players velocity except when i set the minimum and maximum x rotation angle to 34 the camera always sets its rotation to an X rotation of -65.61 at the start of the game. I'm not sure what is happening and some help would be appreciated, Thanks.
Related
I have a problem with rotation of enemies in Unity. I used this script:
Transform target;
NavMeshAgent agent;
// Start is called before the first frame update
void Start()
{
target = PlayerManager.instance.player.transform;
agent = GetComponent<NavMeshAgent>();
FaceTarget();
}
// Update is called once per frame
void Update()
{
float distance = Vector3.Distance(target.position, transform.position);
agent.SetDestination(target.position);
FaceTarget();
}
void FaceTarget()
{
Vector3 direction = (target.position - transform.position).normalized;
Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x, 0, direction.z));
transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * 10f);
}
But if I put an enemy on scene and started game they were rotated by 90 degrees. Its my first game and I dont know ho to fix it. Is it a script fault? Thanks in advance.
So I have script which I got from Blackthornprods ranged combat youtube video since im a beginner. Im trying to get my weapon to rotate around my sphere gameobject but for some reason it doesnt rotate to where the mouse position is, but when I jump it rotates around weirdly not really to the mouse but randomly (im assuming randomly). My game is 3D and his tutorial was for 2d. I would really appreciate any attempt for a solution. Here is my code:
void Update()
{
Vector3 difference = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
float rotZ = Mathf.Atan2(difference.y, difference.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0f, 0f, rotZ + offset);
}
The weapon is still to rotate around the Z axis.
First, Camera.main calls FindGameObjectsWithTag, which is an expensive operation, so (as the documentation says), you should call it as few times as possible and cache the result:
Camera mainCam;
void Awake()
{
mainCam = Camera.main;
}
Second, you're using ScreenToWorldPoint incorrectly. If this is really a 3d game as the question describes, you should provide a depth from the camera as the z component of the argument. You can use vector math to do this, and the result is a world position you can tread the cursor as being at.:
Camera mainCam;
void Awake()
{
mainCam = Camera.main;
}
void Update()
{
float objectDepthFromCamera = Vector3.Dot(
transform.position - mainCam.transform.position,
mainCam.transform.forward);
Vector3 cursorWorldPosition = mainCam.ScreenToWorldPoint(Input.mousePosition
+ Vector3.forward * objectDepthFromCamera);
Then assuming the "front" of the object points out of the local up direction, you can use the optional second parameter of Quaternion.SetRotation to set the rotation so that is pointing toward the cursor:
Camera mainCam;
void Awake()
{
mainCam = Camera.main;
}
void Update()
{
float objectDepthFromCamera = Vector3.Dot(
transform.position - mainCam.transform.position,
mainCam.transform.forward);
Vector3 cursorWorldPosition = mainCam.ScreenToWorldPoint(Input.mousePosition
+ Vector3.forward * objectDepthFromCamera);
transform.rotation = Quaternion.LookRotation(Vector3.forward,
cursorWorldPosition - transform.position);
}
If the front of the object points out the local right direction, you can use Vector3.Cross to determine what direction the local up should be pointing:
Camera mainCam;
void Awake()
{
mainCam = Camera.main;
}
void Update()
{
float objectDepthFromCamera = Vector3.Dot(
transform.position - mainCam.transform.position,
mainCam.transform.forward);
Vector3 cursorWorldPosition = mainCam.ScreenToWorldPoint(Input.mousePosition
+ Vector3.forward * objectDepthFromCamera);
Vector3 localUpNeeded = Vector3.Cross(Vector3.forward,
cursorWorldPosition - transform.position);
transform.rotation = Quaternion.LookRotation(Vector3.forward, localUpNeeded);
}
When player shoot, the bullet fly to the center of the screen. But if player stay too close to some object, then bullet hits it not in the center, because it flies from the gun on the right side of the screen. How can I fix this?
public Rigidbody projectile;
public int speed = 50;
public Transform startBulletPosition;
void Update()
{
if (Input.GetButtonDown("Fire1"))
{
Rigidbody clone;
clone = Instantiate(projectile, startBulletPosition.position, transform.rotation) as Rigidbody;
var centre = new Vector3(0.5f, 0.5f, 0f);
var ray = Camera.main.ViewportPointToRay(centre);
clone.velocity = ray.direction * speed;
}
}
public Rigidbody projectile;
public Transform startBulletPosition;
public float speed;
public float rotationSpeed;
public Camera camera;
Vector3 startingDirection;
void Start() {
startingDirection = startBulletPosition.transform.forward;
}
void Update() {
if (Input.GetButtonDown("Fire1")) {
RaycastHit hit;
Vector3 targetDirection;
if (Physics.Raycast(Camera.main.transform.position, camera.transform.forward, out hit)){
targetDirection = hit.transform.position - startBulletPosition.position;
} else {
targetDirection = startingDirection;
}
Vector3 newDirection = Vector3.RotateTowards( startBulletPosition.transform.forward, targetDirection, rotationSpeed * Time.deltaTime, 0.0f);
startBulletPosition.transform.forward = newDirection;
Rigidbody clone;
clone = Instantiate(projectile, startBulletPosition.position, startBulletPosition.rotation) as Rigidbody;
clone.velocity = targetDirection * speed;
}
}
I would do a Raycast from the Camera Position to see what you can hit and then rotate the weapon to that direction. As in my Example Code. The weapon will point to exactly Center View on what your camera Raycast hits.
Also you can control the max turnspeed by that public float. This will make for a nice weapon movement and not just instantaneous jumps.
Here are the docu links of what I used in this snippet:
https://docs.unity3d.com/ScriptReference/RaycastHit.html
https://docs.unity3d.com/ScriptReference/Vector3.RotateTowards.html
If the raycast misses, the stored original direction of the weapon will be used. (Assuming startBulletPosition is the transform of the weapon...)
If you want, you can add the maxDistance Parameter to the Physics.Raycast call to limit the distance on which this behaviour is active.
I have been writing a script for enemy movement in my game, but when the target(Player) jumps, the enemy begins to gradually float up to the same y position the target was in. I would like it if the enemy stayed at the same position as the ground, but I have not found out how I would be able to do that. I am new to Unity, so the only thing I could think of was adding a rigidbody to the enemy but that did not seem to work. Would anyone have any Idea on how to do this? Here is my script:
public class EnemyMovement : MonoBehaviour {
//target
public Transform Player;
//the distace the enemy will begin walking towards the player
public float walkingDistance = 10.0f;
//the speed it will take the enemy to move
public float speed = 10.0f;
private Vector3 Velocity = Vector3.zero;
void Start(){
}
void Update(){
transform.LookAt (Player);
//finding the distance between the enemy and the player
float distance = Vector3.Distance(transform.position, Player.position);
if(distance < walkingDistance){
//moving the enemy towards the player
transform.position = Vector3.SmoothDamp(transform.position,
Player.position, ref Velocity, speed);
}
}
Just set the y value before doing the movement
public class EnemyMovement : MonoBehaviour {
//target
public Transform Player;
//the distace the enemy will begin walking towards the player
public float walkingDistance = 10.0f;
//the speed it will take the enemy to move
public float speed = 10.0f;
private Vector3 Velocity = Vector3.zero;
void Start(){
}
void Update(){
transform.LookAt (Player);
Vector3 target = Player.position;
target.y = transform.position.y;
//finding the distance between the enemy and the player
float distance = Vector3.Distance(transform.position, target);
if(distance < walkingDistance){
//moving the enemy towards the player
transform.position = Vector3.SmoothDamp(transform.position,
target, ref Velocity, speed);
}
}
My Camera Follow script is not very smooth. How can I smoothen the movement of the camera?
Here it is:
using UnityEngine;
using System.Collections;
public class FollowCamera : MonoBehaviour {
public float interpVelocity;
public float minDistance;
public float followDistance;
public GameObject target;
public Vector3 offset;
Vector3 targetPos;
void Start () {
targetPos = transform.position;
}
void FixedUpdate () {
if (target)
{
Vector3 posNoZ = transform.position;
posNoZ.z = target.transform.position.z;
Vector3 targetDirection = (target.transform.position - posNoZ);
interpVelocity = targetDirection.magnitude * 5f;
targetPos = transform.position + (targetDirection.normalized * interpVelocity * Time.deltaTime);
transform.position = Vector3.Lerp( transform.position, targetPos + offset, 0.25f);
}
}
}
The script makes the camera follow a rotating target.
You are updatng camera position on FixedUpdate. Change it to LateUpdate. FixedUpdate is designed for other purposes and is called less often usually then every frame. LateUpdate is called every frame and after Update so if your target is updated on Update camera will update its position later, what is desired.