I made the script bellow for the camera to follow the player, but I don't want it to follow him on his X axis. So it should follow the player smoothly only on his Z axis. Any suggestions?
Camera Script:
public Transform Ball;
public float SmoothSpeed = 0.125f;
public Vector3 offset;
bool MoveCamera = true;
void Start () {
}
public void FixedUpdate () {
if(MoveCamera == true){
Vector3 desiredPosition = Ball.position + offset;
Vector3 SmoothedPosition = Vector3.Lerp(transform.position, desiredPosition, SmoothSpeed);
transform.position = SmoothedPosition;
}
if (transform.position.z >= 2f)
{
MoveCamera = false;
}
}
What about only changing the z component?
public void FixedUpdate () {
if(MoveCamera == true){
Vector3 desiredPosition = new Vector3(0, Ball.position.y + offset.y, Ball.position.z + offset.z);
Vector3 SmoothedPosition = Vector3.Lerp(transform.position, desiredPosition, SmoothSpeed);
transform.position = SmoothedPosition;
}
if (transform.position.z >= 2f)
{
MoveCamera = false;
}
}
public gameObject toFollow;
Vector3 camDistance;
public void Start(){
camDistance = toFollow.transform.position-Camera.main.position;
}
public void Update(){
Vector3 following = new Vector3(Camera.main.x,Camera.main.z,toFollow.transform.position.z-Camera.main.position.z);
Camera.main.transform.position = following;
}
i just threw this together so it may require a few tweaks, but it should get you where you need to go. alternatively.... you can add a rigidbody to the camera, and in the inspector tick the boxes for constraints on the x and y axis. this will allow it to move only on the z (if you go this route remember to turn of the gravity for the cameras rigidbody as well)
Anybody in 2019 need a camera to be offset a specific position from their 3d character? Here is an easy solution! Attach this script to the camera you want to follow the player. Select the player as your target in the Unity editor.
This script sets the new position of the camera to
(EDIT: Where did the LaTeX go?)
$v = <targetPosition.x + xOffset, targetPosition.y + yOffset, targetPosition.z + zOffset>$
Benefits of this script:
Camera orientation does not change, even if character turns (because camera is not parented to the player).
Works regardless of player position
Limitations:
- Because camera orientation is fixed, you need to make sure that your character is not obscured by scenery.
- This style of camera control is best-suited for a 3rd person orthographic projection.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraController : MonoBehaviour
{
public Transform target;
Vector3 targetPos;
void Update()
{
targetPos = target.position;
transform.position = new Vector3(targetPos.x + 10f, targetPos.y + 8.571067812f, targetPos.z - 10f);
// transform.LookAt(target.transform);
}
}
My use-case required an orthographic projection. Orthographic angles are usually at a 30 degree angle of declination, so my offset is back 10 units, over 10 units, and up half that hypotenuse (that is, up 10*sqrt2 * 1/2). I also bumped the y-position up by the character's height (1.5 units), which I thought would give a better center for the camera target. This gives a y-offset of about 8.571067812.
Related
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);
}
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);
}
This is what i got and why does this website want me to put more explaining when i clarified above well i want to achieve a smooth camera control where the player is in the middle of the camera if the mouse is in the middle but as it moves toward a direction i want the camera to move just a little bit to reveal terrain (here i have 2 problems:
1.The camera doesnt move if the mouse is at the point 0,0 of the screen and i want it to be the center of the camera
2. the camera drifts away in that direction, it doesnt stop like i want to make it):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraController : MonoBehaviour {
// Camera cam = Camera.main.orthographicSize;
//Vector2 camcenter = new Vector2(cam * 2, camheight);
public GameObject mage;
private Vector3 offset;
public float mincam = 30f;
public float maxcam = 120f;
public bool mouse_smooth_cam = false;
// Update is called once per frame
void LateUpdate ()
{
offset = Input.mousePosition / 100 + transform.position - mage.transform.position;
transform.position = mage.transform.position + offset;
}
void Update()
{
HandleZoom();
}
private void HandleZoom()
{
float scrollValue = Input.mouseScrollDelta.y;
float newCamSize = Camera.main.orthographicSize - scrollValue*4;
Camera.main.orthographicSize = Mathf.Clamp(newCamSize, mincam, maxcam);
}
}
Instead of Input.mousePosition / 100 use Camera.main.ScreenToWorldPoint(Input.mousePosition)
also always use Time.deltaTime in Update methods
var PAN_SPEED = 30f;
var mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
offset = mousePos + transform.position - mage.transform.position;
transform.position = mage.transform.position + offset * Time.deltaTime * PAN_SPEED;
I am trying to make a simple game where I am shooting a projectile when the user touches the screen, I first spawn 8 projectiles (sprites) and when the user touches the screen I would like the top projectile to fly in the touch direction. I was able to do this; However, every time I shoot, the projectile goes in the wrong direction, here is an image which will illustrate the issue.
Obviously the image is still here but the object will continue flying until it goes out of the screen and then gets destroyed.
Here is the code snippet that handles this
GameplayController.cs
if (Input.GetMouseButtonDown(0))
{
Vector3 position = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0);
position = Camera.main.ScreenToWorldPoint(position);
GameObject target;
target = new GameObject();
target.transform.position = position;
Arrow comp = currentArrows[0].GetComponent<Arrow>();
comp.setTarget(target.transform);
comp.GetComponent<Arrow>().arrowSpeed = 12;
comp.GetComponent<Arrow>().shoot = true;
currentArrows.RemoveAt(0);
Destroy(target);
}
I know I am getting the mouse input here and not the phone touch and that's fine for me, later I will convert it to the touch input.
Arrow.cs
public bool shoot = false;
public float arrowSpeed = 0.0f;
public Vector3 myDir;
public float speed = 30.0f;
private Transform target;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if(shoot)
{
transform.position += transform.right * arrowSpeed * Time.deltaTime;
}
}
public void setTarget(Transform targetTransform)
{
this.target = targetTransform;
Vector3 vectorToTarget = target.position - transform.position;
float angle = Mathf.Atan2(vectorToTarget.y, vectorToTarget.x) * Mathf.Rad2Deg;
Quaternion q = Quaternion.AngleAxis(angle, Vector3.forward);
transform.rotation = Quaternion.Slerp(transform.rotation, q, Time.deltaTime * speed);
}
private void OnBecameInvisible()
{
print("Disappeared");
Destroy(gameObject);
Gameplay.instance.isShooting = false;
}
Vector3 position = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0);
I think that your problem is that you're getting the screen coordinates by click, not the world coordinates, which is actually two different things. In order to direct your projectile correctly you need to convert your screen coordinates to world like it's done here.
The next thing is how you move the projectile:
transform.position += transform.right * arrowSpeed * Time.deltaTime;
You're moving the projectile to the right and then rotating it somehow. Maybe you should try to move it with Vector3.Lerp, which will be easier and rotate it with Transform.LookAt.
I've made my camera a child of my character so that it follows it's movement. However I don't want the camera to move upwards when the player jumps, or follow it when it falls.
Is there a way in c# i can free the y?
You would have to update your camera position manually and store Y position of a camera after initialization.
Transform playerTransform;
float yPosition;
Vector3 offsetVector; // some offset vector from player
public void AttachToPlayer(Transform pTransform) {
playerTransform = pTransform;
y.position = playerTransform.position.y + 0.5; //some offset
}
void Update() {
transform.position = playerTransform.position + playerTransorm.rotation*offsetVector;
transform.position.y = yPosition;
}
That should do the trick, but it is very simple implementation. And it will only work if level is on same y position.