Unity3d: How can I move Gameobjects from the same script independently?

Asked

Viewed 567 times

3

I created a script in Unity3d that makes a GameObject move in a sinusoidal way.

The movement occurs perfectly, but when more than one GameObject containing this script is on the scene all move like a mirror to each other and not relative, leaving the game very artificial.

I tried to use local positioning and still could not solve the problem.

Here’s the code:

using System.Collections; using System.Collections.Generic; using UnityEngine;

public class Enemy4 : Nave {

 public float horizontalSpeed;
 public int yFactor;
 private float count = 3;
 private Vector3 s;
 private bool setPos = false;
 private float x;
 private float y;
 // Use this for initialization
 void Start () {
     x = 0;
     y = 0;
     s = transform.position;
     side = Side.defside.ENEMY;
 }

 // Update is called once per frame
 void Update () {
     y += yFactor * Time.deltaTime;
     x = Mathf.Sin (Time.time) * horizontalSpeed;
     transform.position = s + new Vector3 (x,y, 0);
 }

}
  • I don’t know if I understand this correctly, but if you use an Andom for the movement then each one will have a slightly different behavior. Dai is with you set where you will want to use the Random, whether in position, speed, direction etc....

1 answer

2

Sine waves

A sine wave has three relevant properties:

  • Frequency - The inverse of the distance between two peaks of a sine wave.

  • Amplitude - Is the difference between the peak height of the wave valley.

  • Phase - It is the part of the sine wave in which an object moving through it is.

For example, let’s assume that x and y are two consecutive wave peaks, so that:

- [a] x < y,
- [b] Mathf.Sin(x) = Mathf.Sin(y) = p,
- [c] there is no t such that (x < t < y and Mathf.Sin(t) = 1) and
- [d] for all b real -a <= Mathf.Sin(b) <= a.

Therefore, the frequency would be given by 1 / (y - x). The amplitude is 2 * a. The stage is given by t for the expression f(t), where f is its senoid function (not necessarily its function sin, for f(x) = 2 * Mathf.Sin(x) is also a senoid function).

By analyzing your code

You are using the following to set the position of your object:

x = Mathf.Sin (Time.time) * horizontalSpeed;

Its sinusoidal function in the case is f(x) = Mathf.Sin (Time.time) * horizontalSpeed. The horizontalSpeed is the amplitude. The phase is given by Time.time and the frequency is 2π seconds. This means that your objects will have a position that always oscillates in cycles of 2π seconds and all will be synchronized as the phase of the wave.

The solution is to introduce something that causes them to deviate in phase and frequency.

Also, use FixedUpdate instead of Update. The FixedUpdate has consistent time intervals and is useful to update the game’s logic, while the Update has more purpose to prepare the rendering on the screen.

Resulting code

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Enemy4 : Nave {

    public float horizontalSpeed;
    public int yFactor;
    public float frequency;
    public float phaseOffset;
    private float count = 3;
    private Vector3 s;
    private bool setPos = false;
    private float x;
    private float y;

    void Start() {
        x = 0;
        y = 0;
        s = transform.position;
        side = Side.defside.ENEMY;
    }

    void FixedUpdate() {
        y += yFactor * Time.deltaTime;
        x = Mathf.Sin(Time.time * frequency / Mathf.PI + phaseOffset) * horizontalSpeed;
        transform.position = s + new Vector3(x, y, 0);
    }
}

The value of frequency will be the number of times per second you want your object to run a full cycle on the wave (and cannot be zero). The value of the phaseOffset defines the phase in which the object is when time is zero. These values, you can define a different one for each object or put some random number any, according to what you think best.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.