Camera Controller in Unity - c#

There are two similar scripts that makes the same thing(The Camera is following the player).The first, is what I wrote and the second one, is from the unity tutorial.Which one is more reliable and why?
1st
public class CameraController : MonoBehaviour {
public GameObject player;
void LateUpdate () {
transform.position = new Vector3 (player.transform.position.x, player.transform.position.y,-10f);
}
}
2nd
public GameObject player;
private Vector3 offset;
void Start ()
{
offset = transform.position - player.transform.position;
}
void LateUpdate ()
{
transform.position = player.transform.position + offset;
}

There is no such thing as reliability between the two scripts. Although, I would encourage you to use the second script.
The first script is assigning the camera's position with the position of the player. The only thing it doesn't assign is the z-axis which you hard-coded to -10. When game starts, the camera will be moved to where the player is. The z- axis of the camera will be set to -10. This happens every late update.
The second script is assigning the camera's position with the position of the player and offset value taken in the start function. When game starts, the offset distance between the camera and the player is retrieved in the Start function. In the LateUpdate function, the player's position is retrieved and the offset is added to it and is then applied to the camera's position.
The result of the first script is that the camera will always be position where the player is but the z axis will always be set to -10. I am sure you don't want the z axis to not be moving.
The result of the second script is that the camera will always have the-same distance between it and the player. Even if you move the camera or player from the Editor, the second script will automatically adjust the position and make sure that the distance between the camera and the player before the game started is always the-same. I am sure this is what you are looking for but I wouldn't call this reliable. The first code is simply not appropriate for what you are doing , the second code is.

I would bet that the second one is more reliable because it doesn't have any hardcoded variables. But it's also easy to use to programmers and none programmers since it calculates the offSet you want to give in any direction based on the position you set on the scene.

Related

I am working on a game project on unity and I am stuck at a camera problem

It has two camera angles. First person for engaging gameplay and top-down for 2D game experience. But in top down camera view I can't figure out the rotation of the camera with respect to player.
I wrote the following script for the main(top-down) camera view.
public class FollowPlayer : MonoBehaviour
{
public GameObject player;
private Vector3 offset = new Vector3(0f, 24.953f, -0f);
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void LateUpdate()
{
transform.position = player.transform.position + offset;
}
}`
I tried
transform.rotation = player.transform.rotation;
but it didn't work since camera is on top of player. If I could somehow do
transform.rotation = player.transform.rotation + X axis 90 degree;
That would be perfect but I don't know how to do that.
If I understand you correctly, you want to follow the player from above with your second camera. Leaving some flexibility, the best option I think would be Unity's built in Transform.LookAt(target) method (LookAt), which automatically rotates an object (in your case the camera) so that it faces the target.
Therefore, you could do something like this in your Update, assuming your script is attached to the Camera. Otherwise substitute transform with Camera.main.transform:
transform.LookAt(player);
Note: If you plan to have your camera fixed above your player at all times, it is sufficient if you perform the LookAt once, e.g. in Start and then attach the camera as a child to the player. If your camera does not move with your player in the world but you want it to focus the player anyway, do do it in Update. Hope I addressed your problem:)
My problem has been resolved. I was trying to rotate the wrong axis. My bad.
mouseInput = Input.GetAxis("Mouse X");
transform.Rotate(Vector3.forward * speed * -mouseInput);
I needed to get mouse input from user and change the Z-axis according to it. Game is working fine now.

How to instantiate an object to the where the camera is looking at in Unity

I have been making a first person game called "shoot the ball into the bin". The camera is in a cylinder as a player also the cylinder has collision.
I have been struggling with the main driver of the game. Like in most first person shooter games, you shoot out from the center point of the camera or the cursor.
I have trouble replicating that. The code I have so far for the shooting is:
Instantiate(prefab, new Vector3(Camera.main.transform.position.x, Camera.main.transform.position.y, Camera.main.transform.position.z), Camera.main.transform.rotation);
(Credits to #derHugo for helping me instantiate a prefab)
But that just spawns it on top of the player, not in front of it. How do I make it shoot away from the player, but also in front of the player, not on top.
In order to spawn in front of that position simply use
// Already reference this via the Inspector if possible
[SerializeField] private Camera _camera;
// Adjust how far in front of the camera the object should spawn
[SerializeField] private float distance;
private void Awake ()
{
// otherwise get it ONCE
if(!_camera) _camera = Camera.main;
}
And then simply add an offset in the direction of Transform.forward of the camera like
Instantiate(prefab, _camera.transform.position + _camera.transform.forward * distance, _camera.transform.rotation);
so it seems when you instantiate the bullets, you are spawning them directly on the position of the camera. You should adjust those values so that it spawns in the center of the screen. To do so, you should divide the y position by 2 or 1.5 depending on how high up the gun is from the ground. Then change the z so that the bullets pushed further in front of the player.
Instantiate(prefab, new Vector3(Camera.main.transform.position.x, Camera.main.transform.position.y / 2, Camera.main.transform.position.z + somearbitraryvalue), Camera.main.transform.rotation);
Next, to get give the bullets a velocity, you should create a separate script for the bullet prefab that is in charge of moving the bullets.
public Rigidbody2D bullet;
bullet = GetComponent<Rigidbody2D>()
void Update(){
bullet.velocity = new Vector 3(0,0,1)
}
Hope this answer helps!

Player not moving down with gravity after transforming position - UNITY 2D

I'm making a game in which I have to transform the players position after he completes the objective, but when I transform him, he's stuck in the air on the new transform position, even though I have a Rigibody2D set on it with a gravity scale of 2. When I move him manually by dragging and releasing, he falls to the ground normally. I'm fairly new so any help would be appreciated. I can't seem to identify the problem.
Here's the code,
public GameObject player;
public Transform nextPart;
public Camera cam;
void Start()
{
}
// Update is called once per frame
void Update()
{
if (PlayerController.canTransform)
{
player.transform.position = nextPart.position;
cam.transform.position = new Vector3(nextPart.position.x, nextPart.position.y, -10);
}
}
Here's a picture too,
Your code is within the Update function. This means that so long as canTransform is true your player will be placed at that transform every frame.
You need to set that boolean back to false after moving your player or have some other check to ensure you don't move to that position more than once.
It might be better to instead have the player set to that position in a separate function and simply call it one time when you reaches that objective.

Character rotate at collider with camera script

I am using a simple script for the Camera to follow a Player target.
// 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;
}
but when I start the game the player starts rotating and ignores colliders when hitting a collider for the first time.
This started happening after I have put this script on the player. I even tried to freeze the rotation but if I freeze the rotation I can not rotate my player with animations. How can I fix this?
Attach this script to the 'Camera' not the 'Player' and you should be just fine.

How to make an enemy AI that would follow the player without rotating or looking at the player?

I am new to programming and I am making a 2D side-scrolling beat em' up for my project. I got an AI working for my enemies but my enemy objects are modelled to be flat so only one side is meant to be shown. When I start my game, the enemies immediately rotates to face the player when i wanted it to stay as it is but still move towards the player.
http://i.imgur.com/TJYtfro.png This is what I want the enemies to stay as, just having this face shown as it slides towards the player without rotating or tilting.
http://i.imgur.com/n0gI2Rf.png This is what happens when I start the game which is why I do not want the objects to rotate or tilt. If you want additional informations of what I have done or if I am unclear, just let me know. It is my first time asking online.
This is the code I got for the enemyAI. I know the code is all wrong when it comes to what I wanna achieve but I have very limited coding knowledge and still learning.
//------------Variables----------------//
public Transform target;
public int moveSpeed;
public int rotationSpeed;
public int maxdistance;
private Transform myTransform;
//------------------------------------//
void Awake()
{
myTransform = transform;
}
void Start ()
{
maxdistance = 2;
}
void Update ()
{
if(Vector3.Distance(target.position, myTransform.position) > maxdistance)
{
//Move towards target
transform.LookAt (target.position);
myTransform.position += myTransform.forward * moveSpeed * Time.deltaTime;
}
}
Your problem is that you have some confusion over what "forward" means. You need to decide which direction forward is. Currently, "forward " is "out of the screen", because you're doing a 2D side scroller and you have all of your enemies facing out of the screen.
However, you're trying to use LookAt() to make the characters look at the player. But then of course they'll turn, because "forward" for each enemy mesh/model is currently the direction facing out from their face.
You have two options. One is to rotate all of your models 90 degrees so that forward is coming out their side. In this case, you could still use LookAt() and then tell the enemies to move forward, but visually they'd still be looking out of the screen. However, the enemies would turn around backwards if you got onto their other side. So probably not a good option.
The other option is that you shouldn't be setting the enemy transform/position using the "forward" vector. Just set the enemy position based on a vector that's the difference between the enemy position and the player position. Subtract the enemy position vector from the player position vector and you'll have a vector pointing in the direction of the player. Normalize it to get a unit direction vector. Then multiply that by the move speed and delta time as you have above. Use that instead of "forward" and your enemies will toward the player. In this case, you don't call the LookAt() at all, because you always want the enemies facing out of the screen.
EDIT: I don't have a copy of Unity, but it should be something like this:
if (Vector3.Distance(target.position, myTransform.position) > maxdistance)
{
// Get a direction vector from us to the target
Vector3 dir = target.position - myTransform.position;
// Normalize it so that it's a unit direction vector
dir.Normalize();
// Move ourselves in that direction
myTransform.position += dir * moveSpeed * Time.deltaTime;
}

Categories