- Home /
Smooth Camera
Hello Unity3D i have a question about camera movement?How can i make it that when my character collides with with another character the camera moves to a 2d view and when there is no collision being dealt to the other character the camera moves back to the original spot?For example i want the camera to move from point (A) which is third person view and when my character collides with the other character it goes to point (B) 2d view.If anyone knows how i can do this?Can you please tell me how?
P.S this is what im aiming for link text
Answer by _Gkxd · Apr 07, 2015 at 03:18 PM
There are two sets of information that you want to keep track of: the 3rd person camera view, and the "2d" camera view. To switch between these two transforms smoothly, you can use Vector3.Lerp to interpolate the position of the camera and Quaternion.Lerp to interpolate the rotation of the camera.
Let's refer to the camera position/rotations as camPos3d, camRot3d, camPos2d, camRot2d
. Inside your LateUpdate
, you would do something along the lines of this (pseudocode):
camera.transform.position = Vector3.Lerp(camPos3d, camPos2d, t);
camera.transform.rotation = Quaternion.Lerp(camRot3d, camRot2d, t);
Here t
is a float value between 0 and 1. If t
is 0, the camera position will be in the 3rd person view. If t
is 1, the camera will be in 2d view. If t
is somewhere in between, the camera will be in a position somewhere in between.
What you can do now is in your collision handling code, if you're colliding with the right thing, increase t
gradually. If you're not colliding with the right thing, decrease t
gradually, clamping at 0/1.
Basic Example Code (C#)
using UnityEngine;
using System.Collections;
public class SmoothCameraSwapExample : MonoBehaviour {
private GameObject mainCamera;
private GameObject dummyCameraA;
private GameObject dummyCameraB;
private float cameraLerpAmount;
void Start () {
mainCamera = GameObject.FindGameObjectWithTag ("MainCamera");
// The dummy cameras are empty game objects used to keep track of the camera positions
dummyCameraA = new GameObject ("Dummy Camera A");
dummyCameraB = new GameObject ("Dummy Camera B");
dummyCameraA.transform.SetParent (transform);
dummyCameraB.transform.SetParent (transform);
dummyCameraA.transform.localPosition = new Vector3 (10, 5, 0);
dummyCameraB.transform.localPosition = new Vector3 (4, 0, -4);
dummyCameraA.transform.LookAt (transform);
dummyCameraB.transform.LookAt (transform);
}
void Update () {
// Space switches between the two camera positions
if (Input.GetKey (KeyCode.Space)) {
cameraLerpAmount = Mathf.Clamp01 (cameraLerpAmount + 0.1f);
} else {
cameraLerpAmount = Mathf.Clamp01 (cameraLerpAmount - 0.1f);
}
}
void LateUpdate() {
mainCamera.transform.position = Vector3.Lerp (dummyCameraA.transform.position, dummyCameraB.transform.position, cameraLerpAmount);
mainCamera.transform.rotation = Quaternion.Lerp (dummyCameraA.transform.rotation, dummyCameraB.transform.rotation, cameraLerpAmount);
}
}
This should be the basics of what you want. Just attach it to a GameObject and press space to swap views. The positions are currently hard-coded, but I think you'll get the idea. (Also, you need a camera tagged "MainCamera" in your scene.) Feel free to ask for more clarification.
Thank You So $$anonymous$$uch =D!But i have one more question?how would this script work if i was punching an object and if i don't click anything for over 1 second the camera goes back to the starting position?
This is just an example on how you would interpolate two camera transforms. The way that the lerp amount changes inside Update()
is completely up to you, so you would probably want to experiment with things other than what I put in Update()
.
Oh..=o Ok You have no idea how much i needed this.Thank You Again ^.^
Answer by IKilledKenny_2 · Apr 07, 2015 at 10:05 PM
Do You mean like this?
var player : GameObject;
var gravity : float = 60.0;
var myTransform : Transform;
var speed: float =5;
var mass: float = 3.0; // the lower the mass, the higher the impact
var hitForce: float = 2.5; // impact "force" when hit by rigidbody
var mainCamera : Camera;
var target : Transform;
var smooth : float = 5;
var normtarget : Transform;
var moveSpeed : float = 5;
var camPos3d : GameObject;
var camPos2d : GameObject;
var t : float = 5;
var camRot3d : float = 50;
var camRot2d : float = 50;
private var impact = Vector3.zero; // character momentum
private var character: CharacterController;
function Awake() {
myTransform = transform;
}
function Start() {
// Keep a note of the time the movement started.
enemy = GameObject.FindWithTag("Dummy").transform;
character = GetComponent(CharacterController);
}
function AddImpact(force: Vector3){
var dir = force.normalized;
dir.z = 0.5; // add some velocity upwards - it's cooler this way
impact += dir.normalized * force.magnitude / mass;
}
function Update(){
if (impact.magnitude > 0.2){ // if momentum > 0.2...
character.Move(impact * Time.deltaTime); // move character
}
// impact vanishes to zero over time
impact = Vector3.Lerp(impact, Vector3.zero, 5*Time.deltaTime);
}
function OnCollisionEnter(collision : Collision){
if(collision.gameObject.tag == "Dummy"&&player.animation.IsPlaying("Sidekick")){
enemy.transform.gameObject.animation.Play("Hit1");
AddImpact(enemy.relativeVelocity * hitForce);
}
if(collision.gameObject.tag == "Dummy"&&player.animation.IsPlaying("Sidekick_lightning")){
collision.transform.gameObject.animation.Play("Hit1");
mainCamera.transform.position = target.transform.position - target.transform.forward * smooth * moveSpeed;
mainCamera.transform.Rotate(0,-180,90);
camera.transform.position = Vector3.Lerp(camPos3d, camPos2d, t);
camera.transform.rotation = Quaternion.Lerp(camRot3d, camRot2d, t);
AddImpact(enemy.relativeVelocity * hitForce);
}
if(collision.gameObject.tag == "Dummy"&&player.animation.IsPlaying("Sailor_kick")){
enemy.transform.gameObject.animation.Play("Hit1_Reverse");
AddImpact(enemy.relativeVelocity * hitForce);
}
if(collision.gameObject.tag == "Dummy"&&player.animation.IsPlaying("Ninja_Kicks")){
enemy.transform.gameObject.animation.Play("Hit1");
mainCamera.transform.position = normtarget.transform.position - normtarget.transform.forward;
AddImpact(enemy.relativeVelocity * hitForce);
}
if(collision.gameObject.tag == "Dummy"&&player.animation.IsPlaying("Jab")){
enemy.transform.gameObject.animation.Play("Hit1");
enemy.transform.gameObject.rigidbody.AddForce(transform.forward * speed);
}
if(collision.gameObject.tag == "Dummy"&&player.animation.IsPlaying("Cross")){
enemy.transform.gameObject.animation.Play("Hit1_Reverse");
}
if(collision.gameObject.tag == "Dummy"&&player.animation.IsPlaying("Hook")){
enemy.transform.gameObject.animation.Play("Hit1");
}
if(collision.gameObject.tag == "Dummy"&&player.animation.IsPlaying("Punch4")){
enemy.transform.gameObject.animation.Play("Hit_Stomach");
}
}
Sorry i pasted the whole code i didnt want to confuse you by leaving important stuff out.
I've added a working example to my answer above. I think you'll be able to figure the rest out.