Object Generation Gaps - unity3d

Help me understand what the problem is in Unity3D.
I generate an infinite number of blocks in motion.
But the higher the speed of movement, the larger the gap between objects. As far as I understand, the gap will be sampled due to the frame refresh time.
How to generate objects close to each other?
void Update()
{
if (startspawn)
{
spawn1 = Instantiate(spawner);
spawn1.GetComponent<Rigidbody>().velocity = new Vector3(15, 0, 0);
startspawn = false;
}
if (spawn1.transform.position.x - startcoordinateX > size)
{
spawn2 = Instantiate(spawner);
spawn2.GetComponent<Rigidbody>().velocity = new Vector3(15, 0, 0);
spawn1 = spawn2;
}
}
Screenshot

Use FixedUpdate instead of Update. FixedUpdate ensures the time between calls is the same. You can read more about it here: https://docs.unity3d.com/ScriptReference/MonoBehaviour.FixedUpdate.html.

I'll leave it here.
Managed to solve the problem by simple binding to Time.deltaTime.
Now, even at high speed, there are no gaps.
Just use.
spawn1.GetComponent().velocity = new Vector3(speed * Time.deltaTime, 0, 0);

You can use Fixed update which makes the time between calls the same.

Related

Game only functions at 800 fps

I had a problem in my program, and at first I thought it was related to coroutines. Every script that featured a coroutine worked slower in it's entirety. I later discovered this was the case because of a difference in FPS. In the editor, the FPS was 800, while it was 60 in the build. When I changed the code, so it would be 800 in both, everything worked fine.
This fixed everything, but this feels like a weird solution. It's a very simple project, so I don't mind for now, but I'd still like to know what's going on. Any ideas?
public IEnumerator BeInvincible()
{
isInvincible = true;
for (float i = 0; i < invistime; i += invistimedelta)
{
// Alternate between 0 and 1 scale to simulate flashing
if (sprite.color == new Color(1, 1, 1, 1))
{
sprite.color = new Color(1, 0, 0, 1);
}
else
{
sprite.color = new Color(1, 1, 1, 1);
}
yield return new WaitForSecondsRealtime(invistimedelta);
}
sprite.color = new Color(1, 1, 1, 1);
isInvincible = false;
}
I use fixedupdate for movement, and update for inputs. When I put inputs in fixedupdate (50 FPS), the game reacts the bad way, even when the game runs in base 800 fps.
Bad in what way?
In any case, if there is a problem at the time of code execution
Or a direct delay in performance, most likely the problem is from here
yield return new WaitForSecondsRealtime(invistimedelta);
The execution of a coroutine can be paused at any point using the yield statement. When a yield statement is used, the coroutine pauses execution and automatically resumes at the next frame. See the Coroutines documentation for more details.
And also you can review this

Unity jagged mouse input detection

I wrote a script that writes Input.mousePosition into a file on every frame. The idea is that I want to identify which button on screen the player is trying to click before actually clicking, from the speed of the mouse basically. However, I ran into data like this:
(1113.0, 835.0, 0.0)
(1113.0, 835.0, 0.0)
(1113.0, 835.0, 0.0)
(1126.0, 835.0, 0.0)
Basically on one frame the x position is one value, a couple of frames later it's changed, but in the middle there is no gradation. While my mouse movement was continuous, if I'm to believe Unity, in the example above I hovered on 1 pixel for 3 frames then jumped 13 pixels to the right in one frame. Why is this? Is there any code to get the actual frame by frame position of the mouse?
EDIT:
Vector2 _lastPosition;
StreamWriter _mouseData;
// Start is called before the first frame update
void Start()
{
_mouseData = new StreamWriter(File.Open("sdata.txt", FileMode.Create));
}
// Update is called once per frame
void FixedUpdate()
{
_mouseData.WriteLine(Input.mousePosition.ToString());
if (Input.GetMouseButtonDown(0))
{
_mouseData.WriteLine("CLICK\n\n");
}
_lastPosition = Input.mousePosition;
}
void OnDestroy()
{
_mouseData.Close();
}
EDIT 2:
I changed the code to the following:
void FixedUpdate()
{
_mouseData.WriteLine(Vector2.SqrMagnitude(new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"))));
if (Input.GetMouseButtonDown(0))
{
_mouseData.WriteLine("CLICK\n\n");
}
}
Now I'm still getting output that's 50% 0-es and non-0 values are sprinkled in on every second row. Exceptions: a few rows where actual values are supposed to be still contain random 0-es. Now, I'm not super concerned about getting less frequent than 1/frame data, but there's no way to distinguish between these false 0-es and actual 0-es when the mouse is not moving, which is an issue.
I cannot find out from your question but I am guessing that you use the FixedUpdate() method which is unreliable in this situation. Update() is advised to use for calls that you want to execute once per frame.
EDIT:
Also, note that it is recommended that you set your application's framerate to a realistic number since it is unlimited by default (on desktop) and your app could be running with so many FPS that it is faster than how often you can sample your mouse input.
You can set the framerate using: Application.targetFrameRate = 60;
Aside from this problem it is generally a good idea to set your framerate to save yourself some headaches. (This is specifically true if you develop for mobile platforms and test on your desktop.)

Player moves in Update() but not FixedUpdate() in Unity

I made a car controller in unity to drive around. I've read FixedUpdate is better to use for physical objects instead of Update, but when I switch to Fixed update my car no longer drives. Does anyone know why this might be? Thank so much you for any help you an provide!
public float speed;
public float turnSpeed;
private RigidBody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void FixedUpdate()
{
Move();
Turn();
}
void Move(){
// moves the car
if (Input.GetKey(KeyCode.W)){
rb.AddRelativeForce(new Vector3(Vector3.forward.x, 0, Vector3.forward.z) * speed);
}
else if (Input.GetKey(KeyCode.S)){
rb.AddRelativeForce(new Vector3(Vector3.forward.x, 0, Vector3.forward.z) * -speed);
}
// maintains forward velocity relative to car.
Vector3 localVelocity = transform.InverseTransformDirection(rb.velocity);
localVelocity.x = 0;
rb.velocity = transform.TransformDirection(localVelocity);
}
void Turn(){
// turns the car.
if (Input.GetKey(KeyCode.D)){
rb.AddRelativeTorque(Vector3.up * turnSpeed);
Debug.Log("TURNING CAR");
}
else if (Input.GetKey(KeyCode.A)){
rb.AddRelativeTorque(-Vector3.up * turnSpeed);
Debug.Log("TURNING CAR");
}
Here's the code. Pressing W or S adds a force, pressing A or D adds a torque. When I try turning in FixedUpdate the console will write "TURNING CAR" as it should which shows that it's making past the AddRelativeTorque line, but it still won't turn so I'm not really sure what's going on. Thanks again, I really appreciate any help.
Try increasing the force used.
Fixed update runs less frequently than update (using the default settings, in most scenarios). Since the code is running much less frequently, less force is being accumulated over the same time period.
Consider a game running at 100fps. The default fixed time step is 0.02s (50 frames per second). Since update is running at 100fps, you have twice as much force being applied from update than would be applied from fixed update.
If you make your force value independent of the time since the last update happened, you will not need to worry about this.
For Update use myForceValue * Time.deltaTime.
For FixedUpdate use myForceValue * Time.fixedDeltaTime.

Moving something rotated on a custom pivot Unity

I've created an arm with a custom pivot in Unity which is essentially supposed to point wherever the mouse is pointing, regardless of the orientation of the player. Now, this arm looks weird when pointed to the side opposite the one it was drawn at, so I use SpriteRenderer.flipY = true to flip the sprite and make it look normal. I also have a weapon at the end of the arm, which is mostly fine as well. Now the problem is that I have a "FirePoint" at the end of the barrel of the weapon, and when the sprite gets flipped the position of it doesn't change, which affects particles and shooting position. Essentially, all that has to happen is that the Y position of the FirePoint needs to become negative, but Unity seems to think that I want the position change to be global, whereas I just want it to be local so that it can work with whatever rotation the arm is at. I've attempted this:
if (rotZ > 40 || rotZ < -40) {
rend.flipY = true;
firePoint.position = new Vector3(firePoint.position.x, firePoint.position.y * -1, firePoint.position.z);
} else {
rend.flipY = false;
firePoint.position = new Vector3(firePoint.position.x, firePoint.position.y * -1, firePoint.position.z);
}
But this works on a global basis rather than the local one that I need. Any help would be much appreciated, and I hope that I've provided enough information for this to reach a conclusive result. Please notify me should you need anything more. Thank you in advance, and have a nice day!
You can use RotateAround() to get desired behaviour instead of flipping stuff around. Here is sample code:
public class ExampleClass : MonoBehaviour
{
public Transform pivotTransform; // need to assign in inspector
void Update()
{
transform.RotateAround(pivotTransform.position, Vector3.up, 20 * Time.deltaTime);
}
}

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);
}
}