I'm working on a downhill racer and I want to have the camera shake to various degrees to convey that the player is getting faster. Right now I have a GameObject called "CameraHolder" which is a parent to the Main Camera.
I have a script attached to the Holder that follows the player, and another script attached to the camera that is meant to shake it within that holder.
CameraHolder Follow Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraFollow : MonoBehaviour
{
public Camera cam;
public Transform player;
public Vector3 offset;
public float speed = 2f;
public Rigidbody rb;
public float startingFieldOfView = 60f;
void FixedUpdate()
{
float interpolation = speed * Time.deltaTime;
Vector3 cameraPosition = new Vector3(Mathf.Lerp(transform.position.x, player.position.x, interpolation), player.position.y + player.localScale.y + offset.y, player.position.z + -player.localScale.z + offset.z);
// Change of camera FOV depending on the speed of the rigidbody
transform.position = cameraPosition;
cam.fieldOfView = Mathf.Lerp(cam.fieldOfView, startingFieldOfView + (rb.velocity.magnitude / 3), .1f);
CameraShake Script attached to child Main Camera
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraShake : MonoBehaviour
{
public Rigidbody player;
public float shakeThreshold;
public float shakeMagnitude;
private void Update()
{
float x = Random.Range(-shakeMagnitude, shakeMagnitude);
float y = Random.Range(-shakeMagnitude, shakeMagnitude);
if (player.velocity.magnitude >= shakeThreshold)
{
transform.localPosition = new Vector3(x, y, transform.position.z);
}
}
}
I think maybe I misunderstand how localPosition works. I thought that it would move the camera the random amount while moving within the holder, but it does nothing. Am I applying this wrong or is the logic off?
I think using cinemachine will really help you.
To remplace your CameraFollow script you can use a virtual camera with the property Follow, for more information you can go there : https://docs.unity3d.com/Packages/com.unity.cinemachine#2.6/manual/CinemachineSetUpVCam.html
To replace your Camera shake you can check the Noise Property there : https://docs.unity3d.com/Packages/com.unity.cinemachine#2.6/manual/CinemachineVirtualCameraNoise.html
For more information on cinemachine go check the doc here : https://docs.unity3d.com/Packages/com.unity.cinemachine#2.6/manual/CinemachineUsing.html
Related
I'm trying to make a simple top-down 2d movement demo as a personal project, and I've run into a very weird roadblock. I was using code from this website to move the sprite, and it worked fine. I then drew in a simple structure using tilemap to test movement and collision of the sprite, but now when I use the arrow keys it moves the structure I painted in with the tilemap in an inverted control scheme (up arrow is down, left arrow is right, etc.). I have the script I wrote for the test sprite attached below. Can anyone help?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class PlayerController : MonoBehaviour
{
Rigidbody2D body;
float horizontal;
float vertical;
Vector2 move;
public float runSpeed = 2.5f;
void Start()
{
body = GetComponent<Rigidbody2D>();
}
void Update ()
{
horizontal = Input.GetAxis("Horizontal");
vertical = Input.GetAxis("Vertical");
//move.x = horizontal;
//move.y = vertical;
}
private void FixedUpdate()
{
body.velocity = new Vector2(horizontal * runSpeed, vertical * runSpeed);
}
}
I know it was much worse but could you try? :)
body.velocity = new Vector2(-horizontal * runSpeed, -vertical * runSpeed);
Video explanation
My cube in Unity is falling down randomly.It is on a cube named "Ground" and it has a movement script attached below. Above is the video showing what happens, and I'll attach an image too. Image
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ThirdPersonMovement : MonoBehaviour
{
public CharacterController controller;
public float speed = 6f;
// Update is called once per frame
void Update()
{
float horizontal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
Vector3 direction = new Vector3(horizontal, 0f, vertical).normalized;
if (direction.magnitude >= 0.1f)
{
controller.Move(direction * speed * Time.deltaTime);
}
}
}
Make sure the colider covers the entire cube, because now it’s only of size 1 on all axis.
The following script is supposed to make the enemy sprite follow the player, but all it does is teleport left and right of the player.
The speed I set is connected to the distance the enemy teleports. If you need anything else besides this script, just tell me I'm quite new to Unity and C#.
The error I'm getting is:
Assertion failed on expression: 'task.rasterData.vertexBuffer == NULL'
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)
And my code is:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyMove : MonoBehaviour
{
public Rigidbody2D target;
public float speed = 10f;
Rigidbody2D rb;
void Start()
{
rb = GetComponent<Rigidbody2D>();
target = GameObject.FindGameObjectWithTag("Player").GetComponent<Rigidbody2D>();
}
void FixedUpdate()
{
Vector2 dir = target.position - rb.position;
rb.MovePosition(dir.normalized * speed);
}
}
As BugFinder says, yo need the transform. Also although you are working in 2d, a transform's position is a vector3. Find some modifications as suggestions for your code.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyMove : MonoBehaviour
{
public Transform target;
public float speed = 10f;
public Transform rb;
void Start()
{
//You can get these programatically or attach them ni the editor. Seems that
//target is the player and the rb is the follower. You can make the variables
//public attach them in the editor so that they can be accessed in the code
// rb = GetComponent<Rigidbody2D>();
// target =
//GameObject.FindGameObjectWithTag("Player").GetComponent<Rigidbody2D>();
}
void Update()
{
Vector3 dir = target.position - rb.position;
rb.position = rb.position + (dir.normalized * speed);
}
}
Hope that helps
I am creating a simple game where you are locked in the center of the screen and must shoot things as they move toward you. The problem I am currently facing is that I can not launch a bullet in the direction of my mouse cursor. Currently, my code looks like this
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour {
PlayerScript playerScript;
public float xVel;
public float yVel;
public float direction;
private void Awake()
{
playerScript = FindObjectOfType<PlayerScript>();
//playerScript.AngleDeg is the direction the player is facing (based on mouse cursor)
transform.rotation = Quaternion.Euler(0, 0, playerScript.AngleDeg);
direction = transform.rotation.z;
//from the unit circle (x = cos(theta), y = sin(theta)
xVel = Mathf.Cos(direction * Mathf.PI);
yVel = Mathf.Sin(direction * Mathf.PI);
}
void Update () {
transform.position += new Vector3(xVel,yVel,0);
}
}
currently, when I run the code, the bullet shoots at an angle which is at the direction that is correct when the player is orientated sideways, but when orientated vertically is a full 45 degrees off.
Attach this as a component to your instantiated bullet object and it should work.
Transform playerTransform;
float bulletSpeed;
Vector3 directionToShoot
void Start()
{
playerTransform = FindObjectOfType<PlayerScript>().gameObject.transform;
bulletSpeed = 3f;
//Direction for shooting
directionToShoot = playerTransform.forward - Camera.main.ScreenToWorldPoint(Input.mousePosition);
}
void Update()
{
//shoot
transform.Translate(directionToShoot * bulletSpeed * Time.deltaTime);
}
I need to rotate the camera around my player gameobject while holding the left mouse button. How would I approach this?
Also, I've read a bit on Vector 3, but I don't have a full understanding of it. Anybody who could explain it would be greatly appreciated.
I've looked at youtube videos and this one is exactly the concept I was looking for. I was just having trouble applying it to my code.
I'm on a bit of a time crunch, exams are nearing and my teacher hasn't explained most things that are explained in the video.
// This is my code inside the camera which follows the ball/player
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ScriptBallCam : MonoBehaviour
{
public GameObject player;
private Vector3 offset;
void Start()
{
offset = transform.position - player.transform.position;
}
void LateUpdate()
{
transform.position = player.transform.position + offset;
}
//End of code inside camera
//Code inside of player/ball
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ScriptBall : MonoBehaviour
{
public float speed;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
rb.AddForce(movement * speed);
}
// end code
Results I'm expecting are exactly shown at 1:22 in
https://www.youtube.com/watch?v=xcn7hz7J7sI
Try this. The script goes on your camera.
Basically this script works by first getting the direction your mouse has moved in. In this case the X axis Mouse X (left/right direction). Then we take our rotation speed turnSpeed, and use it to rotate around the player by that amount of degrees using Quaternion.AngleAxis. Finally we make sure that the camera is always looking at the player by using transform.LookAt
using UnityEngine;
using System.Collections;
public class OrbitPlayer : MonoBehaviour {
public float turnSpeed = 5.0f;
public GameObject player;
private Transform playerTransform;
private Vector3 offset;
private float yOffset = 10.0f;
private float zOffset = 10.0f;
void Start () {
playerTransform = player.transform;
offset = new Vector3(playerTransform.position.x, playerTransform.position.y + yOffset, playerTransform.position.z + zOffset);
}
void FixedUpdate()
{
offset = Quaternion.AngleAxis (Input.GetAxis("Mouse X") * turnSpeed, Vector3.up) * offset;
transform.position = playerTransform.position + offset;
transform.LookAt(playerTransform.position);
}
}
There is a lot of information on this topic over here:
https://answers.unity.com/questions/600577/camera-rotation-around-player-while-following.html