I have a planet and a player moving on it using gravity. I would like to have a camera to follow the player around it. Using the Parent Constraint component works perfectly, but I want to delay the rotation follow, so I have to use a script. I just cannot figure out how to make it follow it around the globe. I either have a camera that completely freaks out, or a camera that sort of follows the player but doesn't move over the planet and always stays in front of it. And often the position following works, but as soon as I add something that changes rotation it only does that. I've tried many different scripts but nothing works. I'm grateful for any help.
EDIT
I'm sorry for not adding an example. At the moment I've tried this script attached to the camera:
public class CameraFollow : MonoBehaviour
{
public GameObject player;
private Vector3 offset;
void Start()
{
offset = transform.position - player.transform.position;
}
void LateUpdate()
{
transform.rotation = Quaternion.Slerp(transform.rotation, player.transform.rotation, 50f * Time.deltaTime);
transform.position = player.transform.position + offset;
}
The camera does mimic the rotation of the player, but the position isn't being follow correctly anymore. It seems mostly stuck in place, moving only very slightly.
In order to have a camera following a GameObject, you need to go to the camera you want following the GameObject, select Add component, write FollowPlayer, press New script, and then press select and add. Edit the script so it contains the following:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FollowPlayer : MonoBehaviour
{
public Transform player;
public Vector3 offset;
// Update is called once per frame
void Update()
{
transform.position = player.position + offset;
}
}
Then, you will need to drag and drop the GameObject you want the camera to follow, in the "Player" box.
Define the offset of the camera from the GameObject, and your'e good to go.
Related
I got an issue that I've been trying to figure out for some time now and still haven't managed. I created a script for movement which besides using the WASD keys also uses two more buttons to go up and down. The thing is - because of the way I added those buttons for some reason no other function regarding position of the player doesn't work well. For example if I put a collider with a simple on trigger transform.position function for the player to hit - the player is placed on that position but then instantly returned back like there was nothing.
Here is my code. I had tons of iterations how this movement can be done. I did it through physics and controller in several ways but nothing helped. Can you guys tell me if it's the code or some hidden Unity synergy that I don't know about?
(this version works around addForce. Regardless, whatever way I make the up and down functions I cannot move the player with script after that.)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Mov : MonoBehaviour
{
private CharacterController controller;
private Rigidbody Rb;
private Vector3 playerVelocity;
private float playerSpeed =12;
void Start()
{
controller = gameObject.AddComponent<CharacterController>();
Rb = gameObject.GetComponent<Rigidbody>();
}
// Update is called once per frame
void FixedUpdate()
{
Vector3 move = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
Vector3 add =new Vector3 (0, playerSpeed, 0);
controller.Move(move * Time.deltaTime * playerSpeed);
if (Input.GetKey(KeyCode.Mouse1))
{
Rb.AddForce(0, 1200, 0, ForceMode.Acceleration);
}
if (Input.GetKey(KeyCode.Mouse0))
{
Rb.AddForce(0, -1200, 0, ForceMode.Acceleration);
}
}
}
I'm not sure what you mean by "no other function regarding position of the player doesn't work well" but from have you turning "Collision Detection" in your Rigidbody's settings to "Continuous" and "Interpolate" to "Interpolate"? If you don't do so, Unity's collision's may be a bit funky especially if you are going at high speeds.
VIDEO < in the video I have a walking particles that appear when ever my player moves left and right but I want them to be destroyed after the particles are finished fading away I tried using stop action in unity but that only destroyes the finish particles when the player stops moving and after that the particles will
stop showing up
these are my dublicated particles that will stay in my game forever and cause lag later on I need a way to stop showing them when they are done
IMAGE < the inspector of my particles
image < the name of my particles
is there a way I could some how in my code check if the particle is faded away or check if its finished and then destroy those because sometimes with the destroy it will destroy everything and the particles wont show up if I walk again
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class partscript2 : MonoBehaviour
{
public Joystick joystick2;
public GameObject hays2;
public Rigidbody2D rb;
float horizontalMove = 0f;
// public bool show = true;
public Animator animator3;
// public Transform player;
//public Transform particleposition;
// Start is called before the first frame update
void Start()
{
//transform.position = particleposition.position;
animator3 = GetComponent<Animator>();
//Destroy(gameObject, 1f);
}
//destroy(hays);
// Update is called once per frame
void Update()
{
if (joystick2.Horizontal <= -.2f)
{
Instantiate(hays2, transform.position, hays2.transform.rotation);
}
if (joystick2.Horizontal >= .2f)
{
Instantiate(hays2, transform.position, hays2.transform.rotation);
}
}
}
Firstly, instantiating a game object in update is not the best way to go considering that if your game runs at 60 frames per second you will end up creating 60 game objects each second which can and most likely will affect performance especially on a mobile device which you are working.
But into the point, you can call the Destroy method and pass the duration of the particle.
GameObject hay = Instantiate(hays2, transform.position, hays2.transform.rotation);
ParticleSystem p = hay.GetComponent<ParticleSystem>();
float duration = p.duration + p.startLifetime;
Destroy(hay , duration);
If your particle's duration is fixed you can always skip the part where we get the duration via script and simply pass it in the Destroy method.
GameObject hay = Instantiate(hays2, transform.position, hays2.transform.rotation);
Destroy(hay , 5f);
I'm trying to learn Unity by myself. I'm recreating pong in 3d with Unity objects. I started a few minutes ago and every time I throw any input into the pad its y coordinate shifts to 2.6, I have no idea why. Can someone help?
public class PadMovement : MonoBehaviour {
private CharacterController pad;
private Vector3 direction;
private Vector3 movement;
[SerializeField] private float speed = 50.0f;
// Use this for initialization
void Start() {
pad = GetComponent<CharacterController>();
}
// Update is called once per frame
void Update() {
direction = new Vector3(Input.GetAxis("Horizontal"), 0, 0);
movement = direction * speed;
pad.Move(movement * Time.deltaTime);
}
}
SOLVED: there was a capsule collider out of place!
Afternoon, I recently copied your code into a 'Unity3d', ".cs", File and actually I created a cube and placed my game into a 2d mode, After this I named my file "PadMovement", after that I dragged it onto my newly created cube, Once I had done that I tried to click play and noticed that my cube didn't have a "CharacterController", attached to my cube, Once I had done that and clicked play I was eligible to have my "paddle", smoothly move around the screen # 50.0f along the X axis.
Knowingly, My Input came from the "Character Controller", My Speed came from the Serial field you had for speed!
Do you by any chance have a CapsuleCollider Component or some other collider on the same GameObject that you have this PadMovement Component on? That sounds like a height where it might just be trying to pop the object out of ground collision.
It should be harmless if that's all it is. If you really want an object to be at y of 0 you can attach it to a parent object and have that parent stay at 0.
I am very new to Unity and just got done yesterday following the Roller Ball example on the learn page here at Unity3d.
To practice what I have learned I wanted to try and recreate something similar using my own art and making the game different. I have been playing around with Voxel Art and I am using MagicaVoxel to create my assests. I created the walls, the ground etc.. and all is well.
Then came the player object, the sphere. I created one as close to a sphere as possible with magicaVoxel and it rolls fine. However, when using a script to have the camera follow the object it runs into issues.
If I don't constrain the Y axis then I will get bouncing and as far as the x and z axis I get kind of a Flat Tire effect. Basically the camera doesn't follow smoothly it bounces around, stop go etc...
I have tried making the collider larger then the sphere and even using the position of the collider vs the object itself. I have also tried putting the code in Update / FixedUpdate / LateUpdate. What is the proper way to fix or address something like this? Here is my scripts below:
Camera Controller:
public class CamController : MonoBehaviour {
public GameObject player;
private Vector3 offset;
void Start ()
{
// Get the distance between the player ball and camera.
offset = this.transform.position - player.transform.position;
}
void LateUpdate ()
{
this.transform.position = player.transform.position + offset;
}
}
Player Controller:
public class PlayerController : MonoBehaviour {
public float _speed;
void FixedUpdate()
{
// Get input from keyboard.
float _hoz = Input.GetAxis("Horizontal");
float _ver = Input.GetAxis("Vertical");
// Create a vector3 based on input from keyboard.
Vector3 _move = new Vector3(_hoz, 0.0f, _ver);
// Apply force to the voxel ball
this.GetComponent<Rigidbody>().AddForce(_move * _speed);
}
}
Thanks for any help in advance.
You can use the SmoothFollow Script of Unity it self for getting smooth follow of camera.
Here are the steps how you can get the script:
1) Assets->Import Package->Scripts.
2) At the dialog that appears select all the scripts, or just the smooth follow one and hit Import button.
3) Now this script is in your project, and you can attach it to the camera.
Hope this will help you...
Best,
Hardik.
How do we achieve a control similar to this game?
https://play.google.com/store/apps/details?id=com.fridgecat.android.atiltlite&hl=en
You can do this with builtin physics:
create a level from some simple scaled cubes (don't forget the ground).
add the ball - a sphere, then and add a RigidBody to it. Set a constraint on the rigidbody - check freeze position y (or it will be able to jump out of the level if you put the device upside down).
add this script anywhere on the scene (for example to the camera):
using UnityEngine;
public class GravityFromAccelerometer : MonoBehaviour {
// gravity constant
public float g=9.8f;
void Update() {
// normalize axis
Physics.gravity=new Vector3(
Input.acceleration.x,
Input.acceleration.z,
Input.acceleration.y
)*g;
}
}
or if you want the physics to just affect this one object, add this script to the object and turn off it's rigidbody's affected by gravity:
using UnityEngine;
[RequireComponent(typeof(Rigidbody))]
public class ForceFromAccelerometer : MonoBehaviour {
// gravity constant
public float g=9.8f;
void FixedUpdate() {
// normalize axis
var gravity = new Vector3 (
Input.acceleration.x,
Input.acceleration.z,
Input.acceleration.y
) * g;
GetComponent<Rigidbody>().AddForce (gravity, ForceMode.Acceleration);
}
}
And now you have working ball physics. To make the ball behave as you'd like, try to play with the rigidbody properties. For example, change the drag to something like 0.1.