Orbiting target with camera and changing height - unity3d

I want to be able to use joystick (left-right) to make the camera orbit around target. I have this handled with the code below:
using UnityEngine;
using System.Collections;
using UnityStandardAssets.CrossPlatformInput;
public class OrbitCamera : MonoBehaviour {
public Transform target;
public float turnSpeed;
public float height;
public float distance;
private Vector3 offsetX;
void Start()
{
offsetX = new Vector3 (0, height, distance);
}
void LateUpdate()
{
offsetX = Quaternion.AngleAxis (CrossPlatformInputManager.GetAxis ("hOrbit") * turnSpeed, Vector3.down) * offsetX;
transform.position = target.position + offsetX;
transform.LookAt (target.position);
}
}
I need to extend this script so that the player can move camera also up and down using the same joystick. So what I want is the camera to be able to move around player in a shape of sphere, always looking at the player. Thanks in advance.

Use a boom camera
A boom camera is wonderfully easy to setup and has a range of convenient cinematic controls:
To set it up, you simply create a new game object which we'll call the dolly. You then simply parent the camera to the dolly and tidy up the positions and rotations:
Camera
Transform: 0,0,-distance
Rotation: 0,0,0
Dolly
Transform: 0,height,0
Rotation: 0,0,0
Why a boom camera is great
Rotate the dolly on x and y and you'll get the camera moving in a sphere. (Note that dragging the rotation gizmo in scene view doesn't show the effect properly because of axis alignment; edit the x/y rotation values in the inspector only).
That -distance z value is the zoom. Change the local position of the camera to zoom in/out.
Local rotating the camera gives interesting tilt/pan effects.
Making it work in your case
You'd attach the script to the dolly gameobject, then use the joystick input to rotate it on x/y:
using UnityEngine;
using System.Collections;
using UnityStandardAssets.CrossPlatformInput;
public class OrbitCamera : MonoBehaviour {
// Height and distance are now set in the scene (by positioning the dolly and changing that camera z value).
public float turnSpeed;
private float horizontal;
private float vertical;
void LateUpdate()
{
// Update horizontal/ vertical angles:
horizontal += CrossPlatformInputManager.GetAxis ("hOrbit") * turnSpeed;
vertical += CrossPlatformInputManager.GetAxis ("vOrbit") * turnSpeed;
// Update the rotation:
transform.rotation = Quaternion.Euler(horizontal, vertical, 0f);
}
}

Related

Canvas rotating when I change it to worldSpace, Unity

I've got a canvas that changes from Overlay to worldSpace when an event occurs, but when it changes to Overlay from worldSpace, the rotation of the canvas is changed, which I don't want it to be.
Images:
As you can see in the order that the images are, it starts with no rotation in worldSpace, then the event occurs changes it to overlay and the rotation is now 140, after the event and I'm back in worldSpace, it is still 140 degrees.
I don't know what is wrong with this. Please help if you can
This happens because, internally, the Canvas is being transformed into camera space when set to Overlay. That's how it renders. Your solution would be to cache the transform before changing the Render Mode.
Something like this, given a component:
using UnityEngine;
[RequireComponent(typeof(Canvas))]
public class CanvasRenderModeSwitcher : MonoBehaviour
{
private Canvas canvas;
private Vector3 position;
private Vector3 scale;
private Quaternion rotation;
private void OnEnable()
{
canvas = GetComponent<Canvas>();
}
public void SetRenderMode(RenderMode renderMode)
{
if (renderMode == RenderMode.WorldSpace)
{
// Set the render mode before values are reset.
canvas.renderMode = renderMode;
// Restore the values.
transform.position = position;
transform.rotation = rotation;
transform.localScale = scale;
}
else
{
// Cache the values.
position = transform.position;
rotation = transform.rotation;
scale = transform.localScale;
// Set the render mode after values are cached.
canvas.renderMode = renderMode;
}
}
}

How to make limited camera movement in Unity C#

I am making a FNAF fan game using Unity, and I need limited camera movement, like shown in this video. I've been trying to figure this out but I found no tutorials nor any answers. If you could link a script for this I would be very greatful!
https://vimeo.com/710535461
Attach this code to the camera and you can limit the camera movement by setting two angles in the inspector. Remember that this code limits localEulerAngles values and always must set the camera rotation to zero, To adjust its rotation, place the camera as child of an empty object and then rotate the parent.
public class LimitedCamera : MonoBehaviour
{
public float LimitAngleX = 10f;
public float LimitAngleY = 10f;
private float AngleX;
private float AngleY;
public void Update()
{
var angles = transform.localEulerAngles;
var xAxis = Input.GetAxis("Mouse X");
var yAxis = Input.GetAxis("Mouse Y");
AngleX = Mathf.Clamp (AngleX-yAxis, -LimitAngleX, LimitAngleX);
AngleY = Mathf.Clamp (AngleY+xAxis, -LimitAngleY, LimitAngleY);
angles.x = AngleX;
angles.y = AngleY;
transform.localRotation = Quaternion.Euler (angles);
transform.localEulerAngles = angles;
}
}

the GameObject rotates incorrectly on the z-axis

there is a circle, it needs to be rotated by pressing the button, with a certain speed along the z axis, and when it turns 90, the rotation will stop, but for some reason the rotation is not working properly
public GameObject Circle;
private bool RotationActive;
//rotation value at which the circle stops rotation
private float RotatePost;
private float RotationSpeed;
private float CircleRotateZ;
void Start()
{
RotationActive = false;
RotationSpeed = 0.5f;
RotatePost = 90;
}
//function is bound to a button
public void RotateActive(){
RotationActive = true;
}
void FixedUpdate()
{
if (RotationActive == true)
{
CircleRotateZ = Circle.transform.rotation.z;
//if the circle along the z axis is rotated more than Rotation Post...
if (CircleRotateZ >= RotatePost )
{
RotatePost = CircleRotateZ + 90;
RotationActive = false;
}
//assignment of a new coordinate
Circle.transform.Rotate(new Vector3(0,0,RotationSpeed + CircleRotateZ));
}
}
You are trying to grab the rotation from the Quaternion which is not the angle of the object. Instead you should use:
CircleRotateZ = Circle.transform.eulerAngles.z;
Also the way you are currently rotating will make it speed up over time. The Rotate functions rotates the object by the amount, not to the amount given, so if you only want to rotate by the rotation speed you should use:
Circle.transform.Rotate(new Vector3(0, 0, RotationSpeed));
What do you mean by not working properly. You mean it doesn't move at all? If it doesn't move at all, check if you dragged the circle game object to the game object field in the Inspector. One more thing, why didn't you call the 'RotateActive' function?

I'm trying to rotate my character to face the mouse position, only works relative to Transform: (0,0,0)

Character rotation, only happens when mouse is rotated around world centre (0,0,0) -
The MoveToMouse() works perfectly, click on a point in the world, and the player moves, and camera follows.
But when holding shift to rotate the character to where mouse is pointing, it only points relative to the world centre.
transform.LookAt - works perfectly, but I want to be able to smooth the rotation.
using UnityEngine;
using UnityEngine.AI;
public class ClickToMove : MonoBehaviour
{
NavMeshAgent player;
public float rotSpeed = 10f;
void Start()
{
player = GetComponent<NavMeshAgent>();
}
void Update()
{
MoveToMouse();
LookAtMouse();
}
void MoveToMouse()
{
if (Input.GetMouseButtonDown(1))
{
RaycastHit hit;
if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 100))
{
player.destination = hit.point;
}
}
}
void LookAtMouse()
{
if (Input.GetKey(KeyCode.LeftShift))
{
RaycastHit lookHit;
Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out lookHit, 100);
//transform.LookAt - works perfectly, but want to be able to smooth the rotation.
//transform.LookAt(lookHit.point);
transform.rotation = Quaternion.Slerp(transform.rotation,
Quaternion.LookRotation(lookHit.point), rotSpeed * Time.deltaTime);
}
}
}
Quaternion.LookRotation takes directional Vector as a parameter not a position.

unity3d: Camera does not follow the player

I am fairly new in game development, I have a piece of code that makes camera move based on player's movement.
player's movement script:
using UnityEngine;
using System.Collections;
public class PlayerMovement : MonoBehaviour
{
public float speed = 6f;
//to store movement
Vector3 movement;
Rigidbody playerRigidbody;
int floorMask;
float camRayLenghth = 100f;
//gets called regardless if the script is enabled or not
void Awake(){
floorMask = LayerMask.GetMask ("Floor");
playerRigidbody = GetComponent<Rigidbody> ();
//Input.ResetInputAxes ();
}
//unity calls automatically on every script and fire any physics object
void FixedUpdate(){
float h = Input.GetAxisRaw ("Horizontal");
float v = Input.GetAxisRaw ("Vertical");
Move (h, v);
//Rotate ();
Turning ();
}
void Move(float h, float v){
movement.Set (h,0f,v);
movement = movement.normalized * speed * Time.deltaTime;
playerRigidbody.MovePosition (transform.position + movement);
}
void Turning (){
Ray camRay = Camera.main.ScreenPointToRay (Input.mousePosition);
RaycastHit floorHit;
if (Physics.Raycast (camRay,out floorHit,camRayLenghth,floorMask)) {
Vector3 playerToMouse = floorHit.point - transform.position;
playerToMouse.y = 0f;
Quaternion newRotation = Quaternion.LookRotation (playerToMouse);
playerRigidbody.MoveRotation (newRotation);
}
}
}
and here is the script attached to the main camera:
using UnityEngine;
using System.Collections;
public class CameraFollow : MonoBehaviour {
// a target for camera to follow
public Transform player;
// how fast the camera moves
public float smoothing = 4f;
//the initial offset from the target
Vector3 offset;
void start(){
//calculation of initial offset (distance) between player and camera
offset = transform.position - player.position;
Debug.Log ("offset is " + offset);
}
void FixedUpdate (){
//updates the position of the camera based on the player's position and offset
Vector3 playerCameraPosition = player.position + offset;
//make an smooth transfer of location of camera using lerp
transform.position = Vector3.Lerp(transform.position, playerCameraPosition, smoothing * Time.deltaTime);
}
}
but when I attach the script to my main camera, as soon as I play test the game camera starts to relocate and moves towards the ground even though the player hasn't moved yet. If I remove the script from the camera and make the camera the child of the player, as soon as I hit play, camera starts to rotate around the object.
Please give me some hints what am I doing wrong ?
The camera offset isn't being set because of the lower case on your start method. This means the offset remains at its default value which is 0,0,0 causing your camera to move to some funky place.
Change: `
void start() {
...
}
to
void Start() {
...
}
see you don't need any code for this just make you camera a child of your player object..
drag you camera object onto the player object in hierarchy