When I use LookAt the camera seems to look at the targets feet. I would like the target to be closer to the bottom of the screen. (e.g. look at the head instead).
Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ThirdPersonCamera : MonoBehaviour
{
private GameObject player;
private void Start()
{
player = GameObject.FindWithTag("Player");
}
private void LateUpdate()
{
Vector3 offset = new Vector3(0,2.0f,-4.0f);
transform.position = player.transform.position + offset;
transform.LookAt(player.transform.position);
}
}
How can I make it so the camera stop centering at the feet?
I created an empty game object as a child of the player, and then adjusted the position of that. Then in my script I set it to look at that empty object instead of the player. This gives me full control of what position the camera looks at on the player.
Related
In my game on unity 2d I have spaceship and a planet. The planet is orbiting a star so I made a script that parents the planet to the player when I get within a range so the planet doesn't fly past or into the player. This script makes the player move with the planet so they land on it and fly around it easily.
Here is the script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ParentPlayer : MonoBehaviour
{
[SerializeField] GameObject Player;
private float Dist;
[SerializeField] float Threshold;
private CircleCollider2D ParentTrigger;
// Start is called before the first frame update
void Start()
{
ParentTrigger = GetComponents<CircleCollider2D>()[1];
ParentTrigger.isTrigger = true;
ParentTrigger.radius = Threshold / transform.localScale.x;
}
// Update is called once per frame
void Update()
{
}
private void OnTriggerEnter2D(Collider2D collider)
{
if(collider.gameObject == Player)
{
collider.gameObject.transform.SetParent(transform);
}
}
private void OnTriggerExit2D(Collider2D collider)
{
if(collider.gameObject == Player)
{
collider.gameObject.transform.SetParent(null);
}
}
void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, Threshold);
}
}
The problem is that as the planet rotates it ends up moving the player that has been parented to it. How can I make the planet's rotation not affect the position and rotation of the player, but still make the planets position affect the position of the player?
This might not be what you're looking for but I'm going to add it reguardless. Given that the Child-object will follow the parent, I would suggest putting the planet and spaceship as a child of the empty gameobject. Then you could rotate the the planet object, and if planets are in movement, you could add the movement to the parent object.
How about instead of parenting the player, write a script to set its position to the planets + some offset, and then the rotation wouldn't be an issue. Alternatively, if the player doesn't rotate at all, add constraints to its Rigidbody. Maybe something like this:
player.transform.position = planet.transform.position + offset;
Hope that works!
I am working on a 3D, top-down, voxel, spaceship arena shooter (mnk, gamepad) with a static camera.
I am moving the spaceship with WASD and want it to rotate with my mouse input on its Y-axis.
For that, I want to create an invisible circle that stays in the middle of the screen that the cursor can't leave. Based on the position of the cursor in the circle I want to rotate my spaceship independent from where the ship is.
Diagram for clarification
I don't know how to calculate this angle and apply it to the rotation of my ship or even how to create such circle with the limited cursor movement. I want to add a crosshair in the end and I use the new input system (if that's relevant).
So far my code for the movement looks like this:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class MovementBehaviour : MonoBehaviour
{
private Rigidbody sphereRigbod;
private PlayerInput playerInput;
private PlayerInputActions playerInputActions;
private Camera mainCamera;
public WeaponBehaviour weapon;
public Vector3 playerRotation;
[SerializeField] private float speed = 70f;
private void Awake()
{
sphereRigbod = GetComponent<Rigidbody>();
playerInput = GetComponent<PlayerInput>();
playerInputActions = new PlayerInputActions();
playerInputActions.PlayerMovement.Enable(); //Enables EVERY Action map set up!
mainCamera = FindObjectOfType<Camera>();
}
private void FixedUpdate()
{
//X Z Movement WASD
Vector2 inputVector = playerInputActions.PlayerMovement.Movement.ReadValue<Vector2>();
sphereRigbod.AddForce(new Vector3(inputVector.x, 0, inputVector.y) * speed, ForceMode.Force);
}
}
This is what my movement looks like at the moment.
Edit: made this ugly animation for further clarification.
I have a script that controls camera. Here is the script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraController : MonoBehaviour
{
public GameObject player;
private Vector3 offset;
// Start is called before the first frame update
void Start()
{
offset = transform.position - player.transform.position;
}
// Update is called once per frame
void LateUpdate()
{
transform.position = player.transform.position + offset;
}
}
I drag and drop script to camera, it it works. But I have not added any variable for camera, so unable to understand how it is controlling camera?
e.g. player.transform.position >> This is position of player.
but transform.position >> this is controlling the camera. How? Shouldn't it be something like camera.transform.position?
transform.position is the transform.position of the game object to which the script is attached.
Here the script is attached to the Camera game object, so transform.position is the position of the Camera game object.
I'm moving a player around the inside of a hollow sphere equipped with a non-convex mesh-collider. The player is meant to walk along the inner surface of the sphere with a gravitational pull towards the ship hull (away from the center). For the gravity, I've attached a modified version of this script to the player:
using UnityEngine;
using System.Collections;
public class Gravity : MonoBehaviour
{
//credit some: podperson
public Transform planet;
public bool AlignToPlanet;
public float gravityConstant = -9.8f;
void Start()
{
}
void FixedUpdate()
{
Vector3 toCenter = planet.position - transform.position;
toCenter.Normalize();
GetComponent<Rigidbody>().AddForce(toCenter * gravityConstant, ForceMode.Acceleration);
if (AlignToPlanet)
{
Quaternion q = Quaternion.FromToRotation(-transform.up, -toCenter);
q = q * transform.rotation;
transform.rotation = Quaternion.Slerp(transform.rotation, q, 1);
}
}
}
Unity's default movement controllers don't seem to work with this Gravity script, so I fashioned a simple one (forward/backward movement only):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
public class NewController : MonoBehaviour {
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
}
private void FixedUpdate()
{
GetComponent<Rigidbody>().AddForce(transform.forward * CrossPlatformInputManager.GetAxis("Vertical"), ForceMode.Impulse);
}
}
It works in that I'm able to walk around the inside of the sphere. It's very bumpy though, presumably because the forward force causes the player to constantly run into the corners/edges of the sphere polygon, and because these incongruities are not corrected quickly enough by the "AlignToPlanet" Quaternion in the gravity script.
To sum up, I need a way to move smoothly along the inside of the sphere. I'm not sure if this needs to be solved with code or values in the Unity Editor (regard drag, etc.).
So, i'm building a 3D runner and i've got a lot of problems making the camera following the ball. I've been on google for a few hours and can't find anything that's not outdated or fills in the things I need. I want a camera that follows my ball but goes straight in the X-axis. When there are the stairs the camera needs to follow on Y axis.
I just don't want my camera to rotate (since my object is a rolling ball) and to move in the Z-axis.
var myPos : Vector3;
var myPlay : Transform;
function Update()
{
transform.position = myPlay.position + myPos;
}
This is what I already have. It doesn't rotate, but it follows on the Z-axis. I don't want that.
http://prntscr.com/9pmypz This is what it looks like in the Inspector.
As per Unity3D's Roll-A-Ball tutorial:
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;
}
}
I can't comment #HDL_CinC_Dragon answer because of my low reputation, but I wanted to add that using the public access modifier is a really bad habit. Instead you should use the private access modifier with the SerializeField attribute on the field, like this:
public class CameraController : MonoBehaviour
{
[SerializeField]
private GameObject player;
private Vector3 offset;