Unity 5 - edit the camera2DFollow script - c#

I'm using the standard camera2DFollow script that comes with Unity 5. But I have a problem with the position of the camera. I've rotated my main camera and it looks like this now.
You see that my player is on top of the screen instead of the middle.
This is the default script in C# for the people who don't have it.
using System;
using UnityEngine;
namespace UnityStandardAssets._2D
{
public class Camera2DFollow : MonoBehaviour
{
public Transform target;
public float damping = 1;
public float lookAheadFactor = 3;
public float lookAheadReturnSpeed = 0.5f;
public float lookAheadMoveThreshold = 0.1f;
private float m_OffsetZ;
private Vector3 m_LastTargetPosition;
private Vector3 m_CurrentVelocity;
private Vector3 m_LookAheadPos;
// Use this for initialization
private void Start()
{
m_LastTargetPosition = target.position;
m_OffsetZ = (transform.position - target.position).z;
transform.parent = null;
}
// Update is called once per frame
private void Update()
{
// only update lookahead pos if accelerating or changed direction
float xMoveDelta = (target.position - m_LastTargetPosition).x;
bool updateLookAheadTarget = Mathf.Abs(xMoveDelta) > lookAheadMoveThreshold;
if (updateLookAheadTarget)
{
m_LookAheadPos = lookAheadFactor*Vector3.right*Mathf.Sign(xMoveDelta);
}
else
{
m_LookAheadPos = Vector3.MoveTowards(m_LookAheadPos, Vector3.zero, Time.deltaTime*lookAheadReturnSpeed);
}
Vector3 aheadTargetPos = target.position + m_LookAheadPos + Vector3.forward*m_OffsetZ;
Vector3 newPos = Vector3.SmoothDamp(transform.position, aheadTargetPos, ref m_CurrentVelocity, damping);
transform.position = newPos;
m_LastTargetPosition = target.position;
}
}
}
I want to change the Y to a +3 of the current position. So if my camera is on Y 2 than put it on Y 5. (This makes it so the player is in the middle and not on the top).
Thanks for the help!

You can do this by adding 3 to the camera's position at the end of each frame but I recommend against it.
What I would do, is create an empty object, name it "PlayerCameraCenter" and make the player parent to this object; then place the camera center wherever you want relative to the player, like y = 3, and make the camera follow this object instead of the player.
This way you can easily change the position of the camera, through the editor without fiddling with code.

Related

Unity3D FollowCam not following player vehicle

I have a garage that gives the option for the player to select the car he wants to take to the race, the problem is the camera doesn't attach to the when it's sent.
The follow camera is using the standard unity assets.
Garage code(This code loads the car into the map):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class LoadCharacter : MonoBehaviour
{
public GameObject[] characterPrefabs;
public Transform spawnPoint;
//public TMP_Text label;
void Start()
{
int selectedCharacter = PlayerPrefs.GetInt("selectedCharacter");
GameObject prefab = characterPrefabs[selectedCharacter];
GameObject clone = Instantiate(prefab, spawnPoint.position, Quaternion.identity);
//label.text = prefab.name;
}
}
Camera code:
using System;
using UnityEngine;
#if UNITY_EDITOR
#endif
namespace UnityStandardAssets.Cameras
{
[ExecuteInEditMode]
public class AutoCam : PivotBasedCameraRig
{
[SerializeField] private float m_MoveSpeed = 3; // How fast the rig will move to keep up with target's position
[SerializeField] private float m_TurnSpeed = 1; // How fast the rig will turn to keep up with target's rotation
[SerializeField] private float m_RollSpeed = 0.2f;// How fast the rig will roll (around Z axis) to match target's roll.
[SerializeField] private bool m_FollowVelocity = false;// Whether the rig will rotate in the direction of the target's velocity.
[SerializeField] private bool m_FollowTilt = true; // Whether the rig will tilt (around X axis) with the target.
[SerializeField] private float m_SpinTurnLimit = 90;// The threshold beyond which the camera stops following the target's rotation. (used in situations where a car spins out, for example)
[SerializeField] private float m_TargetVelocityLowerLimit = 4f;// the minimum velocity above which the camera turns towards the object's velocity. Below this we use the object's forward direction.
[SerializeField] private float m_SmoothTurnTime = 0.2f; // the smoothing for the camera's rotation
private float m_LastFlatAngle; // The relative angle of the target and the rig from the previous frame.
private float m_CurrentTurnAmount; // How much to turn the camera
private float m_TurnSpeedVelocityChange; // The change in the turn speed velocity
private Vector3 m_RollUp = Vector3.up;// The roll of the camera around the z axis ( generally this will always just be up )
protected override void FollowTarget(float deltaTime)
{
// if no target, or no time passed then we quit early, as there is nothing to do
if (!(deltaTime > 0) || m_Target == null)
{
return;
}
// initialise some vars, we'll be modifying these in a moment
var targetForward = m_Target.forward;
var targetUp = m_Target.up;
if (m_FollowVelocity && Application.isPlaying)
{
// in follow velocity mode, the camera's rotation is aligned towards the object's velocity direction
// but only if the object is traveling faster than a given threshold.
if (targetRigidbody.velocity.magnitude > m_TargetVelocityLowerLimit)
{
// velocity is high enough, so we'll use the target's velocty
targetForward = targetRigidbody.velocity.normalized;
targetUp = Vector3.up;
}
else
{
targetUp = Vector3.up;
}
m_CurrentTurnAmount = Mathf.SmoothDamp(m_CurrentTurnAmount, 1, ref m_TurnSpeedVelocityChange, m_SmoothTurnTime);
}
else
{
// we're in 'follow rotation' mode, where the camera rig's rotation follows the object's rotation.
// This section allows the camera to stop following the target's rotation when the target is spinning too fast.
// eg when a car has been knocked into a spin. The camera will resume following the rotation
// of the target when the target's angular velocity slows below the threshold.
var currentFlatAngle = Mathf.Atan2(targetForward.x, targetForward.z)*Mathf.Rad2Deg;
if (m_SpinTurnLimit > 0)
{
var targetSpinSpeed = Mathf.Abs(Mathf.DeltaAngle(m_LastFlatAngle, currentFlatAngle))/deltaTime;
var desiredTurnAmount = Mathf.InverseLerp(m_SpinTurnLimit, m_SpinTurnLimit*0.75f, targetSpinSpeed);
var turnReactSpeed = (m_CurrentTurnAmount > desiredTurnAmount ? .1f : 1f);
if (Application.isPlaying)
{
m_CurrentTurnAmount = Mathf.SmoothDamp(m_CurrentTurnAmount, desiredTurnAmount,
ref m_TurnSpeedVelocityChange, turnReactSpeed);
}
else
{
// for editor mode, smoothdamp won't work because it uses deltaTime internally
m_CurrentTurnAmount = desiredTurnAmount;
}
}
else
{
m_CurrentTurnAmount = 1;
}
m_LastFlatAngle = currentFlatAngle;
}
// camera position moves towards target position:
transform.position = Vector3.Lerp(transform.position, m_Target.position, deltaTime*m_MoveSpeed);
// camera's rotation is split into two parts, which can have independend speed settings:
// rotating towards the target's forward direction (which encompasses its 'yaw' and 'pitch')
if (!m_FollowTilt)
{
targetForward.y = 0;
if (targetForward.sqrMagnitude < float.Epsilon)
{
targetForward = transform.forward;
}
}
var rollRotation = Quaternion.LookRotation(targetForward, m_RollUp);
// and aligning with the target object's up direction (i.e. its 'roll')
m_RollUp = m_RollSpeed > 0 ? Vector3.Slerp(m_RollUp, targetUp, m_RollSpeed*deltaTime) : Vector3.up;
transform.rotation = Quaternion.Lerp(transform.rotation, rollRotation, m_TurnSpeed*m_CurrentTurnAmount*deltaTime);
}
}
}
This are the cars that the map gets from the selection
This is the follow cam
This is what happens when the player chooses the car, it switches places with an empty object
The only way to follow is if I go in the editor and manually drag the car into the follow
Edit: I found a way to work around it, anyone wondering you just have to make a prefab with the car and camera.

Moving Maincamera slowly to another position

I want to move main camera slowly from one point to another point when a button is pressed. This button calls the method which has the code to move the camera.
I have tried using the Lerp method but the camera position is changing so fast that when I click on the button camera directly shifting to a new position. I want the camera to move slowly to a new position.
Below is my code, can anyone please help me with this.
=========================================================================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Cameramove : MonoBehaviour
{
public GameObject cam;
Vector3 moveToPosition;// This is where the camera will move after the start
float speed = 2f; // this is the speed at which the camera moves
public void move()
{
//Assigning new position to moveTOPosition
moveToPosition = new Vector3(200f, 400f, -220f);
float step = speed * Time.deltaTime;
cam.transform.position = Vector3.Lerp(cam.transform.position, moveToPosition, step);
cam.transform.position = moveToPosition;
}
}
It's easier to use lerp with frames and you need to use it in an Update function. Try using the example from the Unity docs:
public int interpolationFramesCount = 45; // Number of frames to completely interpolate between the 2 positions
int elapsedFrames = 0;
void Update()
{
float interpolationRatio = (float)elapsedFrames / interpolationFramesCount;
Vector3 interpolatedPosition = Vector3.Lerp(Vector3.up, Vector3.forward, interpolationRatio);
elapsedFrames = (elapsedFrames + 1) % (interpolationFramesCount + 1); // reset elapsedFrames to zero after it reached (interpolationFramesCount + 1)
Debug.DrawLine(Vector3.zero, Vector3.up, Color.green);
Debug.DrawLine(Vector3.zero, Vector3.forward, Color.blue);
Debug.DrawLine(Vector3.zero, interpolatedPosition, Color.yellow);
}
Try using smooth damp.
Here is the new code you should try:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Cameramove : MonoBehaviour
{
Vector3 matric;
public GameObject cam;
Vector3 moveToPosition;
float speed = 2f;
bool move_ = false;
void Update(){
if(move_){
//Assigning new position to moveTOPosition
moveToPosition = new Vector3(200f, 400f, -220f);
cam.transform.position =
Vector3.SmoothDamp(cam.transform.position,
moveToPosition,
ref matric, speed);
}
}
public void move()
{
move_ = true;
}
}

Change camera position when following player in unity

I have created a walking character in Unity 3D and I watched a tutorial to make a script that makes the player follow the camera which is good but I want the camera to be lower done and to be rotated more backwards so that the camera can see more of the world as right now not much is visible passed the player. I have attached a link to an image of what it looks like now.
https://i.imgur.com/jQ6efAJ.png
as you can see you can't see much of what's in front of the player.
Next I will attach the script and hopefully you can show me what code needs adding or changing to allow my changes to be possible.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraFollow : MonoBehaviour
{
public Transform playerObject;
public float distanceFromObject = 6f;
void Update()
{
Vector3 lookOnObject = playerObject.position - transform.position;
lookOnObject = playerObject.position - transform.position;
transform.forward = lookOnObject.normalized;
Vector3 playerLastPosition;
playerLastPosition = playerObject.position - lookOnObject.normalized * distanceFromObject;
playerLastPosition.y = playerObject.position.y + distanceFromObject / 2;
transform.position = playerLastPosition;
}
Thank you in advance for helping me. This is for a school project so I really hope that your solutions are great and can't wait to hear from you!
You're looking into adding an offset to the camera relative to the look position of the camera. What you need to do is to offset the playerObject.position when you assign it to the lookOnObject.
Add a new vector3 and call it as an lookOffset. It will now become lookOnObject = (playerObject.position + lookOffset) - transform.position. It will act as a pitch control for your camera.
Use distanceFromObject to control the z position of the camera.
[EDIT]
Here's the altered script that I made. As mentioned above, you need to offset the position that the camera will look to. In this script, instead of a Vector3, I used float:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;`
public class CameraFollow : MonoBehaviour
{
public Transform playerObject;
//Controls the pitch of the camera where it rotates
//in X axis
public float pitchOffset = 0;
//Controls the yaw of the camera where it rotates
//in Y axis
public float yawOffset = 0;
public float distanceFromObject = 6f;
void Update()
{
//Creation of the look offset relative to the
//Observable position
Vector3 lookOffset = playerObject.position;
lookOffset.y += pitchOffset;
lookOffset.x += yawOffset;
Vector3 lookOnObject = playerObject.position - transform.position;
//Replaced playerObject.position with lookOffset
lookOnObject = lookOffset - transform.position;
transform.forward = lookOnObject.normalized;
Vector3 playerLastPosition;
//Replaced playerObject.position with lookOffset
playerLastPosition = lookOffset - lookOnObject.normalized * distanceFromObject;
playerLastPosition.y = playerObject.position.y + distanceFromObject / 2;
transform.position = playerLastPosition;
}
}
It could be done with Vector3 or Vector2 where you store the pitchOffset, and yawOffset to x and y fields.

Right paddle not moving in pong game for unity

I am trying to allow the player, in a pong game, to control both paddles. However, for some reason only one paddle is controllable while the other simply does nothing. Here is an image of the paddle property bar.
And here is the code to the right most paddle that should be controlled with arrow keys.
using UnityEngine;
using System.Collections;
public class PaddleRight : MonoBehaviour
{
public Vector3 playerPosR;
public float paddleSpeed = 1F;
public float yClamp;
void Start()
{
}
// Update is alled once per frame
void Update()
{
float yPos = gameObject.transform.position.y + (Input.GetAxis("Vertical") * paddleSpeed);
if (Input.GetKey(KeyCode.DownArrow) || Input.GetKey(KeyCode.UpArrow)) {
playerPosR = new Vector3(gameObject.transform.position.x, Mathf.Clamp(yPos, -yClamp, yClamp), 0);
print("right padddle trying to move");
}
gameObject.transform.position = playerPosR;
}
}
I can't seem to figure out anywhere why it won't move.. Please, any help would be awesome because I have checked everywhere at this point. Thanks!
I recreated the problem in a project and found that the only problem with it might be you forgetting that the yClamp is public and its set to 0 in the inspector. Make sure you set yClamp to whatever it should be instead of 0.
I would suggest moving the yPos assignment as well as setting the position inside the if statement as you arent changing those if the player isnt moving.
You can also change gameObject.transform.position to just plain transform.position
here is the refined code:
public Vector3 playerPosR;
public float paddleSpeed = 1F;
public float yClamp; // make sure it's not 0 in the inspector!
// Update is alled once per frame
void Update()
{
if (Input.GetKey(KeyCode.DownArrow) || Input.GetKey(KeyCode.UpArrow))
{
float yPos = transform.position.y + (Input.GetAxis("Vertical") * paddleSpeed);
playerPosR = new Vector3(transform.position.x, Mathf.Clamp(yPos, -yClamp, yClamp), 0);
transform.position = playerPosR;
}
}

Building an orthographic camera for Unity3D, how can I keep four specific targets in sight?

I have a 2D Orthographic camera for a game that is built similarly to Tennis. I've been working out the code for this, and I think I'm only part of the way so far. At the moment... it... sort-of keeps the two players in frame, with the frame leading more towards the human player - Player One. However, it also has a tendency to drop below the ground level - especially when it zooms out to keep the targets in view. There are four specific targets: The Ground, Ball, Player One, and Player Two.
The ground should always be at the 'bottom', otherwise when the camera goes below ground it shows sky - not really a desirable effect. This is the code I've developed so far... the two players are effectively paddles, but it only shows the center between them:
using UnityEngine;
using System.Collections;
public class CameraController : MonoBehaviour {
// Moving Camera, This Camera tries to follow Player One, Two, and Ball //
public static CameraController Instance;
public Transform PlayerOne;
public Transform PlayerTwo;
public Transform Ball;
public bool Ready = false;
private float MinX = -46.0f;
private float MaxX = 46.0f;
private float MinY = 12.0f;
private float MaxY = 35.0f;
private float LimitFromPlayerX = 20.0f;
private float LimitFromPlayery = 20.0f;
private float DistanceToGround = 0.0f;
private float DistanceFromCenter = 2.0f;
private float Height = 4.0f;
private float Damping = 5f;
private Vector3 EstimatedCameraPosition = Vector3.zero;
private Vector3 WantedPosition = Vector3.zero;
void Awake()
{
Instance = this;
}
public void SetCameraPosition()
{
Vector3 PlayerPosistion = PlayerOne.position;
PlayerPosistion.z = -10.10f;
transform.position = PlayerPosistion;
}
// Update is called once per frame
void FixedUpdate () {
if (Ready) {
Vector3 PlayerPosistion = PlayerOne.position;
PlayerPosistion.z = -10.10f;
Vector3 CameraPosition = transform.position;
CameraPosition.z = -10.10f;
// Get the Distance from the Player to the Ball //
Vector3 WantedPosition = PlayerTwo.transform.position - -PlayerOne.transform.position;
float WPMag = Mathf.Abs(WantedPosition.magnitude);
WPMag = Mathf.Clamp(WPMag, 20, 40);
Debug.Log(WPMag);
Camera.main.orthographicSize = WPMag;
transform.position = Vector3.Lerp(CameraPosition, WantedPosition, Damping * Time.deltaTime);
}
}
void LateUpdate()
{
Vector3 Posit = transform.position;
Posit.x = Mathf.Clamp (Posit.x, MinX, MaxX);
Posit.y = Mathf.Clamp (Posit.y, MinY, MaxY);
transform.position = Posit;
}
}
WPMag was my attempt to zoom out and match the players at least, but so far it's only partially working.
To keep all three objects in view, you'll want to focus the camera on the midpoint or "average" position of the three objects. Getting the midpoint of three objects works just like getting the midpoint of two objects: (PlayerOne.position + PlayerTwo.position + Ball.position) / 3.0f
You'll then want to set orthographic size to the furthest distance from the midpoint of the three tracked objects. This will ensure that all three objects stay in the frame.
Finally, to keep the camera from showing underground skies, you should enforce a lower limit for the camera's Y position. The orthographic size is half the vertical height of the viewport, so you'd use CameraPosition.y = Mathf.Max(CameraPosition.y, groundHeight + camera.main.orthographicSize)

Categories