So i have this script that rotates a point around my "character", it worked until i added a minimap using the canvas ui element, now only works on the bottom left side of the screen.
Here you can see more clearly what im talking about.
this is my script:
using UnityEngine;
public class PlayerAim : MonoBehaviour
{
private void LateUpdate()
{
AimMouse();
}
void AimMouse()
{
Vector3 mousePos = Input.mousePosition;
mousePos = Camera.main.ScreenToWorldPoint(mousePos);
Vector2 direction = new Vector2(
mousePos.x - transform.position.x,
mousePos.y - transform.position.y
);
transform.up = direction;
}
}
I'd be willing to bet your minimap uses a second camera, correct? Do both cameras have the MainCamera tag? If so, then your code that calls Camera.main would have undefined behaviour as to which camera it actually uses. Most likely, it's using the minimap camera for the ScreenToWorldPoint call, which is giving you the unexpected behaviour.
What you need to do is either (a) remove the MainCamera tag from the minimap camera object, or (b) add a Camera reference to your script, and reference it directly in the code.
Related
I am trying to change this script that I found online https://pressstart.vip/tutorials/2018/09/25/58/spawning-obstacles.html to work with a orthographic camera because that is what my game uses. At the moment it only works with perspective cameras and I don't really know how this works cause I have not really touched the camera matrix. Here is the code for the script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class deployAsteroids : MonoBehaviour {
public GameObject asteroidPrefab;
public float respawnTime = 1.0f;
private Vector2 screenBounds;
// Use this for initialization
void Start () {
screenBounds = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, Camera.main.transform.position.z));
StartCoroutine(asteroidWave());
}
private void spawnEnemy(){
GameObject a = Instantiate(asteroidPrefab) as GameObject;
a.transform.position = new Vector2(screenBounds.x * -2, Random.Range(-screenBounds.y, screenBounds.y));
}
IEnumerator asteroidWave(){
while(true){
yield return new WaitForSeconds(respawnTime);
spawnEnemy();
}
}
}
My goal is to change the script to make it work correctly with a orthographic camera. (The indentation is messed up and that is not the problem).
For some reason the code is using Camera.main.transform.position.z for the camera depth component. This value will be negative in a typical camera setup in a 2d game.
So it's finding the left side of the screen by following the right edge of the frustum behind the camera. Very odd. You can't follow the right side of the frustum to find where the left side of the screen if it's orthographic so it is no surprise that it doesn't work.
Instead, just use the left side of the frustum and make the depth positive by negating that component:
screenBounds = Camera.main.ViewportToWorldPoint(
new Vector3(0f, 0f, -Camera.main.transform.position.z));
Hi Im not very good at c# but good at unity anyway i was making a game like gta v and i start with making the camera first and i have success with that . second thing i have start making is the movement and for the vertical movement it was good but when came to make the horizontal movement it worked too but the problem is when i move left and right the camera are turning left and right using ("a" button And "d" btton) that's mean when ever i move the player left and right the camera is turning left and right too using these two button But this is not what i want . for butter understanding please whatch this video to see the problem https://youtu.be/5ZPQg8EjIJ0 .
Now here is what i did
1- first i made an empty game object that has two things the player prefab and the camera as the child
Notice: i didnt make the camera a child of the player prefab
2- i made the cameraTurn Script And add it to the main camera
Here is the cameraTurn Script
using UnityEngine;
using System.Collections;
public class cameraTurn : MonoBehaviour {
[SerializeField] private Transform target;
public float rotSpeed = 1.5f;
private float _rotY;
private Vector3 _offset;
void Start()
{
_rotY = transform.eulerAngles.y;
_offset = target.position - transform.position;
}
void LateUpdate()
{
float horInput = Input.GetAxis("Horizontal");
if (horInput != 0) {
_rotY += horInput * rotSpeed;
} else {
_rotY += Input.GetAxis("Mouse X") * rotSpeed * 3;
}
Quaternion rotation = Quaternion.Euler(0, _rotY, 0);
transform.position = target.position - (rotation * _offset);
transform.LookAt(target);
}
}
3- I have made an small sphere and add it to the player prefab as a child and made at the top of the character and call it Mind
And Then i have added the mind as a target for the camera so the camera can look at it when ever it turning
Now if you start the game and move your mouse left and right you can see the camera are looking on the player while it move like gta v and also if you pressed [a] key and [d] key the camera will go around too and this is not what i want because if i keep going and making the movement it will be disaster just like the video you have seen in the top
Hope its all good And if there anything feel free to comment and i will give you more info Thanks,
I've been doing some research on why my player(GameObject) is does not rotate toward my mouse position in my TopDown 3D game and I can't seem to find what is wrong with my code, so im making this post. The problem thats I have is that only the GameObject of my player (in my case, a capsule) rotate toward my mouse position but the axis of my player stays the same. In other word, I can't rotate the axis of my player, to face my mouse position, but I can rotate the GameObject of my player to face my mouse position. Its really hard to explain and this never happened to me before. Question is how can I rotate the axis of my player to face my mouse position. Keep in mind that my game is a top down view.
Here is the code im using for my playerMouvment and for my mouseLook:
public class Controller : MonoBehaviour
{
public float moveSpeed = 6;
Rigidbody rb;
Camera viewCamera;
Vector3 velocity;
void Start()
{
rb = GetComponent<Rigidbody>();
viewCamera = Camera.main;
}
void Update()
{
Vector3 mousePos = viewCamera.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, viewCamera.transform.position.y));
transform.LookAt(mousePos + Vector3.up * transform.position.y);
velocity = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical")).normalized * moveSpeed;
}
void FixedUpdate()
{
rb.MovePosition(rb.position + velocity * Time.fixedDeltaTime);
}
}
Again I tried and look for any error in my code and I can't find anything that cause this weird situation and so if anyone can help me find a better way to write this code and solve my problem it would be great!
If I understand you correctly everything is fine with your game and the player is turning as it should, but only in the editor that the axis of the player (red, green and blue arrows) don't turn with the player?
If this is the problem it might be that you are using global space handle instead of local space. Clicking the icon I highlighted in the image should do the trick.
Use this code instead of LookAt() function
Vector2 direction = mousePos.position - player.transform.position;
player.transform.right /* Maybe you need Up or -Up or -right */ = direction;
This would work too in some cases
Vector2 direction = new Vector2
(
mousePos.position.x - player.transform.position.x,
mousePos.positoin.y - player.transform.position.y
)
player.transform.right /* Maybe you need Up or -Up or -right */ = direction;
I am using unity 2018.3.5f1 so a few solutions to this problem don't work.
Starting from the Roll-A-Ball demo project, I want to extend the camera script to follow the player, but also keeping track of the direction of movement. Ex: If the ball starts moving to the side, I need the camera to rotate around the player's axis to position behind him, and then start following him.
I have tried making the camera a child to the ball i'm trying to control and i've tried making a script but it won't follow the ball correctly it keeps rotating the camera as well as the ball (i'm using this bit of code and trying to modify it as it's the only one that works)
here is the code I have at the moment:
using UnityEngine;
using System.Collections;
public class CompleteCameraController : MonoBehaviour
{
public GameObject player; //Public variable to store a reference to the player game object
private Vector3 offset; //Private variable to store the offset distance between the player and camera
// Use this for initialization
void Start()
{
//Calculate and store the offset value by getting the distance between the player's position and camera's position.
offset = transform.position - player.transform.position;
}
// LateUpdate is called after Update each frame
void LateUpdate()
{
// Set the position of the camera's transform to be the same as the player's, but offset by the calculated offset distance.
transform.position = player.transform.position + offset;
}
}
I understand why it is rotating but no reasearch is helping me find out how to lock the camera so it is looking behind the ball at all times
Have you tried adding some restraints to your camera? If it is only supposed to turn to follow the ball, you can freeze the position of 2 axes (x and z), and only let the camera rotate around the y axis of the ball.
You can play around with the restraints on the Inspector, or use GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezeRotationX; in the camera script.
(EDIT) Sorry, this is how you would do it if the gameObject has a rigidbody, but the idea is the same if it doesn't have one.
When you're setting the position or rotation of the camera, think about which components of the position/rotation you actually want to change (x,y,z).
Use offset = new Vector3 (offset.x, offset.y, offset.z)and replace anything that shouldn't change with a constant.
Also, when you made the Camera the child of the ball, you could have set it so that every frame, the Camera updates in such a way that it won't roll with the ball. You could do this by putting code in the update method of the camera that sets the component x, y, or z equal to some constant. Whatever axis the ground plane is on is probably the correct choice.
If you want the same camera angle that the camera should follow while following the ball (similar to Temple Run), then try the below code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class CompleteCameraController : MonoBehaviour
{
public Transform Player;
public float distanceFromObject = 3f;
void Update()
{
Vector3 lookOnObject = Player.position - transform.position;
lookOnObject = Player.position - transform.position;
transform.forward = lookOnObject.normalized;
Vector3 playerLastPosition;
playerLastPosition = Player.position - lookOnObject.normalized * distanceFromObject;
playerLastPosition.y = Player.position.y + distanceFromObject / 2;
transform.position = playerLastPosition;
}
When the ball moves left or right, the camera will follow the same angle as the ball moves towards.
I have been working on getting a camera to follow my player when he moves with 3rd person controller.
At the moment the camera does follow him but the view remains looking forward, so if I was to move left and right the camera sits still instead of rotating to face the same direction as my character.
The code I currently have is:
using UnityEngine;
using System.Collections;
public class CameraController : MonoBehaviour
{
public GameObject player;
private Vector3 offset;
void Start ()
{
offset = transform.position - player.transform.position;
}
void LateUpdate ()
{
transform.position = player.transform.position + offset;
}
}
Anyone know a solution to make my camera rotate with the charater?
You have three option for getting this done.
Make the camera as a child of your 3rd person in game object hierarchy.
Using scripts align its forward vector to the person's forward vector.
transform.forward = player.transform.forward;
Using scripts make the camera to LookAt the 3rd person.
transform.LookAt(player);