how to get background to scroll with player height in unity? - unity3d

I am making an endless jumper. I am trying to get the BG to scroll down based on the players height.
I have seen code that moves the code at a specific speed:
public float speed = .5f;
void Updated(){
Vector2 offset = new Vector2(0, Time.deltatime * speed);
GetComponent<Renderer>().material.mainTextureOffset = offset;
}
I want to move it with the height of the player.
public float PlayerHeight;
So now I need to set the height of the BG. I can't figure out how to do this part.
Transform background;
public float backgroundHeightY;
public GameObject BackGround;
from here I am stuck. I don't want it to move with the camera, but move at a certain rate based on the height of the player. Any help would be awesome.

It sounds like you have a background that has a fixed position relative to the camera, but you want the background to scroll "against" the player as they move up and down, giving a parallax effect?
public Transform player;
public float multiplier = 0.1f; //Tweak this
void Update(){
Vector2 offset = new Vector2(0, player.position.y * multiplier);
GetComponent<Renderer>().material.mainTextureOffset = offset;
}

I have it working well going up, but not down. Here is how it is working going up. I have adjusted the backgroundModifier to fit the timing I need.
//Changes the BG position
changeAmount = (playerHeightY - currentCameraHeight)/backgroundModifier;
Vector3 temp = new Vector3(0, changeAmount, 0);
BackGround.transform.position += temp;
Anyone have an idea on how to get the falling to work. I feel like I am making this harder than it needs to be.

Here is how I finally did this. I actually switched the camera from orthographic to perspective. It took a lot of tweaking to layout, but it ended up working perfectly well. So the code I have above I deleted.

Related

Detect collisions between 2 objects

I'm trying to do a little game on mobile using Unity and I've got a problem with the rotation of a maze.
To add context :
When your moving your finger on the screen, the maze is rotating on himself. There is a ball in it and you need to make it go on a cell to win the level.
When the maze is rotating too fast, the ball falls down and go through the ground and I don't know how to fix it.
I tried to play with the gravity, colliders...
This is the same when the ball is jumping (when the maze is going up and down quickly).
For the moment I just reset the ball position when you're falling.
{
ball.transform.position = new Vector3(0, 2, 0);
maze.transform.position = Vector3.zero;
maze.transform.rotation = Quaternion.identity;
}
Do you guys have some ideas ? Thanks
I had a similar problem in a tilt maze mini-game I worked on. Ideally implementing jkimishere's solution will work but I assume the maze is moving too fast for the collisions to register properly. You'll need to smooth the maze's rotation with a Lerp. In our case we had pressure plates with a tilt value, so it doesn't directly translate to your mobile use but perhaps give you a nudge in the right direction. We used:
public GameObject maze;
private float _lerpTime;
private bool _isRotating;
private Quaternion _startingRot, _desiredRot;
private void Awake()
{
_startingRot = maze.transform.localRotation;
}
private void Update()
{
//Don't want to move the maze if we don't ask for it
if(!_isRotating)
return;
//Lerp the maze's rotation
_lerpTime = Mathf.Clamp(_lerpTime + Time.deltaTime * 0.5f, 0f, 1f);
maze.transform.localRotation = Quaternion.Lerp(_startingRot, _desiredRot, _lerpTime);
//Once the maze gets where it needs to be, stop moving it
if(affectedObject.transform.localRotation.Equals(_desiredRot)
_isRotating = false;
}
private void ActivateTilt()
{
//Set the new starting point of the rotation.
_startingRot = maze.transform.localRotation;
//However you want to calculate the desired rotation here
//Reset our lerp and start rotating again
_lerpTime = 0f;
_isRotating = true;
}
This will ease the rotation of your maze over time. So that the ball can adapt to the new collider positions.
In the rigidbody(for the ball), make the collision detection to continuous, and in the rigidbody for the maze(if you have one) set the collision detection to continuous dynamic. Hope this helps!
I think that is unavoidable if you allow the player to move the platform freely. I suggest you restrain the speed at wich the player can tilt the platform. This way, the ball will have more frames to adapt to the new slope

Player stops move the character direction resets [Unity 2D]

My character is a car and I try to rotate it the direction it move, so far so good I succeeded to do that but once I stop moving the character flips back to the direction it was on the start.
Also how can I make my turns from side to the opposite site smooth ?
Here is my code so far:
[SerializeField] float driveSpeed = 5f;
//state
Rigidbody2D myRigidbody;
// Start is called before the first frame update
void Start()
{
myRigidbody = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
Move();
}
private void Move()
{
//Control of velocity of the car
float HorizontalcontrolThrow = CrossPlatformInputManager.GetAxis("Horizontal"); // Value between -1 to 1
float VerticalcontrolThrow = CrossPlatformInputManager.GetAxis("Vertical"); // Value between -1 to 1
Vector2 playerVelocity = new Vector2(HorizontalcontrolThrow * driveSpeed, VerticalcontrolThrow * driveSpeed);
myRigidbody.velocity =playerVelocity;
**//Direction of the car**
Vector2 direction = new Vector2(HorizontalcontrolThrow, VerticalcontrolThrow);
float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
myRigidbody.rotation = angle;
}
I'm not sure about this, but maybe that last line "myRigidbody.rotation = angle" being called every frame is what is making your car reset its rotation.
Maybe change it to "myRigidbody.rotation *= angle" or "myRigidbody.rotation += angle".
It looks like it may be because HorizontalcontrolThrow and VerticalcontrolThrow are going to be reset when you release the controls. If it's resetting to its original orientation, then what's happening is that until you move, those two values are going to be at their default value. You then move and it affects the rotation. But when you release the controls, those values are back to the starting values again, and so is your rotation.
What you therefore need to do is try to separate the HorizontalcontrolThrow and VerticalcontrolThrow from the rest of the code, which should only be activated when at least one of these two variables are not at their default setting (I can't remember what the axis functions return at the moment).
Edit:
An IF statement should suffice (some rough pseudo code):
if (horizontalAxis != default || verticalAxis != default)
{
Rotate/Move
}
I solved the snap rotation using Quaternion at rotation, the issiu I had with it was to convert it from 3d to 2d, through the guide of this clip: youtube.com/watch?v=mKLp-2iseDc and made my adjustments it works just fine !

Unity3d Linerenderer not visible

I am trying to draw a line between two UI GameObjects with Linerenderer. In scene mode everything work fine, but in game mode line is invisible. I tried to change Z position of objects but lines are still invisible. Can anyone help me? Thanks in advance
private LineRenderer lineRenderer;
private float counter;
private float dist;
private Vector3 aPos;
private Vector3 bPos;
public Transform origin;
public Transform destination;
public float lineDrawSpeed = 6f;
// Use this for initialization
void Start()
{
lineRenderer = GetComponent<LineRenderer>();
aPos = new Vector3(origin.position.x, origin.position.y, origin.position.z); // Using these to move the lines back
bPos = new Vector3(destination.position.x, destination.position.y, destination.position.z);
lineRenderer.SetPosition(0, aPos);
lineRenderer.SetWidth(3f, 3f);
dist = Vector3.Distance(origin.position, destination.position);
}
// Update is called once per frame
void Update()
{
if (counter < dist)
{
counter += .1f / lineDrawSpeed;
float x = Mathf.Lerp(0, dist, counter);
Vector3 pointA = aPos;
Vector3 pointB = bPos;
Vector3 pointAloneLine = x * Vector3.Normalize(pointB - pointA) + pointA;
lineRenderer.SetPosition(1, pointAloneLine);
}
}
Unless I'm overlooking some logic error in the code you've posted, I think the problem might be with the material.
Generic debugging help for line renderers:
Try setting the color/material of the line renderer:
lineRenderer.sortingOrder = 1;
lineRenderer.material = new Material (Shader.Find ("Sprites/Default"));
lineRenderer.material.color = Color.red;
If that doesn't work, perhaps you need to specify the number of vertexes manually?
mineLaser.SetVertexCount (2);
Finally, if these both don't work, it might just be a logic error; try setting the transforms for the lineRenderer's position to be some predefined value and see if it shows up.
For this specific question:
Ah, so its on a canvas. Assuming you mean the UI canvas, I believe linerenderer is the wrong tool to use in this situation. Check out this question.
One of the answers there suggests to:
just use a panel filled with any color you want and use Height and Width to set the length and the Width of your line
This is impossible in "Screen Space - Overlay" Canvas mode. In that mode UI overlay draws on top of everything in Scene (including LineRenderer, that actually non UI element).
Try to use "Screen Space - Camera" option for your Canvas and "Use World Space" option for you Line Renderer.
I think you must have forgotten to set sorting layer for the line renderer. As this could only be the possible reason if the line is visible in the scene view and not in the game view.

Camera Move and Rotate Follow Player very jerky

I make a character move on the surface of a circle. I let the camera move and rotate follow character. But the camera move and rotate very jerky. If I increase the value of the third parameter, the shock increases. and to reduce the value of the third parameter, the camera does not rotate to keep up the character. Help me fix it
My Code Camera Follow Player
public class CameraFollow : MonoBehaviour
{
public Transform player;
GameController gc;
public float speed = 2;
Vector3 pos = new Vector3 (0, 0, -10);
// Use this for initialization
void Start ()
{
gc = FindObjectOfType (typeof(GameController)) as GameController;
}
void FixedUpdate ()
{
if (gc.gameState == GameController.GameState.playing || gc.gameState == GameController.GameState.changeWave) {
transform.position = player.position + pos;
transform.rotation = Quaternion.Slerp (transform.rotation,
player.transform.rotation,
speed * Time.deltaTime);
}
}
}
Setting the position of a transform inside of FixedUpdate is a red flag for sure, especially when you're reporting that it's "jerky". Fixed update happens at an irregular interval compared to the frames displayed. This is because Physics needs to update using a fixed time step. The reason why this is the case is out of scope for this question.
Long story short, try changing FixedUpdate to Update and that should fix things looking "jerky".
Let me know if this doesn't work and I'll look for other possible causes.
If you are using a Rigidbody2D to move the character, make sure to set its Interpolate property to 'Interpolate'. This should fix it.

visual lag of the moving picture in Unity3D. How to make it smoother?

I make a game in Unity3D (+2D ToolKit) for iOS.
It is 2d runner/platformer with side view. So on screen is moving background and obstacles. And we control up/down the main character to overcome obstacles.
The problem is that the moving picture has a visual lag. In other words, it moves jerkily or creates the tail area of the previous frames on iOS-devices. In XCode the number of frames is 30 and over.
I have objects 'plain' with the following script:
public class Move: Monobehavior
{
private float x;
public float Speed = 128.0f;
void Start()
{
x = transform.position.x;
}
void Update()
{
x += Time.DeltaTime *Speed;
Vector3 N = transform.position;
N.x = mathf.FloorInt(x);
transform.position = N;
}
}
The question is how to make the move of background smoother, without jerks and flicker on screen while playing? Maybe the problem is in framerate parameter.
Can anybody help me to find a solution?
I'd say it's the use of the FloorInt function which will move the background only in steps of 1 which is rather not smooth. It should get better when you comment that line out. Do you have any special reason why you are doing the FloorInt there?
The use of floor will definitely hurt your performance. Not only is it one more thing to calculate, but it is actually removing fidelity by removing decimals. This will definalty make the movement look 'jerky'. Also, update is not always called on the same time inteval, depending on what else is happening during that frame, so using Time.delaTime is highly recommended. Another thing, you do not need to set variables for x and Vector3 N, when you can update the transoms position like the code below. And if you have to, you sill only need to create one variable to update, and set your position to it. The code below just updates the players x position at a given rate, based on the amount of time that has passes since the last update. There should be no 'jerky' movement. (Unless you have a serious framerate drop);
public class Move: Monobehavior
{
public float Speed = 128.0f;
void Update()
{
transform.position =
(transform.position.x + (speed*Time.DeltaTime),
transform.position.y,
transform.position.z);
}
}