I come from the flash world and new to Unity and struggling with backgrounds in 2D for mobile. That is, struggling with understanding how to create a parallax background that will fit on all mobile devices. Actually doesn't even have to be parallax. I've read several post on the issue and tried several things but none of them work for me.
I've tried scripts that change the camera size, that scale the images etc. Outcome is never good as one scales the images and they don't look right and the other methods don't display critical parts of the background.
What have I missed with 2D backgrounds and how can I address it?
Thank-you
As you are new to Unity explaining each and everything may take brief answer.
Have a look on this script it will help you if it doesn't comment and ask.
Code :
using UnityEngine;
using System.Collections;
public class Done_BGScroller : MonoBehaviour
{
public float scrollSpeed;
public float tileSizeZ;
private Vector3 startPosition;
void Start ()
{
startPosition = transform.position;
}
void Update ()
{
float newPosition = Mathf.Repeat(Time.time * scrollSpeed, tileSizeZ);
transform.position = startPosition + Vector3.forward * newPosition;
}
}
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.
GOAL
So I have a space-invaders type game I have made to practise unity and I want to upload it to Itch.io as I have done in the past.
This is a clip of the game.
I switched platforms to WebGL in Build Settings etc, and everything worked fine in Unity.
PROBLEM
However when I built it and uploaded the zip file to Itch.io, the aliens are now a lot faster than usual. (Be aware there may be other things that have changed, I just haven't been able to get to them since it is extremely hard).
CODE
Alien movement:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class AleenController : MonoBehaviour
{
Rigidbody2D rigidbody;
public float speed = 10f;
ScoreController scoreController;
AudioSource aleenDie;
void Start()
{
scoreController = GameObject.Find("Canvas/Score").GetComponent<ScoreController>();
rigidbody = GetComponent<Rigidbody2D>();
aleenDie = GameObject.Find("Main Camera/AleenDie").GetComponent<AudioSource>();
}
void Update()
{
rigidbody.MovePosition(transform.position + new Vector3 (0, -1, 0) * speed * Time.deltaTime);
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.tag == "laser")
{
aleenDie.Play();
scoreController.score += 1;
Destroy(gameObject);
}
}
}
NOTE
I am really struggling to find out what is wrong here, since everything is fine in unity. If you do need more details just leave a comment.
If you use physics you should
not set or get values via Transform at all
do things in FixedUpdate
In general though in your case instead of using
void Update()
{
rigidbody.MovePosition(transform.position + new Vector3 (0, -1, 0) * speed * Time.deltaTime);
}
at all simply set the velocity once like e.g.
void Start ()
{
...
rigidbody.velocity = Vector3.down * speed;
}
The rest seems to depend a bit on your screen size. Looks like you are moving your elements in pixel space -> the smaller the display the less pixel distance between the top and bottom -> the faster elements seem to travel.
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.
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.
I have an issue with trying to get an 'object(character)' to walk around a cube (all sides) within Unity. Ive attached an image and video showing what i am trying to achieve. Im trying to show you visually rather than trying to explain. As the character drops over the edge it rotates 90 degrees and then the stands up like gravity has switched. Then the character can jump walk etc.
This is an example of someone else that posted a video showing exactly what im trying to achieve
I have looked through the forums and cant find what im after. i have tried to attach a diagram but the site wont let me. Any advice would be greatly appreciated!
Regards
Nick
You have a couple of options that I can think of.
One is to trigger the gravity change when the character exits one face of the cube to go to another. To achieve this you would have trigger zones on each edge and face and use a [Bob went from Face A to Edge ANorth -> Switch Gravity to go in X direction].
This would work for situations where the gravity switch must affect other objects too but be advantageous to your player (walking off the side makes an enemy fall off and die - for example.)
However, if you want all entities to stick to their relative sides then we need to make custom gravity! To do this is easier than you might think as gravity is simply a downward accelleration of 9.8. So turn off the engines native gravity and create a "personal gravity" component:
private Vector3 surfaceNormal;
private Vector3 personalNormal;
private float personalGravity = 9.8f;
private float normalSwitchRange = 5.0f;
public void Start()
{
personalNormal = transform.up; // Start with "normal" normal
rigidbody.freezeRotation = true; // turn off physics rotation
}
public void FixedUpdate()
{
// Apply force taking into account character normal as personal gravity:
rigidbody.AddForce(-personalGravity * rigidbody.mass * personalNormal);
}
Rotating your character and changing his normal is then up to you to suit your situation or game mechanic, whether you do that by raycasting if you're standing on a surface to detect when to change it or only want gravity to change when you hit a powerup or similar - experiment and see what works. Comment more if you have questions!
EDIT:
As an addition to the video you linked. You can keep a state variable on the jump state and raycast in each axis direction to check which face is nearest in the case of just rolling off.
public void Update()
{
// we don't update personal normals in the case of jumping
if(!jumping)
{
UpdatePersonalNormal();
}
}
public void UpdatePersonalNormal()
{
RaycastHit hit; //hit register
// list of valid normals to check (all 6 axis)
Ray[] rays =
{
Vector3.up, Vector3.down,
Vector3.left, Vector3.right,
Vector3.forward, Vector3.backward
};
//for each valid normal...
foreach(Ray rayDirection in rays)
{
//check if we are near a cube face...
if(Physics.Raycast(rayDirection , hit, normalSwitchRange)
{
personalNormal = hit.Normal; //set personal normal ...
return; // and return as we are done
}
}
}
Please keep in mind that the above is completely hand written and not tested but play with it and this pseudo start should give you a good idea of what to do.